diff --git a/lib/SAML2/ArtifactResolve.php b/lib/SAML2/ArtifactResolve.php
index c7de093ba6e77e4c28001e1bdb653ac4733d01cb..b0e100649cc6836733e8cb4160a4cd8f0f7e4a02 100644
--- a/lib/SAML2/ArtifactResolve.php
+++ b/lib/SAML2/ArtifactResolve.php
@@ -42,7 +42,7 @@ class SAML2_ArtifactResolve extends SAML2_Request {
 	 * @param String  The $artifact.
 	 */
 	public function setArtifact($artifact) {
-
+		assert('is_string($artifact)');
 		$this->artifact = $artifact;
 	}
 
@@ -53,7 +53,10 @@ class SAML2_ArtifactResolve extends SAML2_Request {
 	 */
 	public function toUnsignedXML() {
 
-		throw new Exception('Not SUPPORTED');
+		$root = parent::toUnsignedXML();
+		$artifactelement = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'Artifact', $this->artifact);
+		$root->appendChild($artifactelement);
+		return $root;
 	}
 
 
diff --git a/lib/SAML2/HTTPArtifact.php b/lib/SAML2/HTTPArtifact.php
index 0251a69ea4f17115406a03fca69b947a34f0e1de..962a1633bef2df3b8a9769e2fd8bff26f62c3ece 100644
--- a/lib/SAML2/HTTPArtifact.php
+++ b/lib/SAML2/HTTPArtifact.php
@@ -10,6 +10,8 @@
  */
 class SAML2_HTTPArtifact extends SAML2_Binding {
 
+	private $spMetadata;
+
 	/**
 	 * Create the redirect URL for a message.
 	 *
@@ -50,7 +52,7 @@ class SAML2_HTTPArtifact extends SAML2_Binding {
 
 
 	/**
-	 * Receive a SAMLart.
+	 * Receive a SAML 2 message sent using the HTTP-Artifact binding.
 	 *
 	 * Throws an exception if it is unable receive the message.
 	 *
@@ -58,7 +60,81 @@ class SAML2_HTTPArtifact extends SAML2_Binding {
 	 */
 	public function receive() {
 
-		throw new Exception('Receiving SAML2 Artifact messages not supported.');
+		if (array_key_exists('SAMLart', $_REQUEST)) {
+			$artifact = base64_decode($_REQUEST['SAMLart']);
+			$endpointIndex =  bin2hex(substr($artifact,2,2));
+			$sourceId = bin2hex(substr($artifact,4,20));
+
+		}else{
+			throw new Execption('Missing SAMLArt parameter.');
+		}
+
+		$metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+
+		$idpmetadata = $metadataHandler->getMetaDataConfigForSha1($sourceId, 'saml20-idp-remote');
+
+
+		$endpoint = NULL;
+		foreach ($idpmetadata->getEndpoints('ArtifactResolutionService') as $ep) {
+			if ($ep['index'] ===  hexdec($endpointIndex)) {
+				$endpoint = $ep;
+				break;
+			}
+		}
+
+		if ($endpoint === NULL) {
+			throw new Exception('No ArtifactResolutionService with the correct index.');
+		}
+
+		SimpleSAML_Logger::debug("ArtifactResolutionService endpoint being used is := " . $endpoint['Location']);
+
+		//Construct the ArtifactResolve Request
+		$ar = new SAML2_ArtifactResolve();
+
+		/* Set the request attributes */
+
+		$ar->setIssuer($this->spMetadata->getString('entityid'));
+		$ar->setArtifact($_REQUEST['SAMLart']);
+		$ar->setDestination($endpoint['Location']);
+
+		/* Sign the request */
+		sspmod_saml2_Message::addSign($this->spMetadata, $idpmetadata, $ar); // Shoaib - moved from the SOAPClient.
+
+		$soap = new SAML2_SOAPClient();
+
+		// Send message through SoapClient
+		$artifactResponse = $soap->send($ar, $this->spMetadata);
+
+		if (!$artifactResponse->isSuccess()) {
+			throw new Exception('Received error from ArtifactResolutionService.');
+		}
+
+		$xml = $artifactResponse->getAny();
+		$samlresponse = SAML2_Message::fromXML($xml);
+		$samlresponse->addValidator(array(get_class($this), 'validateSignature'), $artifactResponse);
+
+
+		if (isset($_REQUEST['RelayState'])) {
+			$samlresponse->setRelayState($_REQUEST['RelayState']);
+		}
+
+		return $samlresponse;
+	}
+
+
+	public function setSPMetadata($sp){
+		$this->spMetadata = $sp;
+	}
+
+
+	/**
+	 * A validator which returns TRUE if the ArtifactResponse was signed with the given key
+	 *
+	 * @return TRUE
+	 */
+	public static function validateSignature(SAML2_ArtifactResponse $message, XMLSecurityKey $key) {
+
+		return $message->validate($key);
 	}
 
 }
diff --git a/lib/SAML2/SOAPClient.php b/lib/SAML2/SOAPClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c272f176e09bd3b40fe0e8d490ef98a184088be
--- /dev/null
+++ b/lib/SAML2/SOAPClient.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Implementation of the SAML 2.0 SOAP binding.
+ *
+ * @author Shoaib Ali
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SAML2_SOAPClient {
+
+	const START_SOAP_ENVELOPE = '<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header/><soap-env:Body>';
+	const END_SOAP_ENVELOPE = '</soap-env:Body></soap-env:Envelope>';
+
+	/**
+	 * This function sends the SOAP message to the service location and returns SOAP response
+	 *
+	 * @param $ar SAML2_ArtifactResolve object.
+	 * @return $soapresponse string
+	 */
+	public function send(SAML2_ArtifactResolve $ar, SimpleSAML_Configuration $spMetadata) {
+
+		$issuer = $ar->getIssuer();
+
+		$options = array(
+			'uri' => $issuer,
+			'location' => $ar->getDestination(),
+		);
+
+		// Determine if we are going to do a MutualSSL connection between the IdP and SP  - Shoaib
+		if ($spMetadata->hasValue('saml.SOAPClient.certificate')) {
+			$options['local_cert'] = SimpleSAML_Utilities::resolveCert($spMetadata->getString('saml.SOAPClient.certificate'));
+			if ($spMetadata->hasValue('saml.SOAPClient.privatekey_pass')) {
+				$options['passphrase'] = $spMetadata->getString('saml.SOAPClient.privatekey_pass');
+			}
+		} else {
+			/* Use the SP certificate and privatekey if it is configured. */
+			$privateKey = SimpleSAML_Utilities::loadPrivateKey($spMetadata);
+			$publicKey = SimpleSAML_Utilities::loadPublicKey($spMetadata);
+			if ($privateKey !== NULL && $publicKey !== NULL && isset($publicKey['PEM'])) {
+				$keyCertData = $privateKey['PEM'] . $publicKey['PEM'];
+				$file = SimpleSAML_Utilities::getTempDir() . '/' . sha1($keyCertData) . '.pem';
+				if (!file_exists($file)) {
+					SimpleSAML_Utilities::writeFile($file, $keyCertData);
+				}
+				$options['local_cert'] = $file;
+				if (isset($privateKey['password'])) {
+					$options['passphrase'] = $privateKey['password'];
+				}
+			}
+		}
+
+		$x = new SoapClient(NULL, $options);
+
+		// Add soap-envelopes
+		$request = $ar->toSignedXML();
+		$request = self::START_SOAP_ENVELOPE . $request->ownerDocument->saveXML($request) . self::END_SOAP_ENVELOPE;
+
+		$action = 'http://www.oasis-open.org/committees/security';
+		$version = '1.1';
+		$destination = $ar->getDestination();
+
+
+		/* Perform SOAP Request over HTTP */
+		$soapresponsexml = $x->__doRequest($request, $destination, $action, $version);
+
+
+		// Convert to SAML2_Message (DOMElement)
+		$dom = new DOMDocument();
+		if (!$dom->loadXML($soapresponsexml)) {
+			throw new Exception('Not a SOAP response.');
+		}
+
+		$soapfault = $this->getSOAPFault($dom);
+		if (isset($soapfault)) {
+			throw new Exception($soapfault);
+		}
+		//Extract the message from the response
+		$xml = $dom->firstChild;    /* Soap Envelope */
+		$samlresponse = SAML2_Utils::xpQuery($dom->firstChild, '/soap-env:Envelope/soap-env:Body/*[1]');
+		$samlresponse = SAML2_Message::fromXML($samlresponse[0]);
+
+
+		simpleSAML_Logger::debug("Valid ArtifactResponse received from IdP");
+
+		return $samlresponse;
+
+	}
+
+
+	/*
+	 * Extracts the SOAP Fault from SOAP message
+	 * @param $soapmessage Soap response needs to be type DOMDocument
+	 * @return $soapfaultstring string|NULL
+	 */
+	private function getSOAPFault($soapmessage) {
+
+		$soapfault = SAML2_Utils::xpQuery($soapmessage->firstChild, '/soap-env:Envelope/soap-env:Body/soap-env:Fault');
+
+		if (empty($soapfault)) {
+			/* No fault. */
+			return NULL;
+		}
+		$soapfaultelement = $soapfault[0];
+		$soapfaultstring = "Unknown fault string found"; // There is a fault element but we havn't found out what the fault string is
+		// find out the fault string
+		$faultstringelement =   SAML2_Utils::xpQuery($soapfaultelement, './soap-env:faultstring') ;
+		if (!empty($faultstringelement)) {
+			return $faultstringelement[0]->textContent;
+		}
+		return $soapfaultstring;
+	}
+
+}
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
index 7494bf5a238cdbc058fc5d313bce18a1a84add80..91c999cd0fa08f2159466500db9b5565bc75774c 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
@@ -307,6 +307,34 @@ class SimpleSAML_Metadata_MetaDataStorageHandler {
 		return SimpleSAML_Configuration::loadFromArray($metadata, $set . '/' . var_export($entityId, TRUE));
 	}
 
+	public function	getMetaDataConfigForSha1($sha1, $set) {
+		assert('is_string($sha1)');
+		assert('is_string($set)');
+
+
+		$result = array();
+
+		foreach($this->sources as $source) {
+			$srcList = $source->getMetadataSet($set);
+
+
+			/* $result is the last argument to array_merge because we want the content already
+			 * in $result to have precedence.
+			 */
+			$result = array_merge($srcList, $result);
+		}
+		foreach($result as $remote_provider ){
+
+			if(sha1($remote_provider['entityid'])==$sha1){
+				$remote_provider['metadata-set'] = $set;
+
+				return SimpleSAML_Configuration::loadFromArray($remote_provider, $set . '/' . var_export($remote_provider['entityid'], TRUE));
+			}
+		}
+
+		return null;
+	}
+
 }
 
 ?>
