diff --git a/src/HAB/Pica/Auth/AbstractHttpAuthentication.php b/src/HAB/Pica/Auth/AbstractHttpAuthentication.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c48840f3371180e5b97ac7ce03f238f60e8c011
--- /dev/null
+++ b/src/HAB/Pica/Auth/AbstractHttpAuthentication.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * This file is part of PicaAuth.
+ *
+ * PicaAuth 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.
+ *
+ * PicaAuth 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 PicaAuth.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+
+namespace HAB\Pica\Auth;
+
+use RuntimeException;
+
+/**
+ * Abstract base class of HTTP based authentication.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+abstract class AbstractHttpAuthentication
+{
+    /**
+     * Send a HTTP request.
+     *
+     * @param  string $method
+     * @param  string $url
+     * @param  array  $header
+     * @param  string $body
+     * @return string
+     */
+    public function sendRequest ($method, $url, array $header = array(), $body = null)
+    {
+        $ctxOptions = array(
+            'http' => array(
+                'method' => $method,
+                'header' => implode("\r\n", $header),
+                'content' => $body
+            )
+        );
+        $ctx = stream_context_create($ctxOptions);
+        $response = @file_get_contents($url, false, $ctx);
+        if ($response === false) {
+            throw new RuntimeException("Error sending HTTP '{$method}' request to '{$url}'");
+        }
+
+        $statuscode = null;
+        if (preg_match('@^HTTP/\d+\.\d+ (?<statuscode>\d+)@i', $http_response_header[0], $matches)) {
+            $statuscode = $matches['statuscode'];
+        }
+        if ($statuscode < 200 || $statuscode > 299) {
+            throw new RuntimeException("Unexpected HTTP status code in server response: {$statuscode}");
+        }
+        return $response;    
+    }
+}
\ No newline at end of file
diff --git a/src/HAB/Pica/Auth/LBSAuthentication.php b/src/HAB/Pica/Auth/LBSAuthentication.php
index 6c76e5529cd47f6031918f0bbe72533f4a41631c..236b0276a413f4b4b4bd51dc9b7ba1ea8ec06fe3 100644
--- a/src/HAB/Pica/Auth/LBSAuthentication.php
+++ b/src/HAB/Pica/Auth/LBSAuthentication.php
@@ -25,9 +25,6 @@ namespace HAB\Pica\Auth;
 
 use RuntimeException;
 
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\RequestException;
-
 /**
  * Authenticate user against the LBS4 Authentication webservice.
  *
@@ -35,7 +32,7 @@ use GuzzleHttp\Exception\RequestException;
  * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
  * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
  */
