diff --git a/sflphone-common/src/sip/Pattern.cpp b/sflphone-common/src/sip/Pattern.cpp
index 71e093d13c96384877e71ca9ff65d721313a7e79..290c9f7a79c52319aae430c78f7e9d143c20e6a7 100644
--- a/sflphone-common/src/sip/Pattern.cpp
+++ b/sflphone-common/src/sip/Pattern.cpp
@@ -180,23 +180,17 @@ std::string Pattern::group (const std::string& groupName)
                  _count,
                  groupName.c_str(),
                  &stringPtr);
-
-    // printf("  _count : %i\n", _count);
-    // printf("stringPtr : %s\n", stringPtr);
     
     if (rc < 0) {
         switch (rc) {
 
             case PCRE_ERROR_NOSUBSTRING:
-	        // printf("Pattern::PCRE_ERROR_NOSUBSTRING\n");
                 throw std::out_of_range ("Invalid group reference.");
 
             case PCRE_ERROR_NOMEMORY:
-	        // printf("Pattern::PCRE_ERROR_NOMEMORY\n");
                 throw match_error ("Memory exhausted.");
 
             default:
-	        // printf("Pattern::default match error\n");
                 throw match_error ("Failed to get named substring.");
         }
     }
@@ -255,10 +249,6 @@ bool Pattern::matches (void) throw (match_error)
 
 bool Pattern::matches (const std::string& subject) throw (match_error)
 {
-    // printf("Pattern::matches\n");
-    // printf("  Current offset: %d, old offset: %d", _offset[1], _offset[0]);
-    // printf("  Trying <start>%s<end>\n", subject.substr(_offset[1]).c_str());
-
     // Try to find a match for this pattern
     int rc = pcre_exec (
                  _re,
@@ -271,7 +261,6 @@ bool Pattern::matches (const std::string& subject) throw (match_error)
                  _ovectorSize);
 
     // Matching failed.
-
     if (rc < 0) {
         _offset[0] = _offset[1] = 0;
         // printf("  Matching failed with %d\n", rc);
@@ -285,8 +274,6 @@ bool Pattern::matches (const std::string& subject) throw (match_error)
         _offset[1] =  _ovector[1] + _offset[0];
     }
 
-    // printf("  Matching succeeded with %d to %d\n", (int) start(), (int) end());
-
     // Matching succeded but not enough space.
     if (rc == 0) {
         throw match_error ("No space to store all substrings.");
@@ -295,7 +282,6 @@ bool Pattern::matches (const std::string& subject) throw (match_error)
 
     // Matching succeeded. Keep the number of substrings for
     // subsequent calls to group().
-    // printf("_count: %i = %i\n", _count, rc);
       _count = rc;
 
     return true;
diff --git a/sflphone-common/src/sip/SdesNegotiator.cpp b/sflphone-common/src/sip/SdesNegotiator.cpp
index e8618e3ab8d80f0bfb9b13fc5205cda5c847c869..f9411df3d9649187f0c59e129ea16240489c7b68 100644
--- a/sflphone-common/src/sip/SdesNegotiator.cpp
+++ b/sflphone-common/src/sip/SdesNegotiator.cpp
@@ -28,13 +28,6 @@
 
 using namespace sfl;
 
-struct CryptoAttribute {
-    std::string tag;
-    std::string cryptoSuite;
-    std::string keyParams;
-    std::string sessionParams;
-};
-
 SdesNegotiator::SdesNegotiator (const std::vector<CryptoSuiteDefinition>& localCapabilites,
                                 const std::vector<std::string>& remoteAttribute) :
         _remoteAttribute (remoteAttribute),
@@ -43,7 +36,7 @@ SdesNegotiator::SdesNegotiator (const std::vector<CryptoSuiteDefinition>& localC
 
 }
 
-void SdesNegotiator::parse (void)
+std::vector<CryptoAttribute *> SdesNegotiator::parse (void)
 {
     // The patterns below try to follow
     // the ABNF grammar rules described in
@@ -63,8 +56,7 @@ void SdesNegotiator::parse (void)
         // used to match white space (which are used as separator) 
         generalSyntaxPattern = new Pattern ("[\x20\x09]+", "g");
 
-        tagPattern = new Pattern ("^a=crypto:(?P<tag>[0-9]{1,9})", "g");
-	// tagPattern = new Pattern ("[0-9]");
+        tagPattern = new Pattern ("^a=crypto:(?P<tag>[0-9]{1,9})");
 
         cryptoSuitePattern = new Pattern (
             "(?P<cryptoSuite>AES_CM_128_HMAC_SHA1_80|" \
@@ -91,7 +83,6 @@ void SdesNegotiator::parse (void)
 
     } catch (compile_error& exception) {
         throw parse_error ("A compile exception occured on a pattern.");
-
     }
       
 
@@ -100,18 +91,15 @@ void SdesNegotiator::parse (void)
 
     
     std::vector<std::string>::iterator iter;
-
+	std::vector<CryptoAttribute *> cryptoAttributeVector;
+	
     for (iter = _remoteAttribute.begin(); iter != _remoteAttribute.end(); iter++) {
-
-        std::cout << (*iter) << std::endl;
-
         // Split the line into its component
         // that we will analyze further down.
-	std::vector<std::string> sdesLine;
+		std::vector<std::string> sdesLine;
 	
         *generalSyntaxPattern << (*iter);
         
-	
         try {
             sdesLine = generalSyntaxPattern->split();
 
@@ -126,49 +114,50 @@ void SdesNegotiator::parse (void)
         // Check if the attribute starts with a=crypto
         // and get the tag for this line
         *tagPattern << sdesLine.at (0);
-
-	tagPattern->matches();
-
-        try {
-            std::string tag = tagPattern->group ("tag");
-            std::cout << "tag = " << tag << std::endl;
-        } catch (match_error& exception) {
-            throw parse_error ("Error while parsing the tag field");
-        }
+				
+		std::string tag; 
+		if (tagPattern->matches()) {
+			try {
+				tag = tagPattern->group ("tag");
+			} catch (match_error& exception) {
+				throw parse_error ("Error while parsing the tag field");
+			}
+		} else {
+			return cryptoAttributeVector;
+		}
 
         // Check if the crypto suite is valid and retreive
         // its value.
         *cryptoSuitePattern << sdesLine.at (1);
 
-	cryptoSuitePattern->matches();
-
-        try {
-            _cryptoSuite = cryptoSuitePattern->group ("cryptoSuite");
-            std::cout << "crypto-suite = " << _cryptoSuite << std::endl;
-        } catch (match_error& exception) {
-            throw parse_error ("Error while parsing the crypto-suite field");
-        }
-
+		std::string cryptoSuite;
+		
+		if (cryptoSuitePattern->matches()) {
+			try {
+				cryptoSuite  = cryptoSuitePattern->group ("cryptoSuite");
+			} catch (match_error& exception) {
+				throw parse_error ("Error while parsing the crypto-suite field");
+			}
+		} else {
+			return cryptoAttributeVector;
+		}
+	
         // Parse one or more key-params field.
         *keyParamsPattern << sdesLine.at (2);
 
+		std::string srtpKeyInfo;
+		std::string srtpKeyMethod;
+		std::string lifetime;
+		std::string mkiLength;
+		std::string mkiValue;
+		
         try {
             while (keyParamsPattern->matches()) {
-                
-                _srtpKeyMethod = keyParamsPattern->group ("srtpKeyMethod");
-                std::cout << "srtp-key-method = " << _srtpKeyMethod << std::endl;
-
-                _srtpKeyInfo = keyParamsPattern->group ("srtpKeyInfo");
-                std::cout << "srtp-key-info = " << _srtpKeyInfo << std::endl;
-
-                _lifetime = keyParamsPattern->group ("lifetime");
-                std::cout << "lifetime = " << _lifetime << std::endl;
-
-                _mkiValue = keyParamsPattern->group ("mkiValue");
-                std::cout << "mkiValue = " << _mkiValue << std::endl;
-
-                _mkiLength = keyParamsPattern->group ("mkiLength");
-                std::cout << "mkiLength = " << _mkiLength << std::endl;
+                srtpKeyMethod = keyParamsPattern->group ("srtpKeyMethod");
+                srtpKeyInfo = keyParamsPattern->group ("srtpKeyInfo");
+                lifetime = keyParamsPattern->group ("lifetime");
+                mkiValue = keyParamsPattern->group ("mkiValue");
+                mkiLength = keyParamsPattern->group ("mkiLength");
             }
         } catch (match_error& exception) {
             throw parse_error ("Error while parsing the key-params field");
@@ -176,7 +165,7 @@ void SdesNegotiator::parse (void)
 
         /**
          *  Parse the optional session-param fields
-         * @todo Implement this !
+         * @TODO Implement this !
          */
         /*
         if (sdesLine.size() == 3) continue;
@@ -191,14 +180,39 @@ void SdesNegotiator::parse (void)
         		}
         	}
         } */
+		
+		// Add the new CryptoAttribute to the vector
+		std::cout << (*iter) << std::endl;
+		CryptoAttribute * cryptoAttribute = new CryptoAttribute(tag, cryptoSuite, srtpKeyMethod, srtpKeyInfo, lifetime, mkiValue, mkiLength);
+		cryptoAttributeVector.push_back(cryptoAttribute);
     }
 
-
+	return cryptoAttributeVector;
 }
 
 bool SdesNegotiator::negotiate (void)
 {
-    parse();
-
+	try {
+		std::vector<CryptoAttribute *> cryptoAttributeVector = parse();
+		
+		std::vector<CryptoAttribute *>::iterator iter;
+		for (iter = cryptoAttributeVector.begin(); iter != cryptoAttributeVector.end(); iter++) {
+			std::cout << "Negotiate tag: " + (*iter)->getTag() << std::endl;
+			std::cout << "Crypto Suite: " + (*iter)->getCryptoSuite() << std::endl;
+			std::cout << "SRTP Key Method: " + (*iter)->getSrtpKeyMethod() << std::endl;
+			std::cout << "SRTP Key Info: " + (*iter)->getSrtpKeyInfo() << std::endl;
+			std::cout << "Lifetime: " + (*iter)->getLifetime() << std::endl;
+			std::cout << "MKI Value: " + (*iter)->getMkiValue() << std::endl;			
+			std::cout << "MKI Length: " + (*iter)->getMkiLength() << std::endl;			
+			
+			delete (*iter);
+		}
+		
+	} catch (parse_error& exception) {
+		return false;
+	} catch (match_error& exception) {
+		return false;
+	}
+	
     return true;
 }
diff --git a/sflphone-common/src/sip/SdesNegotiator.h b/sflphone-common/src/sip/SdesNegotiator.h
index 08e32090ef5e64b5731f2fab2ace701135414fc0..d8a568421e14cdccf540a44ba3f6267d09863775 100644
--- a/sflphone-common/src/sip/SdesNegotiator.h
+++ b/sflphone-common/src/sip/SdesNegotiator.h
@@ -74,11 +74,43 @@ namespace sfl {
           {"AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 },
           {"F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 } };   
         
-    /** 
-     * Internal structure 
-     * used during parsing.
-     */  
-    struct CryptoAttribute;                    
+
+	class CryptoAttribute {
+	
+		public:
+			CryptoAttribute(std::string tag, 
+							std::string cryptoSuite, 
+							std::string srtpKeyMethod, 
+							std::string srtpKeyInfo, 
+							std::string lifetime, 
+							std::string mkiValue, 
+							std::string mkiLength) :
+			tag(tag),
+			cryptoSuite(cryptoSuite),
+			srtpKeyMethod(srtpKeyMethod),
+			srtpKeyInfo(srtpKeyInfo),
+			lifetime(lifetime),
+			mkiValue(mkiValue),
+			mkiLength(mkiLength) {};
+				
+			
+			inline std::string getTag() { return tag; };
+			inline std::string getCryptoSuite() { return cryptoSuite; };
+			inline std::string getSrtpKeyMethod() { return srtpKeyMethod; };
+			inline std::string getSrtpKeyInfo() { return srtpKeyInfo; };
+			inline std::string getLifetime() { return lifetime; };
+			inline std::string getMkiValue() { return mkiValue; };
+			inline std::string getMkiLength() { return mkiLength; };
+
+		private:
+			std::string tag;
+			std::string cryptoSuite;
+			std::string srtpKeyMethod;
+			std::string srtpKeyInfo;
+			std::string lifetime;
+			std::string mkiValue;
+			std::string mkiLength;
+	};         
 
     class SdesNegotiator 
     {
@@ -99,35 +131,35 @@ namespace sfl {
             
             bool negotiate(void);
 
-	    /**
-	     * Return crypto suite after negotiation
-	     */
-	    std::string getCryptoSuite(void) { return _cryptoSuite; }
+			/**
+			 * Return crypto suite after negotiation
+			 */
+			std::string getCryptoSuite(void) { return _cryptoSuite; }
 
-	    /**
-	     * Return key method after negotiation (most likely inline:)
-	     */
-	    std::string getKeyMethod(void) { return _srtpKeyMethod; }
+			/**
+			 * Return key method after negotiation (most likely inline:)
+			 */
+			std::string getKeyMethod(void) { return _srtpKeyMethod; }
 
-	    /**
-	     * Return crypto suite after negotiation
-	     */
-	    std::string getKeyInfo(void) { return _srtpKeyInfo; }
+			/**
+			 * Return crypto suite after negotiation
+			 */
+			std::string getKeyInfo(void) { return _srtpKeyInfo; }
 
-	    /**
-	     * Return key lifetime after negotiation
-	     */
-	    std::string getLifeTime(void) { return _lifetime; }
+			/**
+			 * Return key lifetime after negotiation
+			 */
+			std::string getLifeTime(void) { return _lifetime; }
 
-	    /**
-	     * Return mki value after negotiation
-	     */
-	    std::string getMkiValue(void) { return _mkiValue; }
+			/**
+			 * Return mki value after negotiation
+			 */
+			std::string getMkiValue(void) { return _mkiValue; }
 
-	    /**
-	     * Return mki length after negotiation
-	     */
-	    std::string getMkiLength(void) { return _mkiLength; }
+			/**
+			 * Return mki length after negotiation
+			 */
+			std::string getMkiLength(void) { return _mkiLength; }
 
         private:
             /**
@@ -139,39 +171,37 @@ namespace sfl {
 
             std::vector<CryptoSuiteDefinition> _localCapabilities;
 
-	    /**
-	     * Selected crypto suite after negotiation
-	     */
-	    std::string _cryptoSuite;
-
-	    /**
-	     * Selected key method after negotiation (most likely inline:)
-	     */
-	    std::string _srtpKeyMethod;
-
-	    /**
-	     * Selected crypto suite after negotiation
-	     */
-	    std::string _srtpKeyInfo;
-
-	    /**
-	     * Selected key lifetime after negotiation
-	     */
-	    std::string _lifetime;
-
-	    /**
-	     * Selected mki value after negotiation
-	     */
-	    std::string _mkiValue;
-
-	    /**
-	     * Selected mki length after negotiation
-	     */
-	    std::string _mkiLength;
-            
-            void parse(void);
-
-            CryptoAttribute * tokenize(const std::string& attributeLine);
+			/**
+			* Selected crypto suite after negotiation
+			*/
+			std::string _cryptoSuite;
+
+			/**
+			* Selected key method after negotiation (most likely inline:)
+			*/
+			std::string _srtpKeyMethod;
+
+			/**
+			* Selected crypto suite after negotiation
+			*/
+			std::string _srtpKeyInfo;
+
+			/**
+			* Selected key lifetime after negotiation
+			*/
+			std::string _lifetime;
+
+			/**
+			* Selected mki value after negotiation
+			*/
+			std::string _mkiValue;
+
+			/**
+			* Selected mki length after negotiation
+			*/
+			std::string _mkiLength;
+
+			std::vector<CryptoAttribute *> parse(void);
     };
 }
 #endif
diff --git a/sflphone-common/test/sdesnegotiatorTest.cpp b/sflphone-common/test/sdesnegotiatorTest.cpp
index 71b429a5eac0a74d4a011b4fd9bbdc8b84067808..ebe70c8bac9e51605a764d56fbcc27fca07aeefc 100644
--- a/sflphone-common/test/sdesnegotiatorTest.cpp
+++ b/sflphone-common/test/sdesnegotiatorTest.cpp
@@ -40,21 +40,18 @@ using std::endl;
 
 void SdesNegotiatorTest::setUp()
 {
-
-  std::string attr("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd|2^20|1:32");
-
-  // std::string attr("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32");
-
+	// Add a new SDES crypto line to be processed. 
     remoteOffer = new std::vector<std::string>();
-    remoteOffer->push_back(attr);
-
+    remoteOffer->push_back(std::string("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd|2^20|1:32"));
+	remoteOffer->push_back(std::string("a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32"));
+	
+	// Register the local capabilities.
     localCapabilities = new std::vector<sfl::CryptoSuiteDefinition>();
     for(int i = 0; i < 3; i++) {
         localCapabilities->push_back(sfl::CryptoSuites[i]);
     }
 
     sdesnego = new sfl::SdesNegotiator(*localCapabilities, *remoteOffer);
-
 }
 
 
@@ -121,38 +118,40 @@ void SdesNegotiatorTest::testKeyParamsPattern()
     pattern->matches();
     CPPUNIT_ASSERT(pattern->group("srtpKeyMethod").compare("inline:"));
 
-    /*
-    while (pattern->matches()) {
-                
-        std::string _srtpKeyMethod = pattern->group ("srtpKeyMethod");
-	std::string _srtpKeyInfo = pattern->group ("srtpKeyInfo");
-	std::string _lifetime = pattern->group ("lifetime");
-	std::string _mkiValue = pattern->group ("mkiValue");
-	std::string _mkiLength = pattern->group ("mkiLength");
-    }
-
-
-    CPPUNIT_ASSERT(pattern->group("srtpKeyMethod").compare("inline:"));
-    CPPUNIT_ASSERT(pattern->group("srtpKeyInfo").compare("d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj"));
-    CPPUNIT_ASSERT(pattern->group("lifetime").compare("20"));
-    CPPUNIT_ASSERT(pattern->group("mkivalue").compare("1"));
-    CPPUNIT_ASSERT(pattern->group("mkilength").compare("32"));
-    */
-
     delete pattern;
     pattern = NULL;
 }
 
-
+/**
+ * Make sure that all the fields can be extracted
+ * properly from the syntax. 
+ */
 void SdesNegotiatorTest::testNegotiation()
 {
     CPPUNIT_ASSERT(sdesnego->negotiate());
-    CPPUNIT_ASSERT(sdesnego->getCryptoSuite().compare("AES_CM_128_HMAC_SHA1_80") == 0);
-    CPPUNIT_ASSERT(sdesnego->getKeyMethod().compare("inline") == 0);
-    CPPUNIT_ASSERT(sdesnego->getKeyInfo().compare("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd") == 0);
-    CPPUNIT_ASSERT(sdesnego->getLifeTime().compare("20") == 0);
-    CPPUNIT_ASSERT(sdesnego->getMkiValue().compare("1") == 0);
-    CPPUNIT_ASSERT(sdesnego->getMkiLength().compare("32") == 0);
+}
+
+/**
+ * Make sure that unproperly formatted crypto lines are rejected.
+ */
+void SdesNegotiatorTest::testComponent()
+{
+	// Register the local capabilities.
+    std::vector<sfl::CryptoSuiteDefinition> * capabilities = new std::vector<sfl::CryptoSuiteDefinition>();
+	
+	//Support all the CryptoSuites
+    for(int i = 0; i < 3; i++) {
+        capabilities->push_back(sfl::CryptoSuites[i]);
+    }
+	
+	// Make sure that if a component is missing, negotiate will fail
+	std::string cryptoLine("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:|2^20|1:32");
+	std::vector<std::string> * cryptoOffer = new std::vector<std::string>();
+    cryptoOffer->push_back(cryptoLine);	
+
+    sfl::SdesNegotiator * negotiator = new sfl::SdesNegotiator(*capabilities, *cryptoOffer);
+
+	CPPUNIT_ASSERT(negotiator->negotiate() == false);
 }
 
 
diff --git a/sflphone-common/test/sdesnegotiatorTest.h b/sflphone-common/test/sdesnegotiatorTest.h
index 4e97a9d6dab6134e88fbfde693844e67a79c61e7..2a7b552222a5c1c223fa74f293eff8f91e4d6c2d 100644
--- a/sflphone-common/test/sdesnegotiatorTest.h
+++ b/sflphone-common/test/sdesnegotiatorTest.h
@@ -66,6 +66,7 @@ class SdesNegotiatorTest : public CppUnit::TestCase {
     CPPUNIT_TEST( testCryptoSuitePattern );
     CPPUNIT_TEST( testKeyParamsPattern );
     CPPUNIT_TEST( testNegotiation );
+	// CPPUNIT_TEST( testComponent );
     CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -84,24 +85,25 @@ class SdesNegotiatorTest : public CppUnit::TestCase {
          */
         inline void tearDown();
 
-	void testTagPattern();
+		void testTagPattern();
 
-	void testCryptoSuitePattern();
+		void testCryptoSuitePattern();
 
-	void testKeyParamsPattern();
+		void testKeyParamsPattern();
 
        	void testNegotiation();
+		
+		void testComponent();
 
     private:
 
-	sfl::Pattern *pattern;
+		sfl::Pattern *pattern;
 
-	sfl::SdesNegotiator *sdesnego;
+		sfl::SdesNegotiator *sdesnego;
 
-	std::vector<std::string> *remoteOffer;
-
-	std::vector<sfl::CryptoSuiteDefinition> *localCapabilities;
+		std::vector<std::string> *remoteOffer;
 
+		std::vector<sfl::CryptoSuiteDefinition> *localCapabilities;
 };
 
 /* Register our test module */