\ No newline at end of file
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 7224b6130de87c22e15e7bb238149f5c5b3f7067..f869414eac3fd3b62d5dde76fd5de85e51fff878 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -183,7 +183,6 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
 		$ar = sspmod_saml2_Message::buildAuthnRequest($this->metadata, $idpMetadata);
 
 		$ar->setAssertionConsumerServiceURL(SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $this->authId));
-		$ar->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST);
 
 		if (isset($state['SimpleSAML_Auth_Default.ReturnURL'])) {
 			$ar->setRelayState($state['SimpleSAML_Auth_Default.ReturnURL']);
diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php
index f42e83ba61eb41807fabe6f777655b749b912a74..4c7160169f95b5f4f3d6c03efecdb699aadbe5ef 100644
--- a/modules/saml/www/sp/saml2-acs.php
+++ b/modules/saml/www/sp/saml2-acs.php
@@ -6,8 +6,13 @@
 
 $sourceId = substr($_SERVER['PATH_INFO'], 1);
 $source = SimpleSAML_Auth_Source::getById($sourceId, 'sspmod_saml_Auth_Source_SP');
+$spMetadata = $source->getMetadata();
 
 $b = SAML2_Binding::getCurrentBinding();
+if ($b instanceof SAML2_HTTPArtifact) {
+	$b->setSPMetadata($spMetadata);
+}
+
 $response = $b->receive();
 if (!($response instanceof SAML2_Response)) {
 	throw new SimpleSAML_Error_BadRequest('Invalid message received to AssertionConsumerService endpoint.');
@@ -40,7 +45,6 @@ if ($idp === NULL) {
 SimpleSAML_Logger::debug('Received SAML2 Response from ' . var_export($idp, TRUE) . '.');
 
 $idpMetadata = $source->getIdPmetadata($idp);
-$spMetadata = $source->getMetadata();
 
 try {
 	$assertion = sspmod_saml2_Message::processResponse($spMetadata, $idpMetadata, $response);
diff --git a/modules/saml2/lib/Message.php b/modules/saml2/lib/Message.php
index 918cbe626ca769e0bd18317543055ac94599bb64..38de9951ff0df6511aa3bcc01f40060a8a2045e6 100644
--- a/modules/saml2/lib/Message.php
+++ b/modules/saml2/lib/Message.php
@@ -385,6 +385,15 @@ class sspmod_saml2_Message {
 		$ar->setForceAuthn($spMetadata->getBoolean('ForceAuthn', FALSE));
 		$ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE));
 
+		$protbind = $spMetadata->getValueValidate('ProtocolBinding', array(
+				SAML2_Const::BINDING_HTTP_POST,
+				SAML2_Const::BINDING_HTTP_ARTIFACT,
+				SAML2_Const::BINDING_HTTP_REDIRECT,
+			), SAML2_Const::BINDING_HTTP_POST);
+
+		/* Shoaib - setting the appropriate binding based on parameter in sp-metadata defaults to HTTP_POST */
+		$ar->setProtocolBinding($protbind);
+
 		if ($spMetadata->hasValue('AuthnContextClassRef')) {
 			$accr = $spMetadata->getArrayizeString('AuthnContextClassRef');
 			$ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr));
diff --git a/www/saml2/sp/AssertionConsumerService.php b/www/saml2/sp/AssertionConsumerService.php
index 2fa55b819c8e3776e7539d0a40dc77cec9f2f0e4..bfe0c7766719c60642816901403d26e54d14e680 100644
--- a/www/saml2/sp/AssertionConsumerService.php
+++ b/www/saml2/sp/AssertionConsumerService.php
@@ -63,13 +63,16 @@ if (array_key_exists(SimpleSAML_Auth_ProcessingChain::AUTHPARAM, $_REQUEST)) {
 }
 
 
-if (empty($_REQUEST['SAMLResponse']))
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'ACSPARAMS', $exception);
-
-	
 try {
+	$metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+	$sp = $metadataHandler->getMetaDataCurrentEntityID();
+	$spMetadata = $metadataHandler->getMetaDataConfig($sp, 'saml20-sp-hosted');
 
 	$b = SAML2_Binding::getCurrentBinding();
+	if ($b instanceof SAML2_HTTPArtifact) {
+		$b->setSPMetadata($spMetadata);
+	}
+
 	$response = $b->receive();
 	if (!($response instanceof SAML2_Response)) {
 		throw new SimpleSAML_Error_BadRequest('Invalid message received to AssertionConsumerService endpoint.');
@@ -80,11 +83,8 @@ try {
 		throw new Exception('Missing <saml:Issuer> in message delivered to AssertionConsumerService.');
 	}
 
-	$metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-	$sp = $metadataHandler->getMetaDataCurrentEntityID();
 
 	$idpMetadata = $metadataHandler->getMetaDataConfig($idp, 'saml20-idp-remote');
-	$spMetadata = $metadataHandler->getMetaDataConfig($sp, 'saml20-sp-hosted');
 
 	/* Fetch the request information if it exists, fall back to RelayState if not. */
 	$requestId = $response->getInResponseTo();
diff --git a/www/saml2/sp/initSSO.php b/www/saml2/sp/initSSO.php
index 02058b20c784facc673bd1d99d4e31c69a24039f..4146d103f68c210fd4a3aade32ac5c54b0b57ded 100644
--- a/www/saml2/sp/initSSO.php
+++ b/www/saml2/sp/initSSO.php
@@ -136,7 +136,6 @@ try {
 
 	$assertionConsumerServiceURL = $metadata->getGenerated('AssertionConsumerService', 'saml20-sp-hosted');
 	$ar->setAssertionConsumerServiceURL($assertionConsumerServiceURL);
-	$ar->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST);
 	$ar->setRelayState($_REQUEST['RelayState']);
 
 	if ($isPassive) {