-class LBSAuthentication implements AuthenticationInterface
+class LBSAuthentication extends AbstractHttpAuthentication implements AuthenticationInterface
 {
     /**
      * Service URL.
@@ -58,13 +55,6 @@ class LBSAuthentication implements AuthenticationInterface
      */
     private $lbsUserNumber;
 
-    /**
-     * HTTP client.
-     *
-     * @var Client
-     */
-    private $client;
-
     /**
      * Constructor.
      *
@@ -92,28 +82,11 @@ class LBSAuthentication implements AuthenticationInterface
             'FNO' => $this->catalogNumber,
             'LNG' => 'EN'
         );
-        try {
-            $response = $this->getClient()->get($this->serviceUrl, array('query' => $query));
-        } catch (RequestException $e) {
-            throw new RuntimeException(null, -1, $e);
-        }
-        $attributes = $this->parseResponseBody($response->getBody());
+        $response = $this->sendRequest('GET', sprintf('%s?%s', $this->serviceUrl, http_build_query($query)));
+        $attributes = $this->parseResponseBody($response);
         return $attributes;
     }
 
-    /**
-     * Return HTTP client.
-     *
-     * @return Client
-     */
-    public function getClient ()
-    {
-        if ($this->client === null) {
-            $this->client = new Client();
-        }
-        return $this->client;
-    }
-
     /**
      * Parse response body and user return attributes.
      *
diff --git a/src/HAB/Pica/Auth/LOAN3WebAuthentication.php b/src/HAB/Pica/Auth/LOAN3WebAuthentication.php
index 323ce6b4a1eaecf0c7fd603afa24d57f5c86ea10..a1bc35bf74500c009477a29e9c43b219cb2a3f41 100644
--- a/src/HAB/Pica/Auth/LOAN3WebAuthentication.php
+++ b/src/HAB/Pica/Auth/LOAN3WebAuthentication.php
@@ -23,11 +23,6 @@
 
 namespace HAB\Pica\Auth;
 
-use RuntimeException;
-
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\RequestException;
-
 /**
  * Authenticate user against a LOAN3 web interface.
  *
@@ -35,7 +30,7 @@ use GuzzleHttp\Exception\RequestException;
  * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
  * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
  */
-class LOAN3WebAuthentication implements AuthenticationInterface
+class LOAN3WebAuthentication extends AbstractHttpAuthentication implements AuthenticationInterface
 {
     /**
      * Service URL.
@@ -44,13 +39,6 @@ class LOAN3WebAuthentication implements AuthenticationInterface
      */
     private $serviceUrl;
 
-    /**
-     * HTTP client.
-     *
-     * @var Client
-     */
-    private $client;
-
     /**
      * Constructor.
      *
@@ -72,27 +60,16 @@ class LOAN3WebAuthentication implements AuthenticationInterface
             'BOR_PW' => $password,
             'ACT' => 'UI_DATA',
         );
-        try {
-            $response = $this->getClient()->post($this->serviceUrl, array('body' => $query));
-        } catch (RequestException $e) {
-            throw new RuntimeException(null, -1, $e);
-        }
-        $attributes = $this->parseResponseBody($response->getBody());
+        $response = $this->sendRequest(
+            'POST',
+            $this->serviceUrl,
+            array('Content-Type: application/x-www-form-urlencoded'),
+            http_build_query($query)
+        );
+        $attributes = $this->parseResponseBody($response);
         return $attributes;
 
     }
-    /**
-     * Return HTTP client.
-     *
-     * @return Client
-     */
-    public function getClient ()
-    {
-        if ($this->client === null) {
-            $this->client = new Client();
-        }
-        return $this->client;
-    }
 
     /**
      * Parse response body and user return attributes.
diff --git a/tests/unit-tests/data/lbs4authentication.error.response b/tests/unit-tests/data/lbs4authentication.error.response
index 6af4cd127b9045d0dd489b0acaa4b6ffb2094214..953d378b2a69bf582265a1127b737b00489415e2 100644
--- a/tests/unit-tests/data/lbs4authentication.error.response
+++ b/tests/unit-tests/data/lbs4authentication.error.response
@@ -1,7 +1 @@
-HTTP/1.1 200 OK
-Date: Wed, 06 May 2015 09:43:16 GMT
-Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11
-Content-Length: 168
-Content-Type: application/xml
-
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>NOK</status><error>Wrong password and/or number.</error></AuthenticationResponse>
\ No newline at end of file
diff --git a/tests/unit-tests/data/lbs4authentication.success.response b/tests/unit-tests/data/lbs4authentication.success.response
index 7d048ffe719710f44bbc90b8a3825737f60b6b9b..a3291cbc4cf1a8114a3326b896dc41919bf54d4e 100644
--- a/tests/unit-tests/data/lbs4authentication.success.response
+++ b/tests/unit-tests/data/lbs4authentication.success.response
@@ -1,7 +1 @@
-HTTP/1.1 200 OK
-Date: Wed, 06 May 2015 09:42:33 GMT
-Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11
-Content-Length: 232
-Content-Type: application/xml
-
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>OK</status><sessionID>c3ac4981-eb02-46f5-b092-d7261d08386f</sessionID><userKey>username</userKey><userGroup>20</userGroup></AuthenticationResponse>
\ No newline at end of file
diff --git a/tests/unit-tests/data/loan3authentication.error.response b/tests/unit-tests/data/loan3authentication.error.response
index 834c16552aa8b7fa990da13c0760debf8f7b6156..10d5b0a9b316c8b99060d366ee36e9ea65e5647b 100644
--- a/tests/unit-tests/data/loan3authentication.error.response
+++ b/tests/unit-tests/data/loan3authentication.error.response
@@ -1,15 +1,3 @@
-HTTP/1.1 200 OK
-Date: Wed, 06 May 2015 12:12:11 GMT
-Server: opc4/2.8.4.0-vzg8-dbs1
-Content-Length: 18777
-X-PSI-Class: loan
-X-PSI-Context: USERINFO_LOGIN
-Content-Type: text/html; charset=UTF-8
-Keep-Alive: timeout=5, max=100
-Connection: Keep-Alive
-X-Pad: avoid browser bug
-
-
 <HTML>
 <HEAD>
     <TITLE>OPC4 - borrower/identification</TITLE>
diff --git a/tests/unit-tests/data/loan3authentication.success.response b/tests/unit-tests/data/loan3authentication.success.response
index ad9d9769163272543c47a33b532033022fb855a5..2c7cd2e9a849f813309f68b23ee16037cb953f1e 100644
--- a/tests/unit-tests/data/loan3authentication.success.response
+++ b/tests/unit-tests/data/loan3authentication.success.response
@@ -1,14 +1,3 @@
-HTTP/1.1 200 OK
-Date: Wed, 06 May 2015 12:13:33 GMT
-Server: opc4/2.8.4.0-vzg8-dbs1
-Content-Length: 17414
-X-PSI-Class: loan
-X-PSI-Context: USERINFO
-Content-Type: text/html; charset=UTF-8
-Keep-Alive: timeout=5, max=100
-Connection: Keep-Alive
-
-
 <HTML>
 <HEAD>
     <TITLE>OPC4 - borrower/userdata</TITLE>
diff --git a/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php
index 08c1e73a2743c5e8f4ae4a7fb55f652566877349..a04798548b9872f4e64588bbd0f345418b731fe2 100644
--- a/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php
+++ b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php
@@ -23,8 +23,6 @@
 
 namespace HAB\Pica\Auth;
 
-use GuzzleHttp\Subscriber\Mock;
-
 use PHPUnit_Framework_TestCase as TestCase;
 
 /**
@@ -36,31 +34,25 @@ use PHPUnit_Framework_TestCase as TestCase;
  */
 class LBSAuthenticationTest extends TestCase
 {
-    /**
-     * @expectedException RuntimeException
-     */
-    public function testRuntimeExceptionOnRemoteError ()
-    {
-        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
-        $response = new Mock(array('HTTP/1.1 500 Internal Server Error'));
-        $service->getClient()->getEmitter()->attach($response);
-        $service->authenticate('username', 'password');
-    }
-
     public function testAuthenticationFailure ()
     {
-        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
-        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.error.response')));
-        $service->getClient()->getEmitter()->attach($response);
+        $service = $this->getMock('HAB\Pica\Auth\LBSAuthentication', array('sendRequest'), array('', 0, 0));
+        $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.error.response');
+        $service->expects($this->once())
+            ->method('sendRequest')
+            ->will($this->returnValue($response));
+        
         $attributes = $service->authenticate('username', 'password');
         $this->assertFalse($attributes);
     }
 
     public function testAuthenticationSuccess ()
     {
-        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
-        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.success.response')));
-        $service->getClient()->getEmitter()->attach($response);
+        $service = $this->getMock('HAB\Pica\Auth\LBSAuthentication', array('sendRequest'), array('', 0, 0));
+        $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.success.response');
+        $service->expects($this->once())
+            ->method('sendRequest')
+            ->will($this->returnValue($response));        
         $attributes = $service->authenticate('username', 'password');
         $this->assertInternalType('array', $attributes);
         $this->assertNotEmpty($attributes);
diff --git a/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php b/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php
index cf707cae02a0011d6a779d7ff41b34702855b72a..f8d81680851def9f14099df27774e1084ca1a933 100644
--- a/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php
+++ b/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php
@@ -23,8 +23,6 @@
 
 namespace HAB\Pica\Auth;
 
-use GuzzleHttp\Subscriber\Mock;
-
 use PHPUnit_Framework_TestCase as TestCase;
 
 /**
@@ -36,31 +34,25 @@ use PHPUnit_Framework_TestCase as TestCase;
  */
 class LOAN3WebAuthenticationTest extends TestCase
 {
-    /**
-     * @expectedException RuntimeException
-     */
-    public function testRuntimeExceptionOnRemoteError ()
-    {
-        $service = new LOAN3WebAuthentication('invalid://example.lorg');
-        $response = new Mock(array('HTTP/1.1 500 Internal Server Error'));
-        $service->getClient()->getEmitter()->attach($response);
-        $service->authenticate('username', 'password');
-    }
 
     public function testAuthenticationFailure ()
     {
-        $service = new LOAN3WebAuthentication('invalid://example.org/', 0, 0);
-        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.error.response')));
-        $service->getClient()->getEmitter()->attach($response);
+        $service = $this->getMock('HAB\Pica\Auth\LOAN3WebAuthentication', array('sendRequest'), array('invalid://example.org/'));
+        $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.error.response');
+        $service->expects($this->once())
+            ->method('sendRequest')
+            ->will($this->returnValue($response));
         $attributes = $service->authenticate('username', 'password');
         $this->assertFalse($attributes);
     }
 
     public function testAuthenticationSuccess ()
     {
-        $service = new LOAN3WebAuthentication('invalid://example.org/', 0, 0);
-        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.success.response')));
-        $service->getClient()->getEmitter()->attach($response);
+        $service = $this->getMock('HAB\Pica\Auth\LOAN3WebAuthentication', array('sendRequest'), array('invalid://example.org/'));
+        $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.success.response');
+        $service->expects($this->once())
+            ->method('sendRequest')
+            ->will($this->returnValue($response));
         $attributes = $service->authenticate('username', 'password');
         $this->assertInternalType('array', $attributes);
         $this->assertNotEmpty($attributes);