diff --git a/3rdparty b/3rdparty
index e42a129bf8c10cf9e519cc9e4a0e6978bbcd7e59..ffb6a3a10985ae6dca121200760a78b5a75aa5d5 160000
--- a/3rdparty
+++ b/3rdparty
@@ -1 +1 @@
-Subproject commit e42a129bf8c10cf9e519cc9e4a0e6978bbcd7e59
+Subproject commit ffb6a3a10985ae6dca121200760a78b5a75aa5d5
diff --git a/build/integration/composer.json b/build/integration/composer.json
index d7ccd593277a21717655e7c7c60e16f36fc8dbea..2850caa511a71d2eebcacdc8ec0e4a6f24f5a63b 100644
--- a/build/integration/composer.json
+++ b/build/integration/composer.json
@@ -2,7 +2,7 @@
   "require-dev": {
     "phpunit/phpunit": "~4.6",
     "behat/behat": "^3.0",
-    "guzzlehttp/guzzle": "~5.0",
+    "guzzlehttp/guzzle": "6.3.0",
     "jarnaiz/behat-junit-formatter": "^1.3",
     "sabre/dav": "3.2"
   }
diff --git a/build/integration/features/bootstrap/Auth.php b/build/integration/features/bootstrap/Auth.php
index b185dd0b8c8f13fb5110c488b08fbe042a7ae5b2..da2698b429a56f050528e9175fd13e59d42556d0 100644
--- a/build/integration/features/bootstrap/Auth.php
+++ b/build/integration/features/bootstrap/Auth.php
@@ -59,18 +59,20 @@ trait Auth {
 		$fullUrl = substr($this->baseUrl, 0, -5) . $url;
 		try {
 			if ($useCookies) {
-				$request = $this->client->createRequest($method, $fullUrl, [
+				$options = [
 					'cookies' => $this->cookieJar,
-				]);
+				];
 			} else {
-				$request = $this->client->createRequest($method, $fullUrl);
+				$options = [];
 			}
 			if ($authHeader) {
-				$request->setHeader('Authorization', $authHeader);
+				$options['headers'] = [
+					'Authorization' => $authHeader
+				];
 			}
-			$request->setHeader('OCS_APIREQUEST', 'true');
-			$request->setHeader('requesttoken', $this->requestToken);
-			$this->response = $this->client->send($request);
+			$options['headers']['OCS_APIREQUEST'] = 'true';
+			$options['headers']['requesttoken'] = $this->requestToken;
+			$this->response = $this->client->request($method, $fullUrl, $options);
 		} catch (ClientException $ex) {
 			$this->response = $ex->getResponse();
 		} catch (ServerException $ex) {
@@ -90,7 +92,7 @@ trait Auth {
 	 * @return object
 	 */
 	private function createClientToken($loginViaWeb = true) {
-		if($loginViaWeb) {
+		if ($loginViaWeb) {
 			$this->loggingInUsingWebAs('user0');
 		}
 
@@ -101,7 +103,7 @@ trait Auth {
 				'user0',
 				$loginViaWeb ? '123456' : $this->restrictedClientToken,
 			],
-			'body' => [
+			'form_params' => [
 				'requesttoken' => $this->requestToken,
 				'name' => md5(microtime()),
 			],
@@ -109,7 +111,7 @@ trait Auth {
 		];
 
 		try {
-			$this->response = $client->send($client->createRequest('POST', $fullUrl, $options));
+			$this->response = $client->request('POST', $fullUrl, $options);
 		} catch (\GuzzleHttp\Exception\ServerException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -119,7 +121,7 @@ trait Auth {
 	/**
 	 * @Given a new restricted client token is added
 	 */
-	public function aNewRestrictedClientTokenIsAdded()  {
+	public function aNewRestrictedClientTokenIsAdded() {
 		$tokenObj = $this->createClientToken();
 		$newCreatedTokenId = $tokenObj->deviceToken->id;
 		$fullUrl = substr($this->baseUrl, 0, -5) . '/index.php/settings/personal/authtokens/' . $newCreatedTokenId;
@@ -136,7 +138,7 @@ trait Auth {
 			],
 			'cookies' => $this->cookieJar,
 		];
-		$this->response = $client->send($client->createRequest('PUT', $fullUrl, $options));
+		$this->response = $client->request('PUT', $fullUrl, $options);
 		$this->restrictedClientToken = $tokenObj->token;
 	}
 
@@ -232,13 +234,13 @@ trait Auth {
 		$client = new Client();
 		$response = $client->post(
 			$loginUrl, [
-			'body' => [
-				'user' => 'user0',
-				'password' => '123456',
-				'remember_login' => $remember ? '1' : '0',
-				'requesttoken' => $this->requestToken,
-			],
-			'cookies' => $this->cookieJar,
+				'form_params' => [
+					'user' => 'user0',
+					'password' => '123456',
+					'remember_login' => $remember ? '1' : '0',
+					'requesttoken' => $this->requestToken,
+				],
+				'cookies' => $this->cookieJar,
 			]
 		);
 		$this->extracRequestTokenFromResponse($response);
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php
index f2449242bee0b7d96d97c8b80f2785a0262e1a9c..0aead766f2af944bc743cfd64253e70180c4b3a4 100644
--- a/build/integration/features/bootstrap/BasicStructure.php
+++ b/build/integration/features/bootstrap/BasicStructure.php
@@ -32,7 +32,7 @@
 use GuzzleHttp\Client;
 use GuzzleHttp\Cookie\CookieJar;
 use GuzzleHttp\Exception\ClientException;
-use GuzzleHttp\Message\ResponseInterface;
+use Psr\Http\Message\ResponseInterface;
 
 require __DIR__ . '/../../vendor/autoload.php';
 
@@ -97,7 +97,7 @@ trait BasicStructure {
 	 * @param string $version
 	 */
 	public function usingApiVersion($version) {
-		$this->apiVersion = (int) $version;
+		$this->apiVersion = (int)$version;
 	}
 
 	/**
@@ -115,7 +115,7 @@ trait BasicStructure {
 	 */
 	public function usingServer($server) {
 		$previousServer = $this->currentServer;
-		if ($server === 'LOCAL'){
+		if ($server === 'LOCAL') {
 			$this->baseUrl = $this->localBaseUrl;
 			$this->currentServer = 'LOCAL';
 			return $previousServer;
@@ -138,20 +138,24 @@ trait BasicStructure {
 	/**
 	 * Parses the xml answer to get ocs response which doesn't match with
 	 * http one in v1 of the api.
+	 *
 	 * @param ResponseInterface $response
 	 * @return string
 	 */
 	public function getOCSResponse($response) {
-		return $response->xml()->meta[0]->statuscode;
+		return simplexml_load_string($response->getBody())->meta[0]->statuscode;
 	}
 
 	/**
 	 * This function is needed to use a vertical fashion in the gherkin tables.
+	 *
 	 * @param array $arrayOfArrays
 	 * @return array
 	 */
-	public function simplifyArray($arrayOfArrays){
-		$a = array_map(function($subArray) { return $subArray[0]; }, $arrayOfArrays);
+	public function simplifyArray($arrayOfArrays) {
+		$a = array_map(function ($subArray) {
+			return $subArray[0];
+		}, $arrayOfArrays);
 		return $a;
 	}
 
@@ -175,18 +179,18 @@ trait BasicStructure {
 		];
 		if ($body instanceof \Behat\Gherkin\Node\TableNode) {
 			$fd = $body->getRowsHash();
-			$options['body'] = $fd;
+			$options['form_params'] = $fd;
 		}
 
 		// TODO: Fix this hack!
 		if ($verb === 'PUT' && $body === null) {
-			$options['body'] = [
+			$options['form_params'] = [
 				'foo' => 'bar',
 			];
 		}
 
 		try {
-			$this->response = $client->send($client->createRequest($verb, $fullUrl, $options));
+			$this->response = $client->request($verb, $fullUrl, $options);
 		} catch (ClientException $ex) {
 			$this->response = $ex->getResponse();
 		}
@@ -212,20 +216,20 @@ trait BasicStructure {
 		}
 		if ($body instanceof \Behat\Gherkin\Node\TableNode) {
 			$fd = $body->getRowsHash();
-			$options['body'] = $fd;
+			$options['form_params'] = $fd;
 		}
 
 		try {
-			$this->response = $client->send($client->createRequest($verb, $fullUrl, $options));
+			$this->response = $client->request($verb, $fullUrl, $options);
 		} catch (ClientException $ex) {
 			$this->response = $ex->getResponse();
 		}
 	}
 
-	public function isExpectedUrl($possibleUrl, $finalPart){
+	public function isExpectedUrl($possibleUrl, $finalPart) {
 		$baseUrlChopped = substr($this->baseUrl, 0, -4);
 		$endCharacter = strlen($baseUrlChopped) + strlen($finalPart);
-		return (substr($possibleUrl,0,$endCharacter) == "$baseUrlChopped" . "$finalPart");
+		return (substr($possibleUrl, 0, $endCharacter) == "$baseUrlChopped" . "$finalPart");
 	}
 
 	/**
@@ -249,7 +253,7 @@ trait BasicStructure {
 	 * @param string $contentType
 	 */
 	public function theContentTypeShouldbe($contentType) {
-		PHPUnit_Framework_Assert::assertEquals($contentType, $this->response->getHeader('Content-Type'));
+		PHPUnit_Framework_Assert::assertEquals($contentType, $this->response->getHeader('Content-Type')[0]);
 	}
 
 	/**
@@ -281,7 +285,7 @@ trait BasicStructure {
 		$response = $client->post(
 			$loginUrl,
 			[
-				'body' => [
+				'form_params' => [
 					'user' => $user,
 					'password' => $password,
 					'requesttoken' => $this->requestToken,
@@ -301,16 +305,17 @@ trait BasicStructure {
 		$baseUrl = substr($this->baseUrl, 0, -5);
 
 		$client = new Client();
-		$request = $client->createRequest(
-			$method,
-			$baseUrl . $url,
-			[
-				'cookies' => $this->cookieJar,
-			]
-		);
-		$request->addHeader('requesttoken', $this->requestToken);
 		try {
-			$this->response = $client->send($request);
+			$this->response = $client->request(
+				$method,
+				$baseUrl . $url,
+				[
+					'cookies' => $this->cookieJar,
+					'headers' => [
+						'requesttoken' => $this->requestToken
+					]
+				]
+			);
 		} catch (ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -325,21 +330,20 @@ trait BasicStructure {
 		$baseUrl = substr($this->baseUrl, 0, -5);
 
 		$client = new Client();
-		$request = $client->createRequest(
-			$method,
-			$baseUrl . $url,
-			[
-				'cookies' => $this->cookieJar,
-			]
-		);
 		try {
-			$this->response = $client->send($request);
+			$this->response = $client->request(
+				$method,
+				$baseUrl . $url,
+				[
+					'cookies' => $this->cookieJar
+				]
+			);
 		} catch (ClientException $e) {
 			$this->response = $e->getResponse();
 		}
 	}
 
-	public static function removeFile($path, $filename){
+	public static function removeFile($path, $filename) {
 		if (file_exists("$path" . "$filename")) {
 			unlink("$path" . "$filename");
 		}
@@ -358,12 +362,12 @@ trait BasicStructure {
 
 	public function createFileSpecificSize($name, $size) {
 		$file = fopen("work/" . "$name", 'w');
-		fseek($file, $size - 1 ,SEEK_CUR);
-		fwrite($file,'a'); // write a dummy char at SIZE position
+		fseek($file, $size - 1, SEEK_CUR);
+		fwrite($file, 'a'); // write a dummy char at SIZE position
 		fclose($file);
 	}
 
-	public function createFileWithText($name, $text){
+	public function createFileWithText($name, $text) {
 		$file = fopen("work/" . "$name", 'w');
 		fwrite($file, $text);
 		fclose($file);
@@ -398,8 +402,8 @@ trait BasicStructure {
 	/**
 	 * @BeforeSuite
 	 */
-	public static function addFilesToSkeleton(){
-		for ($i=0; $i<5; $i++){
+	public static function addFilesToSkeleton() {
+		for ($i = 0; $i < 5; $i++) {
 			file_put_contents("../../core/skeleton/" . "textfile" . "$i" . ".txt", "Nextcloud test text file\n");
 		}
 		if (!file_exists("../../core/skeleton/FOLDER")) {
@@ -418,8 +422,8 @@ trait BasicStructure {
 	/**
 	 * @AfterSuite
 	 */
-	public static function removeFilesFromSkeleton(){
-		for ($i=0; $i<5; $i++){
+	public static function removeFilesFromSkeleton() {
+		for ($i = 0; $i < 5; $i++) {
 			self::removeFile("../../core/skeleton/", "textfile" . "$i" . ".txt");
 		}
 		if (is_dir("../../core/skeleton/FOLDER")) {
@@ -438,24 +442,24 @@ trait BasicStructure {
 	/**
 	 * @BeforeScenario @local_storage
 	 */
-	public static function removeFilesFromLocalStorageBefore(){
+	public static function removeFilesFromLocalStorageBefore() {
 		$dir = "./work/local_storage/";
 		$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
 		$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
-		foreach ( $ri as $file ) {
-			$file->isDir() ?  rmdir($file) : unlink($file);
+		foreach ($ri as $file) {
+			$file->isDir() ? rmdir($file) : unlink($file);
 		}
 	}
 
 	/**
 	 * @AfterScenario @local_storage
 	 */
-	public static function removeFilesFromLocalStorageAfter(){
+	public static function removeFilesFromLocalStorageAfter() {
 		$dir = "./work/local_storage/";
 		$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
 		$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
-		foreach ( $ri as $file ) {
-			$file->isDir() ?  rmdir($file) : unlink($file);
+		foreach ($ri as $file) {
+			$file->isDir() ? rmdir($file) : unlink($file);
 		}
 	}
 }
diff --git a/build/integration/features/bootstrap/CalDavContext.php b/build/integration/features/bootstrap/CalDavContext.php
index 27f26b20fbe084dc691012ae13f24e868c19a43b..cbd29a4fbff439683f5ef14c12cde83daea4fcdc 100644
--- a/build/integration/features/bootstrap/CalDavContext.php
+++ b/build/integration/features/bootstrap/CalDavContext.php
@@ -83,7 +83,7 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 
 		$password = ($user === 'admin') ? 'admin' : '123456';
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPFIND',
 				$davUrl,
 				[
@@ -93,7 +93,6 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -170,7 +169,7 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 		$davUrl = $this->baseUrl . '/remote.php/dav/calendars/'.$user.'/'.$name;
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'MKCALENDAR',
 			$davUrl,
 			[
@@ -181,8 +180,6 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 				],
 			]
 		);
-
-		$this->response = $this->client->send($request);
 	}
 
 	/**
@@ -195,7 +192,7 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 		$davUrl = $this->baseUrl . '/remote.php/dav/calendars/'.$user.'/'.$name;
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'POST',
 			$davUrl,
 			[
@@ -209,8 +206,6 @@ class CalDavContext implements \Behat\Behat\Context\Context {
 				],
 			]
 		);
-
-		$this->response = $this->client->send($request);
 	}
 
 	/**
diff --git a/build/integration/features/bootstrap/CapabilitiesContext.php b/build/integration/features/bootstrap/CapabilitiesContext.php
index 6ff9b1813c4a6d63e6c3111837c022bd05fe1d0c..c3cbace5932b1b0e7ddafd0202126e40f1ac045c 100644
--- a/build/integration/features/bootstrap/CapabilitiesContext.php
+++ b/build/integration/features/bootstrap/CapabilitiesContext.php
@@ -44,7 +44,7 @@ class CapabilitiesContext implements Context, SnippetAcceptingContext {
 	 * @param \Behat\Gherkin\Node\TableNode|null $formData
 	 */
 	public function checkCapabilitiesResponse(\Behat\Gherkin\Node\TableNode $formData){
-		$capabilitiesXML = $this->response->xml()->data->capabilities;
+		$capabilitiesXML = simplexml_load_string($this->response->getBody())->data->capabilities;
 
 		foreach ($formData->getHash() as $row) {
 			$path_to_element = explode('@@@', $row['path_to_element']);
diff --git a/build/integration/features/bootstrap/CardDavContext.php b/build/integration/features/bootstrap/CardDavContext.php
index dbac4e2254fe5413ebbd61192050a73867d8f40c..d971c42755a61b800ae37b962c71f57842ec7ead 100644
--- a/build/integration/features/bootstrap/CardDavContext.php
+++ b/build/integration/features/bootstrap/CardDavContext.php
@@ -86,7 +86,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 
 		$password = ($user === 'admin') ? 'admin' : '123456';
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPFIND',
 				$davUrl,
 				[
@@ -96,7 +96,6 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -130,7 +129,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 		$davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/'.$user.'/'.$addressBook;
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'MKCOL',
 			$davUrl,
 			[
@@ -154,8 +153,6 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 			]
 		);
 
-		$this->response = $this->client->send($request);
-
 		if($this->response->getStatusCode() !== (int)$statusCode) {
 			throw new \Exception(
 				sprintf(
@@ -212,7 +209,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 		$davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/'.$user.'/'.$addressBook . '/' . $fileName;
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'PUT',
 			$davUrl,
 			[
@@ -227,8 +224,6 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 			]
 		);
 
-		$this->response = $this->client->send($request);
-
 		if($this->response->getStatusCode() !== 201) {
 			throw new \Exception(
 				sprintf(
@@ -248,7 +243,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'GET',
 				$davUrl,
 				[
@@ -261,7 +256,6 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -275,7 +269,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 		$password = ($user === 'admin') ? 'admin' : '123456';
 
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'GET',
 				$davUrl,
 				[
@@ -288,7 +282,6 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 				$this->response = $e->getResponse();
 		}
@@ -303,7 +296,7 @@ class CardDavContext implements \Behat\Behat\Context\Context {
 		foreach($table->getTable() as $header) {
 			$headerName = $header[0];
 			$expectedHeaderValue = $header[1];
-			$returnedHeader = $this->response->getHeader($headerName);
+			$returnedHeader = $this->response->getHeader($headerName)[0];
 			if($returnedHeader !== $expectedHeaderValue) {
 				throw new \Exception(
 					sprintf(
diff --git a/build/integration/features/bootstrap/ChecksumsContext.php b/build/integration/features/bootstrap/ChecksumsContext.php
index f2fc2d1d653f133104ba3ad9d2c311c87b851cec..434a3b65f15b9a3088a5c3f5dc8cc43e7591c7f3 100644
--- a/build/integration/features/bootstrap/ChecksumsContext.php
+++ b/build/integration/features/bootstrap/ChecksumsContext.php
@@ -78,7 +78,7 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function userUploadsFileToWithChecksum($user, $source, $destination, $checksum)
 	{
-		$file = \GuzzleHttp\Stream\Stream::factory(fopen($source, 'r'));
+		$file = \GuzzleHttp\Psr7\stream_for(fopen($source, 'r'));
 		try {
 			$this->response = $this->client->put(
 				$this->baseUrl . '/remote.php/webdav' . $destination,
@@ -117,7 +117,7 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function userRequestTheChecksumOfViaPropfind($user, $path)
 	{
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'PROPFIND',
 			$this->baseUrl . '/remote.php/webdav' . $path,
 			[
@@ -133,7 +133,6 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 				]
 			]
 		);
-		$this->response = $this->client->send($request);
 	}
 
 	/**
@@ -182,8 +181,8 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function theHeaderChecksumShouldMatch($checksum)
 	{
-		if ($this->response->getHeader('OC-Checksum') !== $checksum) {
-			throw new \Exception("Expected $checksum, got ".$this->response->getHeader('OC-Checksum'));
+		if ($this->response->getHeader('OC-Checksum')[0] !== $checksum) {
+			throw new \Exception("Expected $checksum, got ".$this->response->getHeader('OC-Checksum')[0]);
 		}
 	}
 
@@ -195,7 +194,7 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function userCopiedFileTo($user, $source, $destination)
 	{
-		$request = $this->client->createRequest(
+		$this->response = $this->client->request(
 			'MOVE',
 			$this->baseUrl . '/remote.php/webdav' . $source,
 			[
@@ -208,7 +207,6 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 				],
 			]
 		);
-		$this->response = $this->client->send($request);
 	}
 
 	/**
@@ -236,7 +234,7 @@ class ChecksumsContext implements \Behat\Behat\Context\Context {
 	public function theOcChecksumHeaderShouldNotBeThere()
 	{
 		if ($this->response->hasHeader('OC-Checksum')) {
-			throw new \Exception("Expected no checksum header but got ".$this->response->getHeader('OC-Checksum'));
+			throw new \Exception("Expected no checksum header but got ".$this->response->getHeader('OC-Checksum')[0]);
 		}
 	}
 
diff --git a/build/integration/features/bootstrap/CommandLine.php b/build/integration/features/bootstrap/CommandLine.php
index 2c717e7f5ed1143fce122d2c408b115d938740d7..c6fd232ac9c6a18435e40cc3467391b2bc615daa 100644
--- a/build/integration/features/bootstrap/CommandLine.php
+++ b/build/integration/features/bootstrap/CommandLine.php
@@ -59,8 +59,7 @@ trait CommandLine {
 
 		// Clean opcode cache
 		$client = new GuzzleHttp\Client();
-		$request = $client->createRequest('GET', 'http://localhost:8080/apps/testing/clean_opcode_cache.php');
-		$client->send($request);
+		$client->request('GET', 'http://localhost:8080/apps/testing/clean_opcode_cache.php');
 
 		return $this->lastCode;
 	}
diff --git a/build/integration/features/bootstrap/CommentsContext.php b/build/integration/features/bootstrap/CommentsContext.php
index 651e8c5eedf0151167966ff77beec57a6533500d..ce05b56689d8a3b05ac7cef2e8a4e26adce33314 100644
--- a/build/integration/features/bootstrap/CommentsContext.php
+++ b/build/integration/features/bootstrap/CommentsContext.php
@@ -52,7 +52,7 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 		$client = new \GuzzleHttp\Client();
 		try {
 			$client->delete(
-				$this->baseUrl.'/remote.php/webdav/myFileToComment.txt',
+				$this->baseUrl . '/remote.php/webdav/myFileToComment.txt',
 				[
 					'auth' => [
 						'user0',
@@ -73,7 +73,7 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	 * @return int
 	 */
 	private function getFileIdForPath($path) {
-		$url = $this->baseUrl.'/remote.php/webdav/'.$path;
+		$url = $this->baseUrl . '/remote.php/webdav/' . $path;
 		$context = stream_context_create(array(
 			'http' => array(
 				'method' => 'PROPFIND',
@@ -100,10 +100,10 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	 * @param int $statusCode
 	 * @throws \Exception
 	 */
-	public function postsACommentWithContentOnTheFileNamedItShouldReturn($user, $content, $fileName, $statusCode)  {
+	public function postsACommentWithContentOnTheFileNamedItShouldReturn($user, $content, $fileName, $statusCode) {
 		$fileId = $this->getFileIdForPath($fileName);
 		$this->fileId = (int)$fileId;
-		$url = $this->baseUrl.'/remote.php/dav/comments/files/'.$fileId.'/';
+		$url = $this->baseUrl . '/remote.php/dav/comments/files/' . $fileId . '/';
 
 		$client = new \GuzzleHttp\Client();
 		try {
@@ -124,8 +124,8 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 			$res = $e->getResponse();
 		}
 
-		if($res->getStatusCode() !== (int)$statusCode) {
-			throw new \Exception("Response status code was not $statusCode (".$res->getStatusCode().")");
+		if ($res->getStatusCode() !== (int)$statusCode) {
+			throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
 		}
 	}
 
@@ -139,11 +139,11 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function asLoadloadAllTheCommentsOfTheFileNamedItShouldReturn($user, $fileName, $statusCode) {
 		$fileId = $this->getFileIdForPath($fileName);
-		$url = $this->baseUrl.'/remote.php/dav/comments/files/'.$fileId.'/';
+		$url = $this->baseUrl . '/remote.php/dav/comments/files/' . $fileId . '/';
 
 		try {
 			$client = new \GuzzleHttp\Client();
-			$res = $client->createRequest(
+			$res = $client->request(
 				'REPORT',
 				$url,
 				[
@@ -162,16 +162,15 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$res = $client->send($res);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$res = $e->getResponse();
 		}
 
-		if($res->getStatusCode() !== (int)$statusCode) {
-			throw new \Exception("Response status code was not $statusCode (".$res->getStatusCode().")");
+		if ($res->getStatusCode() !== (int)$statusCode) {
+			throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
 		}
 
-		if($res->getStatusCode() === 207) {
+		if ($res->getStatusCode() === 207) {
 			$service = new Sabre\Xml\Service();
 			$this->response = $service->parse($res->getBody()->getContents());
 			$this->commentId = (int)$this->response[0]['value'][2]['value'][0]['value'][0]['value'];
@@ -191,11 +190,11 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 		$options = [];
 		$options['auth'] = [$user, '123456'];
 		$fd = $body->getRowsHash();
-		$options['body'] = $fd;
+		$options['form_params'] = $fd;
 		$options['headers'] = [
 			'OCS-APIREQUEST' => 'true',
 		];
-		$client->send($client->createRequest($verb, $this->baseUrl.'/ocs/v1.php/'.$url, $options));
+		$client->request($verb, $this->baseUrl . '/ocs/v1.php/' . $url, $options);
 	}
 
 	/**
@@ -205,7 +204,7 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	 * @throws \Exception
 	 */
 	public function asDeleteTheCreatedCommentItShouldReturn($user, $statusCode) {
-		$url = $this->baseUrl.'/remote.php/dav/comments/files/'.$this->fileId.'/'.$this->commentId;
+		$url = $this->baseUrl . '/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId;
 
 		$client = new \GuzzleHttp\Client();
 		try {
@@ -225,8 +224,8 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 			$res = $e->getResponse();
 		}
 
-		if($res->getStatusCode() !== (int)$statusCode) {
-			throw new \Exception("Response status code was not $statusCode (".$res->getStatusCode().")");
+		if ($res->getStatusCode() !== (int)$statusCode) {
+			throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
 		}
 	}
 
@@ -239,14 +238,14 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	public function theResponseShouldContainAPropertyWithValue($key, $value) {
 		$keys = $this->response[0]['value'][2]['value'][0]['value'];
 		$found = false;
-		foreach($keys as $singleKey) {
-			if($singleKey['name'] === '{http://owncloud.org/ns}'.substr($key, 3)) {
-				if($singleKey['value'] === $value) {
+		foreach ($keys as $singleKey) {
+			if ($singleKey['name'] === '{http://owncloud.org/ns}' . substr($key, 3)) {
+				if ($singleKey['value'] === $value) {
 					$found = true;
 				}
 			}
 		}
-		if($found === false) {
+		if ($found === false) {
 			throw new \Exception("Cannot find property $key with $value");
 		}
 	}
@@ -257,8 +256,8 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 	 * @throws \Exception
 	 */
 	public function theResponseShouldContainOnlyComments($number) {
-		if(count($this->response) !== (int)$number) {
-			throw new \Exception("Found more comments than $number (".count($this->response).")");
+		if (count($this->response) !== (int)$number) {
+			throw new \Exception("Found more comments than $number (" . count($this->response) . ")");
 		}
 	}
 
@@ -277,18 +276,18 @@ class CommentsContext implements \Behat\Behat\Context\Context {
 <d:propertyupdate  xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
   <d:set>
    <d:prop>
-      <oc:message>'.$text.'</oc:message>
+      <oc:message>' . $text . '</oc:message>
     </d:prop>
   </d:set>
 </d:propertyupdate>';
 		try {
-			$res = $client->send($client->createRequest('PROPPATCH', $this->baseUrl.'/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId, $options));
+			$res = $client->request('PROPPATCH', $this->baseUrl . '/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId, $options);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$res = $e->getResponse();
 		}
 
-		if($res->getStatusCode() !== (int)$statusCode) {
-			throw new \Exception("Response status code was not $statusCode (".$res->getStatusCode().")");
+		if ($res->getStatusCode() !== (int)$statusCode) {
+			throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
 		}
 	}
 
diff --git a/build/integration/features/bootstrap/FederationContext.php b/build/integration/features/bootstrap/FederationContext.php
index f6c6de335a818c450ab37ebd0556caf058fd9dcc..f3eb004fb848a0a4bde92c41c0a02463e1ae7baa 100644
--- a/build/integration/features/bootstrap/FederationContext.php
+++ b/build/integration/features/bootstrap/FederationContext.php
@@ -67,7 +67,7 @@ class FederationContext implements Context, SnippetAcceptingContext {
 		$this->sendingToWith('GET', "/apps/files_sharing/api/v1/remote_shares/pending", null);
 		$this->theHTTPStatusCodeShouldBe('200');
 		$this->theOCSStatusCodeShouldBe('100');
-		$share_id = $this->response->xml()->data[0]->element[0]->id;
+		$share_id = simplexml_load_string($this->response->getBody())->data[0]->element[0]->id;
 		$this->sendingToWith('POST', "/apps/files_sharing/api/v1/remote_shares/pending/{$share_id}", null);
 		$this->theHTTPStatusCodeShouldBe('200');
 		$this->theOCSStatusCodeShouldBe('100');
diff --git a/build/integration/features/bootstrap/FilesDropContext.php b/build/integration/features/bootstrap/FilesDropContext.php
index 62d06ddf7500d0c6d9d5495b219933f33c5ea2cd..a81df559a2378615c72c131da5fc0de27844dda5 100644
--- a/build/integration/features/bootstrap/FilesDropContext.php
+++ b/build/integration/features/bootstrap/FilesDropContext.php
@@ -50,13 +50,10 @@ class FilesDropContext implements Context, SnippetAcceptingContext {
 		$options['headers'] = [
 			'X-REQUESTED-WITH' => 'XMLHttpRequest'
 		];
-
-		$request = $client->createRequest('PUT', $fullUrl, $options);
-		$file = \GuzzleHttp\Stream\Stream::factory($content);
-		$request->setBody($file);
+		$options['body'] = \GuzzleHttp\Psr7\stream_for($content);
 
 		try {
-			$this->response = $client->send($request);
+			$this->response = $client->request('PUT', $fullUrl, $options);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -82,10 +79,8 @@ class FilesDropContext implements Context, SnippetAcceptingContext {
 			'X-REQUESTED-WITH' => 'XMLHttpRequest'
 		];
 
-		$request = $client->createRequest('MKCOL', $fullUrl, $options);
-
 		try {
-			$this->response = $client->send($request);
+			$this->response = $client->request('MKCOL', $fullUrl, $options);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
diff --git a/build/integration/features/bootstrap/LDAPContext.php b/build/integration/features/bootstrap/LDAPContext.php
index 237f316674f42d9deb49c3be7184efe66b6696d5..3a9c59b52b4942fb4f36c230023d266006465f9c 100644
--- a/build/integration/features/bootstrap/LDAPContext.php
+++ b/build/integration/features/bootstrap/LDAPContext.php
@@ -35,7 +35,7 @@ class LDAPContext implements Context {
 	 * @Given /^the response should contain a tag "([^"]*)"$/
 	 */
 	public function theResponseShouldContainATag($arg1) {
-		$configID = $this->response->xml()->data[0]->$arg1;
+		$configID = simplexml_load_string($this->response->getBody())->data[0]->$arg1;
 		PHPUnit_Framework_Assert::assertInstanceOf(SimpleXMLElement::class, $configID[0]);
 	}
 
@@ -45,7 +45,7 @@ class LDAPContext implements Context {
 	public function creatingAnLDAPConfigurationAt($apiUrl) {
 		$this->apiUrl = $apiUrl;
 		$this->sendingToWith('POST', $this->apiUrl, null);
-		$configElements = $this->response->xml()->data[0]->configID;
+		$configElements = simplexml_load_string($this->response->getBody())->data[0]->configID;
 		$this->configID = $configElements[0];
 	}
 
@@ -60,7 +60,7 @@ class LDAPContext implements Context {
 	 * @Given /^the response should contain a tag "([^"]*)" with value "([^"]*)"$/
 	 */
 	public function theResponseShouldContainATagWithValue($tagName, $expectedValue) {
-		$data = $this->response->xml()->data[0]->$tagName;
+		$data = simplexml_load_string($this->response->getBody())->data[0]->$tagName;
 		PHPUnit_Framework_Assert::assertEquals($expectedValue, $data[0]);
 	}
 
diff --git a/build/integration/features/bootstrap/Provisioning.php b/build/integration/features/bootstrap/Provisioning.php
index 00402d73a2cc33508e594b54d66f0ffc622b6290..2543777faa5377f710f1fa564e8d09909d61a92f 100644
--- a/build/integration/features/bootstrap/Provisioning.php
+++ b/build/integration/features/bootstrap/Provisioning.php
@@ -26,6 +26,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 use GuzzleHttp\Client;
 use GuzzleHttp\Message\ResponseInterface;
 
@@ -42,7 +43,7 @@ trait Provisioning {
 
 	/** @var array */
 	private $createdRemoteGroups = [];
-	
+
 	/** @var array */
 	private $createdGroups = [];
 
@@ -95,7 +96,7 @@ trait Provisioning {
 			$options['auth'] = $this->adminUser;
 		}
 
-		$options['body'] = [
+		$options['form_params'] = [
 			'userid' => $user,
 			'password' => '123456'
 		];
@@ -103,8 +104,8 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
-		if ($this->currentServer === 'LOCAL'){
+		$this->response = $client->post($fullUrl, $options);
+		if ($this->currentServer === 'LOCAL') {
 			$this->createdUsers[$user] = $user;
 		} elseif ($this->currentServer === 'REMOTE') {
 			$this->createdRemoteUsers[$user] = $user;
@@ -117,8 +118,8 @@ trait Provisioning {
 		$options2['headers'] = [
 			'OCS-APIREQUEST' => 'true',
 		];
-		$url = $fullUrl.'/'.$user;
-		$client->send($client->createRequest('GET', $url, $options2));
+		$url = $fullUrl . '/' . $user;
+		$client->get($url, $options2);
 	}
 
 	/**
@@ -136,9 +137,9 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$response = $client->send($client->createRequest("GET", $fullUrl, $options));
+		$response = $client->get($fullUrl, $options);
 		foreach ($settings->getRows() as $setting) {
-			$value = json_decode(json_encode($response->xml()->data->{$setting[0]}), 1);
+			$value = json_decode(json_encode(simplexml_load_string($response->getBody())->data->{$setting[0]}), 1);
 			if (isset($value[0])) {
 				PHPUnit_Framework_Assert::assertEquals($setting[1], $value[0], "", 0.0, 10, true);
 			} else {
@@ -179,7 +180,7 @@ trait Provisioning {
 		$this->currentUser = $previous_user;
 	}
 
-	public function userExists($user){
+	public function userExists($user) {
 		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
 		$client = new Client();
 		$options = [];
@@ -229,9 +230,9 @@ trait Provisioning {
 		$respondedArray = $this->getArrayOfGroupsResponded($this->response);
 
 		if (array_key_exists($group, $respondedArray)) {
-			return True;
-		} else{
-			return False;
+			return true;
+		} else {
+			return false;
 		}
 	}
 
@@ -240,11 +241,11 @@ trait Provisioning {
 	 * @param string $user
 	 * @param string $group
 	 */
-	public function assureUserBelongsToGroup($user, $group){
+	public function assureUserBelongsToGroup($user, $group) {
 		$previous_user = $this->currentUser;
 		$this->currentUser = "admin";
 
-		if (!$this->userBelongsToGroup($user, $group)){
+		if (!$this->userBelongsToGroup($user, $group)) {
 			$this->addingUserToGroup($user, $group);
 		}
 
@@ -287,15 +288,15 @@ trait Provisioning {
 			$options['auth'] = $this->adminUser;
 		}
 
-		$options['body'] = [
+		$options['form_params'] = [
 			'groupid' => $group,
 		];
 		$options['headers'] = [
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
-		if ($this->currentServer === 'LOCAL'){
+		$this->response = $client->post($fullUrl, $options);
+		if ($this->currentServer === 'LOCAL') {
 			$this->createdGroups[$group] = $group;
 		} elseif ($this->currentServer === 'REMOTE') {
 			$this->createdRemoteGroups[$group] = $group;
@@ -316,11 +317,11 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 		// TODO: fix hack
-		$options['body'] = [
+		$options['form_params'] = [
 			'foo' => 'bar'
 		];
 
-		$this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+		$this->response = $client->put($fullUrl, $options);
 	}
 
 	/**
@@ -338,7 +339,7 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+		$this->response = $client->delete($fullUrl, $options);
 	}
 
 	/**
@@ -356,9 +357,9 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+		$this->response = $client->delete($fullUrl, $options);
 
-		if ($this->currentServer === 'LOCAL'){
+		if ($this->currentServer === 'LOCAL') {
 			unset($this->createdGroups[$group]);
 		} elseif ($this->currentServer === 'REMOTE') {
 			unset($this->createdRemoteGroups[$group]);
@@ -393,11 +394,11 @@ trait Provisioning {
 			'OCS-APIREQUEST' => 'true',
 		];
 
-		$options['body'] = [
+		$options['form_params'] = [
 			'groupid' => $group,
 		];
 
-		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+		$this->response =$client->post($fullUrl, $options);
 	}
 
 
@@ -489,13 +490,13 @@ trait Provisioning {
 		if ($this->currentUser === 'admin') {
 			$options['auth'] = $this->adminUser;
 		}
-		$options['body'] = [
+		$options['form_params'] = [
 			'groupid' => $group
 		];
 		$options['headers'] = [
 			'OCS-APIREQUEST' => 'true',
 		];
-		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+		$this->response = $client->post($fullUrl, $options);
 		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
@@ -588,44 +589,48 @@ trait Provisioning {
 
 	/**
 	 * Parses the xml answer to get the array of users returned.
+	 *
 	 * @param ResponseInterface $resp
 	 * @return array
 	 */
 	public function getArrayOfUsersResponded($resp) {
-		$listCheckedElements = $resp->xml()->data[0]->users[0]->element;
+		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users[0]->element;
 		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
 		return $extractedElementsArray;
 	}
 
 	/**
 	 * Parses the xml answer to get the array of groups returned.
+	 *
 	 * @param ResponseInterface $resp
 	 * @return array
 	 */
 	public function getArrayOfGroupsResponded($resp) {
-		$listCheckedElements = $resp->xml()->data[0]->groups[0]->element;
+		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->groups[0]->element;
 		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
 		return $extractedElementsArray;
 	}
 
 	/**
 	 * Parses the xml answer to get the array of apps returned.
+	 *
 	 * @param ResponseInterface $resp
 	 * @return array
 	 */
 	public function getArrayOfAppsResponded($resp) {
-		$listCheckedElements = $resp->xml()->data[0]->apps[0]->element;
+		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->apps[0]->element;
 		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
 		return $extractedElementsArray;
 	}
 
 	/**
 	 * Parses the xml answer to get the array of subadmins returned.
+	 *
 	 * @param ResponseInterface $resp
 	 * @return array
 	 */
 	public function getArrayOfSubadminsResponded($resp) {
-		$listCheckedElements = $resp->xml()->data[0]->element;
+		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->element;
 		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
 		return $extractedElementsArray;
 	}
@@ -689,7 +694,7 @@ trait Provisioning {
 		];
 
 		$this->response = $client->get($fullUrl, $options);
-		PHPUnit_Framework_Assert::assertEquals("false", $this->response->xml()->data[0]->enabled);
+		PHPUnit_Framework_Assert::assertEquals("false", simplexml_load_string($this->response->getBody())->data[0]->enabled);
 	}
 
 	/**
@@ -708,7 +713,7 @@ trait Provisioning {
 		];
 
 		$this->response = $client->get($fullUrl, $options);
-		PHPUnit_Framework_Assert::assertEquals("true", $this->response->xml()->data[0]->enabled);
+		PHPUnit_Framework_Assert::assertEquals("true", simplexml_load_string($this->response->getBody())->data[0]->enabled);
 	}
 
 	/**
@@ -716,8 +721,7 @@ trait Provisioning {
 	 * @param string $user
 	 * @param string $quota
 	 */
-	public function userHasAQuotaOf($user, $quota)
-	{
+	public function userHasAQuotaOf($user, $quota) {
 		$body = new \Behat\Gherkin\Node\TableNode([
 			0 => ['key', 'quota'],
 			1 => ['value', $quota],
@@ -731,13 +735,13 @@ trait Provisioning {
 	 * @Given user :user has unlimited quota
 	 * @param string $user
 	 */
-	public function userHasUnlimitedQuota($user)
-	{
+	public function userHasUnlimitedQuota($user) {
 		$this->userHasAQuotaOf($user, 'none');
 	}
 
 	/**
 	 * Returns home path of the given user
+	 *
 	 * @param string $user
 	 */
 	public function getUserHome($user) {
@@ -746,22 +750,21 @@ trait Provisioning {
 		$options = [];
 		$options['auth'] = $this->adminUser;
 		$this->response = $client->get($fullUrl, $options);
-		return $this->response->xml()->data[0]->home;
+		return simplexml_load_string($this->response->getBody())->data[0]->home;
 	}
 
 	/**
 	 * @BeforeScenario
 	 * @AfterScenario
 	 */
-	public function cleanupUsers()
-	{
+	public function cleanupUsers() {
 		$previousServer = $this->currentServer;
 		$this->usingServer('LOCAL');
-		foreach($this->createdUsers as $user) {	
+		foreach ($this->createdUsers as $user) {
 			$this->deleteUser($user);
 		}
 		$this->usingServer('REMOTE');
-		foreach($this->createdRemoteUsers as $remoteUser) {
+		foreach ($this->createdRemoteUsers as $remoteUser) {
 			$this->deleteUser($remoteUser);
 		}
 		$this->usingServer($previousServer);
@@ -771,15 +774,14 @@ trait Provisioning {
 	 * @BeforeScenario
 	 * @AfterScenario
 	 */
-	public function cleanupGroups()
-	{
+	public function cleanupGroups() {
 		$previousServer = $this->currentServer;
 		$this->usingServer('LOCAL');
-		foreach($this->createdGroups as $group) {
+		foreach ($this->createdGroups as $group) {
 			$this->deleteGroup($group);
 		}
 		$this->usingServer('REMOTE');
-		foreach($this->createdRemoteGroups as $remoteGroup) {
+		foreach ($this->createdRemoteGroups as $remoteGroup) {
 			$this->deleteGroup($remoteGroup);
 		}
 		$this->usingServer($previousServer);
diff --git a/build/integration/features/bootstrap/ShareesContext.php b/build/integration/features/bootstrap/ShareesContext.php
index f659495fcae3ab17a709493b7d64ef206ccb5eb5..24b413ec0912bd054927a6ff99e7df3999b1cfad 100644
--- a/build/integration/features/bootstrap/ShareesContext.php
+++ b/build/integration/features/bootstrap/ShareesContext.php
@@ -23,7 +23,7 @@
  */
 use Behat\Behat\Context\Context;
 use Behat\Behat\Context\SnippetAcceptingContext;
-use GuzzleHttp\Message\ResponseInterface;
+use Psr\Http\Message\ResponseInterface;
 
 require __DIR__ . '/../../vendor/autoload.php';
 
@@ -72,7 +72,7 @@ class ShareesContext implements Context, SnippetAcceptingContext {
 	}
 
 	public function getArrayOfShareesResponded(ResponseInterface $response, $shareeType) {
-		$elements = $response->xml()->data;
+		$elements = simplexml_load_string($response->getBody())->data;
 		$elements = json_decode(json_encode($elements), 1);
 		if (strpos($shareeType, 'exact ') === 0) {
 			$elements = $elements['exact'];
diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php
index 1921a86656dfebad66225fd86c194ce9166f0d30..7aa29e17ee6285da33d3a31bf62abf0b6be93112 100644
--- a/build/integration/features/bootstrap/Sharing.php
+++ b/build/integration/features/bootstrap/Sharing.php
@@ -44,6 +44,9 @@ trait Sharing {
 	/** @var int */
 	private $savedShareId = null;
 
+	/** @var \Psr\Http\Message\ResponseInterface */
+	private $response;
+
 	/**
 	 * @Given /^as "([^"]*)" creating a share with$/
 	 * @param string $user
@@ -69,16 +72,16 @@ trait Sharing {
 				$dateModification = $fd['expireDate'];
 				$fd['expireDate'] = date('Y-m-d', strtotime($dateModification));
 			}
-			$options['body'] = $fd;
+			$options['form_params'] = $fd;
 		}
 
 		try {
-			$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+			$this->response = $client->request("POST", $fullUrl, $options);
 		} catch (\GuzzleHttp\Exception\ClientException $ex) {
 			$this->response = $ex->getResponse();
 		}
 
-		$this->lastShareData = $this->response->xml();
+		$this->lastShareData = simplexml_load_string($this->response->getBody());
 	}
 
 	/**
@@ -159,8 +162,8 @@ trait Sharing {
 			$options['auth'] = [$this->currentUser, $this->regularUser];
 		}
 		$date = date('Y-m-d', strtotime("+3 days"));
-		$options['body'] = ['expireDate' => $date];
-		$this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+		$options['form_params'] = ['expireDate' => $date];
+		$this->response = $this->response = $client->request("PUT", $fullUrl, $options);
 		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
@@ -189,11 +192,11 @@ trait Sharing {
 				$dateModification = $fd['expireDate'];
 				$fd['expireDate'] = date('Y-m-d', strtotime($dateModification));
 			}
-			$options['body'] = $fd;
+			$options['form_params'] = $fd;
 		}
 
 		try {
-			$this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+			$this->response = $client->request("PUT", $fullUrl, $options);
 		} catch (\GuzzleHttp\Exception\ClientException $ex) {
 			$this->response = $ex->getResponse();
 		}
@@ -221,38 +224,39 @@ trait Sharing {
 		} else {
 			$options['auth'] = [$user, $this->regularUser];
 		}
-		$fd = [];
+		$body = [];
 		if (!is_null($path)){
-			$fd['path'] = $path;
+			$body['path'] = $path;
 		}
 		if (!is_null($shareType)){
-			$fd['shareType'] = $shareType;
+			$body['shareType'] = $shareType;
 		}
 		if (!is_null($shareWith)){
-			$fd['shareWith'] = $shareWith;
+			$body['shareWith'] = $shareWith;
 		}
 		if (!is_null($publicUpload)){
-			$fd['publicUpload'] = $publicUpload;
+			$body['publicUpload'] = $publicUpload;
 		}
 		if (!is_null($password)){
-			$fd['password'] = $password;
+			$body['password'] = $password;
 		}
 		if (!is_null($permissions)){
-			$fd['permissions'] = $permissions;
+			$body['permissions'] = $permissions;
 		}
 
-		$options['body'] = $fd;
+		$options['form_params'] = $body;
 
 		try {
-			$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
-			$this->lastShareData = $this->response->xml();
+			$this->response = $client->request("POST", $fullUrl, $options);
+			$this->lastShareData = simplexml_load_string($this->response->getBody());
 		} catch (\GuzzleHttp\Exception\ClientException $ex) {
 			$this->response = $ex->getResponse();
+			throw new \Exception($this->response->getBody());
 		}
 	}
 
 	public function isFieldInResponse($field, $contentExpected){
-		$data = $this->response->xml()->data[0];
+		$data = simplexml_load_string($this->response->getBody())->data[0];
 		if ((string)$field == 'expiration'){
 			$contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00";
 		}
@@ -330,7 +334,7 @@ trait Sharing {
 	}
 
 	public function isUserOrGroupInSharedData($userOrGroup, $permissions = null){
-		$data = $this->response->xml()->data[0];
+		$data = simplexml_load_string($this->response->getBody())->data[0];
 		foreach($data as $element) {
 			if ($element->share_with == $userOrGroup && ($permissions === null || $permissions == $element->permissions)){
 				return True;
@@ -532,7 +536,7 @@ trait Sharing {
 		foreach($table->getTable() as $header) {
 			$headerName = $header[0];
 			$expectedHeaderValue = $header[1];
-			$returnedHeader = $this->response->getHeader($headerName);
+			$returnedHeader = $this->response->getHeader($headerName)[0];
 			if($returnedHeader !== $expectedHeaderValue) {
 				throw new \Exception(
 					sprintf(
diff --git a/build/integration/features/bootstrap/TagsContext.php b/build/integration/features/bootstrap/TagsContext.php
index df2f1cae26309838fc71987060ccdcee8e46979a..5ccb20eaafe9013e957e893934ef7df56be15178 100644
--- a/build/integration/features/bootstrap/TagsContext.php
+++ b/build/integration/features/bootstrap/TagsContext.php
@@ -32,7 +32,7 @@ use GuzzleHttp\Client;
 use GuzzleHttp\Message\ResponseInterface;
 
 class TagsContext implements \Behat\Behat\Context\Context {
-	/** @var string  */
+	/** @var string */
 	private $baseUrl;
 	/** @var Client */
 	private $client;
@@ -61,9 +61,9 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	public function tearDownScenario() {
 		$user = 'admin';
 		$tags = $this->requestTagsForUser($user);
-		foreach($tags as $tagId => $tag) {
+		foreach ($tags as $tagId => $tag) {
 			$this->response = $this->client->delete(
-				$this->baseUrl . '/remote.php/dav/systemtags/'.$tagId,
+				$this->baseUrl . '/remote.php/dav/systemtags/' . $tagId,
 				[
 					'auth' => [
 						$user,
@@ -88,7 +88,8 @@ class TagsContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-		} catch (\GuzzleHttp\Exception\ClientException $e) {}
+		} catch (\GuzzleHttp\Exception\ClientException $e) {
+		}
 	}
 
 	/**
@@ -96,7 +97,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @return string
 	 */
 	private function getPasswordForUser($userName) {
-		if($userName === 'admin') {
+		if ($userName === 'admin') {
 			return 'admin';
 		}
 		return '123456';
@@ -181,8 +182,8 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @throws \Exception
 	 */
 	public function theResponseShouldHaveAStatusCode($statusCode) {
-		if((int)$statusCode !== $this->response->getStatusCode()) {
-			throw new \Exception("Expected $statusCode, got ".$this->response->getStatusCode());
+		if ((int)$statusCode !== $this->response->getStatusCode()) {
+			throw new \Exception("Expected $statusCode, got " . $this->response->getStatusCode());
 		}
 	}
 
@@ -211,7 +212,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 			$body .= '
   </d:prop>
 </d:propfind>';
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPFIND',
 				$this->baseUrl . '/remote.php/dav/systemtags/',
 				[
@@ -225,7 +226,6 @@ class TagsContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -233,9 +233,9 @@ class TagsContext implements \Behat\Behat\Context\Context {
 		$tags = [];
 		$service = new Sabre\Xml\Service();
 		$parsed = $service->parse($this->response->getBody()->getContents());
-		foreach($parsed as $entry) {
+		foreach ($parsed as $entry) {
 			$singleEntry = $entry['value'][1]['value'][0]['value'];
-			if(empty($singleEntry[0]['value'])) {
+			if (empty($singleEntry[0]['value'])) {
 				continue;
 			}
 
@@ -263,7 +263,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	public function theFollowingTagsShouldExistFor($user, TableNode $table) {
 		$tags = $this->requestTagsForUser($user);
 
-		if(count($table->getRows()) !== count($tags)) {
+		if (count($table->getRows()) !== count($tags)) {
 			throw new \Exception(
 				sprintf(
 					"Expected %s tags, got %s.",
@@ -273,9 +273,9 @@ class TagsContext implements \Behat\Behat\Context\Context {
 			);
 		}
 
-		foreach($table->getRowsHash() as $rowDisplayName => $row) {
-			foreach($tags as $key => $tag) {
-				if(
+		foreach ($table->getRowsHash() as $rowDisplayName => $row) {
+			foreach ($tags as $key => $tag) {
+				if (
 					$tag['display-name'] === $rowDisplayName &&
 					$tag['user-visible'] === $row[0] &&
 					$tag['user-assignable'] === $row[1]
@@ -284,7 +284,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 				}
 			}
 		}
-		if(count($tags) !== 0) {
+		if (count($tags) !== 0) {
 			throw new \Exception('Not expected response');
 		}
 	}
@@ -331,9 +331,9 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @param string $user
 	 * @throws \Exception
 	 */
-	public function tagsShouldExistFor($count, $user)  {
-		if((int)$count !== count($this->requestTagsForUser($user))) {
-			throw new \Exception("Expected $count tags, got ".count($this->requestTagsForUser($user)));
+	public function tagsShouldExistFor($count, $user) {
+		if ((int)$count !== count($this->requestTagsForUser($user))) {
+			throw new \Exception("Expected $count tags, got " . count($this->requestTagsForUser($user)));
 		}
 	}
 
@@ -369,8 +369,8 @@ class TagsContext implements \Behat\Behat\Context\Context {
 			if ($tag['display-name'] === $tagName
 				&& $tag['user-visible'] === $userVisible
 				&& $tag['user-assignable'] === $userAssignable) {
-					$foundTag = $tag;
-					break;
+				$foundTag = $tag;
+				break;
 			}
 		}
 		return $foundTag;
@@ -383,8 +383,8 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	private function findTagIdByName($name) {
 		$tags = $this->requestTagsForUser('admin');
 		$tagId = 0;
-		foreach($tags as $id => $tag) {
-			if($tag['display-name'] === $name) {
+		foreach ($tags as $id => $tag) {
+			if ($tag['display-name'] === $name) {
 				$tagId = $id;
 				break;
 			}
@@ -401,12 +401,12 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function editsTheTagWithNameAndSetsItsNameTo($user, $oldName, $newName) {
 		$tagId = $this->findTagIdByName($oldName);
-		if($tagId === 0) {
+		if ($tagId === 0) {
 			throw new \Exception('Could not find tag to rename');
 		}
 
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPPATCH',
 				$this->baseUrl . '/remote.php/dav/systemtags/' . $tagId,
 				[
@@ -424,7 +424,6 @@ class TagsContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -439,12 +438,12 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 */
 	public function editsTheTagWithNameAndSetsItsGroupsTo($user, $oldName, $groups) {
 		$tagId = $this->findTagIdByName($oldName);
-		if($tagId === 0) {
+		if ($tagId === 0) {
 			throw new \Exception('Could not find tag to rename');
 		}
 
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPPATCH',
 				$this->baseUrl . '/remote.php/dav/systemtags/' . $tagId,
 				[
@@ -462,7 +461,6 @@ class TagsContext implements \Behat\Behat\Context\Context {
 					],
 				]
 			);
-			$this->response = $this->client->send($request);
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
@@ -473,7 +471,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @param string $user
 	 * @param string $name
 	 */
-	public function deletesTheTagWithName($user, $name)  {
+	public function deletesTheTagWithName($user, $name) {
 		$tagId = $this->findTagIdByName($name);
 		try {
 			$this->response = $this->client->delete(
@@ -499,8 +497,8 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @return int
 	 */
 	private function getFileIdForPath($path, $user) {
-		$url = $this->baseUrl.'/remote.php/webdav/'.$path;
-		$credentials = base64_encode($user .':'.$this->getPasswordForUser($user));
+		$url = $this->baseUrl . '/remote.php/webdav/' . $path;
+		$credentials = base64_encode($user . ':' . $this->getPasswordForUser($user));
 		$context = stream_context_create(array(
 			'http' => array(
 				'method' => 'PROPFIND',
@@ -531,7 +529,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 
 		try {
 			$this->response = $this->client->put(
-				$this->baseUrl.'/remote.php/dav/systemtags-relations/files/'.$fileId.'/'.$tagId,
+				$this->baseUrl . '/remote.php/dav/systemtags-relations/files/' . $fileId . '/' . $tagId,
 				[
 					'auth' => [
 						$taggingUser,
@@ -551,17 +549,17 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	 * @param TableNode $table
 	 * @throws \Exception
 	 */
-	public function sharedByHasTheFollowingTags($fileName, $sharedOrOwnedBy, $sharingUser, TableNode $table)  {
+	public function sharedByHasTheFollowingTags($fileName, $sharedOrOwnedBy, $sharingUser, TableNode $table) {
 		$loadedExpectedTags = $table->getTable();
 		$expectedTags = [];
-		foreach($loadedExpectedTags as $expected) {
+		foreach ($loadedExpectedTags as $expected) {
 			$expectedTags[] = $expected[0];
 		}
 
 		// Get the real tags
-		$request = $this->client->createRequest(
+		$response = $this->client->request(
 			'PROPFIND',
-			$this->baseUrl.'/remote.php/dav/systemtags-relations/files/'.$this->getFileIdForPath($fileName, $sharingUser),
+			$this->baseUrl . '/remote.php/dav/systemtags-relations/files/' . $this->getFileIdForPath($fileName, $sharingUser),
 			[
 				'auth' => [
 					$sharingUser,
@@ -577,19 +575,18 @@ class TagsContext implements \Behat\Behat\Context\Context {
   </d:prop>
 </d:propfind>',
 			]
-		);
-		$response = $this->client->send($request)->getBody()->getContents();
+		)->getBody()->getContents();
 		preg_match_all('/\<oc:display-name\>(.*?)\<\/oc:display-name\>/', $response, $realTags);
 
-		foreach($expectedTags as $key => $row) {
-			foreach($realTags as $tag) {
-				if($tag[0] === $row) {
+		foreach ($expectedTags as $key => $row) {
+			foreach ($realTags as $tag) {
+				if ($tag[0] === $row) {
 					unset($expectedTags[$key]);
 				}
 			}
 		}
 
-		if(count($expectedTags) !== 0) {
+		if (count($expectedTags) !== 0) {
 			throw new \Exception('Not all tags found.');
 		}
 	}
@@ -605,13 +602,13 @@ class TagsContext implements \Behat\Behat\Context\Context {
 	public function sharedByHasTheFollowingTagsFor($fileName, $sharingUser, $user, TableNode $table) {
 		$loadedExpectedTags = $table->getTable();
 		$expectedTags = [];
-		foreach($loadedExpectedTags as $expected) {
+		foreach ($loadedExpectedTags as $expected) {
 			$expectedTags[] = $expected[0];
 		}
 
 		// Get the real tags
 		try {
-			$request = $this->client->createRequest(
+			$this->response = $this->client->request(
 				'PROPFIND',
 				$this->baseUrl . '/remote.php/dav/systemtags-relations/files/' . $this->getFileIdForPath($fileName, $sharingUser),
 				[
@@ -630,25 +627,24 @@ class TagsContext implements \Behat\Behat\Context\Context {
 </d:propfind>',
 				]
 			);
-			$this->response = $this->client->send($request)->getBody()->getContents();
 		} catch (\GuzzleHttp\Exception\ClientException $e) {
 			$this->response = $e->getResponse();
 		}
-		preg_match_all('/\<oc:display-name\>(.*?)\<\/oc:display-name\>/', $this->response, $realTags);
+		preg_match_all('/\<oc:display-name\>(.*?)\<\/oc:display-name\>/', $this->response->getBody()->getContents(), $realTags);
 		$realTags = array_filter($realTags);
 		$expectedTags = array_filter($expectedTags);
 
-		foreach($expectedTags as $key => $row) {
-			foreach($realTags as $tag) {
-				foreach($tag as $index => $foo) {
-					if($tag[$index] === $row) {
+		foreach ($expectedTags as $key => $row) {
+			foreach ($realTags as $tag) {
+				foreach ($tag as $index => $foo) {
+					if ($tag[$index] === $row) {
 						unset($expectedTags[$key]);
 					}
 				}
 			}
 		}
 
-		if(count($expectedTags) !== 0) {
+		if (count($expectedTags) !== 0) {
 			throw new \Exception('Not all tags found.');
 		}
 	}
@@ -666,7 +662,7 @@ class TagsContext implements \Behat\Behat\Context\Context {
 
 		try {
 			$this->response = $this->client->delete(
-				$this->baseUrl.'/remote.php/dav/systemtags-relations/files/'.$fileId.'/'.$tagId,
+				$this->baseUrl . '/remote.php/dav/systemtags-relations/files/' . $fileId . '/' . $tagId,
 				[
 					'auth' => [
 						$user,
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index 1354c0b19784b9c7015ed8c788db2b4e1adfbb20..12f4a2cc3b3c62be9e06f22dde7210d2fb38ddea 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -28,6 +28,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 use GuzzleHttp\Client as GClient;
 use GuzzleHttp\Message\ResponseInterface;
 use Sabre\DAV\Client as SClient;
@@ -39,9 +40,9 @@ require __DIR__ . '/../../vendor/autoload.php';
 trait WebDav {
 	use Sharing;
 
-	/** @var string*/
+	/** @var string */
 	private $davPath = "remote.php/webdav";
-	/** @var boolean*/
+	/** @var boolean */
 	private $usingOldDavPath = true;
 	/** @var ResponseInterface */
 	private $response;
@@ -73,40 +74,31 @@ trait WebDav {
 		$this->usingOldDavPath = false;
 	}
 
-	public function getDavFilesPath($user){
-		if ($this->usingOldDavPath === true){
+	public function getDavFilesPath($user) {
+		if ($this->usingOldDavPath === true) {
 			return $this->davPath;
 		} else {
 			return $this->davPath . '/files/' . $user;
 		}
 	}
 
-	public function makeDavRequest($user, $method, $path, $headers, $body = null, $type = "files"){
-		if ( $type === "files" ){
+	public function makeDavRequest($user, $method, $path, $headers, $body = null, $type = "files") {
+		if ($type === "files") {
 			$fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user) . "$path";
-		} else if ( $type === "uploads" ){
+		} else if ($type === "uploads") {
 			$fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath . "$path";
-		} 
+		}
 		$client = new GClient();
-		$options = [];
+		$options = [
+			'headers' => $headers,
+			'body' => $body
+		];
 		if ($user === 'admin') {
 			$options['auth'] = $this->adminUser;
 		} else {
 			$options['auth'] = [$user, $this->regularUser];
 		}
-		$request = $client->createRequest($method, $fullUrl, $options);
-		if (!is_null($headers)){
-			foreach ($headers as $key => $value) {
-				$request->addHeader($key, $value);
-			}
-		}
-
-		if (!is_null($body)) {
-			$request->setBody($body);
-		}
-
-
-		return $client->send($request);
+		return $client->request($method, $fullUrl, $options);
 	}
 
 	/**
@@ -115,7 +107,7 @@ trait WebDav {
 	 * @param string $fileSource
 	 * @param string $fileDestination
 	 */
-	public function userMovedFile($user, $entry, $fileSource, $fileDestination){
+	public function userMovedFile($user, $entry, $fileSource, $fileDestination) {
 		$fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user);
 		$headers['Destination'] = $fullUrl . $fileDestination;
 		$this->response = $this->makeDavRequest($user, "MOVE", $fileSource, $headers);
@@ -128,7 +120,7 @@ trait WebDav {
 	 * @param string $fileSource
 	 * @param string $fileDestination
 	 */
-	public function userMovesFile($user, $entry, $fileSource, $fileDestination){
+	public function userMovesFile($user, $entry, $fileSource, $fileDestination) {
 		$fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user);
 		$headers['Destination'] = $fullUrl . $fileDestination;
 		try {
@@ -160,7 +152,7 @@ trait WebDav {
 	 * @param string $fileSource
 	 * @param string $range
 	 */
-	public function downloadFileWithRange($fileSource, $range){
+	public function downloadFileWithRange($fileSource, $range) {
 		$headers['Range'] = $range;
 		$this->response = $this->makeDavRequest($this->currentUser, "GET", $fileSource, $headers);
 	}
@@ -169,43 +161,44 @@ trait WebDav {
 	 * @When /^Downloading last public shared file with range "([^"]*)"$/
 	 * @param string $range
 	 */
-	public function downloadPublicFileWithRange($range){
+	public function downloadPublicFileWithRange($range) {
 		$token = $this->lastShareData->data->token;
 		$fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav";
 
 		$client = new GClient();
 		$options = [];
 		$options['auth'] = [$token, ""];
+		$options['headers'] = [
+			'Range' => $range
+		];
 
-		$request = $client->createRequest("GET", $fullUrl, $options);
-		$request->addHeader('Range', $range);
-
-		$this->response = $client->send($request);
+		$this->response = $client->request("GET", $fullUrl, $options);
 	}
 
 	/**
 	 * @When /^Downloading last public shared file inside a folder "([^"]*)" with range "([^"]*)"$/
 	 * @param string $range
 	 */
-	public function downloadPublicFileInsideAFolderWithRange($path, $range){
+	public function downloadPublicFileInsideAFolderWithRange($path, $range) {
 		$token = $this->lastShareData->data->token;
 		$fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav" . "$path";
 
 		$client = new GClient();
-		$options = [];
+		$options = [
+			'headers' => [
+				'Range' => $range
+			]
+		];
 		$options['auth'] = [$token, ""];
 
-		$request = $client->createRequest("GET", $fullUrl, $options);
-		$request->addHeader('Range', $range);
-
-		$this->response = $client->send($request);
+		$this->response = $client->request("GET", $fullUrl, $options);
 	}
 
 	/**
 	 * @Then /^Downloaded content should be "([^"]*)"$/
 	 * @param string $content
 	 */
-	public function downloadedContentShouldBe($content){
+	public function downloadedContentShouldBe($content) {
 		PHPUnit_Framework_Assert::assertEquals($content, (string)$this->response->getBody());
 	}
 
@@ -215,7 +208,7 @@ trait WebDav {
 	 * @param string $range
 	 * @param string $content
 	 */
-	public function downloadedContentWhenDownloadindShouldBe($fileSource, $range, $content){
+	public function downloadedContentWhenDownloadindShouldBe($fileSource, $range, $content) {
 		$this->downloadFileWithRange($fileSource, $range);
 		$this->downloadedContentShouldBe($content);
 	}
@@ -238,11 +231,11 @@ trait WebDav {
 	 * @throws \Exception
 	 */
 	public function theFollowingHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode $table) {
-		foreach($table->getTable() as $header) {
+		foreach ($table->getTable() as $header) {
 			$headerName = $header[0];
 			$expectedHeaderValue = $header[1];
-			$returnedHeader = $this->response->getHeader($headerName);
-			if($returnedHeader !== $expectedHeaderValue) {
+			$returnedHeader = $this->response->getHeader($headerName)[0];
+			if ($returnedHeader !== $expectedHeaderValue) {
 				throw new \Exception(
 					sprintf(
 						"Expected value '%s' for header '%s', got '%s'",
@@ -261,7 +254,7 @@ trait WebDav {
 	 * @throws \Exception
 	 */
 	public function downloadedContentShouldStartWith($start) {
-		if(strpos($this->response->getBody()->getContents(), $start) !== 0) {
+		if (strpos($this->response->getBody()->getContents(), $start) !== 0) {
 			throw new \Exception(
 				sprintf(
 					"Expected '%s', got '%s'",
@@ -345,8 +338,7 @@ trait WebDav {
 	/**
 	 * @Then the response should contain a share-types property with
 	 */
-	public function theResponseShouldContainAShareTypesPropertyWith($table)
-	{
+	public function theResponseShouldContainAShareTypesPropertyWith($table) {
 		$keys = $this->response;
 		if (!array_key_exists('{http://owncloud.org/ns}share-types', $keys)) {
 			throw new \Exception("Cannot find property \"{http://owncloud.org/ns}share-types\"");
@@ -393,7 +385,7 @@ trait WebDav {
 	}
 
 	/*Returns the elements of a propfind, $folderDepth requires 1 to see elements without children*/
-	public function listFolder($user, $path, $folderDepth, $properties = null){
+	public function listFolder($user, $path, $folderDepth, $properties = null) {
 		$client = $this->getSabreClient($user);
 		if (!$properties) {
 			$properties = [
@@ -412,7 +404,7 @@ trait WebDav {
 	 * @param string $properties properties which needs to be included in the report
 	 * @param string $filterRules filter-rules to choose what needs to appear in the report
 	 */
-	public function reportFolder($user, $path, $properties, $filterRules){
+	public function reportFolder($user, $path, $properties, $filterRules) {
 		$client = $this->getSabreClient($user);
 
 		$body = '<?xml version="1.0" encoding="utf-8" ?>
@@ -457,14 +449,14 @@ trait WebDav {
 	 * @param string $user
 	 * @param \Behat\Gherkin\Node\TableNode|null $expectedElements
 	 */
-	public function checkElementList($user, $expectedElements){
+	public function checkElementList($user, $expectedElements) {
 		$elementList = $this->listFolder($user, '/', 3);
 		if ($expectedElements instanceof \Behat\Gherkin\Node\TableNode) {
 			$elementRows = $expectedElements->getRows();
 			$elementsSimplified = $this->simplifyArray($elementRows);
-			foreach($elementsSimplified as $expectedElement) {
+			foreach ($elementsSimplified as $expectedElement) {
 				$webdavPath = "/" . $this->getDavFilesPath($user) . $expectedElement;
-				if (!array_key_exists($webdavPath,$elementList)){
+				if (!array_key_exists($webdavPath, $elementList)) {
 					PHPUnit_Framework_Assert::fail("$webdavPath" . " is not in propfind answer");
 				}
 			}
@@ -477,9 +469,8 @@ trait WebDav {
 	 * @param string $source
 	 * @param string $destination
 	 */
-	public function userUploadsAFileTo($user, $source, $destination)
-	{
-		$file = \GuzzleHttp\Stream\Stream::factory(fopen($source, 'r'));
+	public function userUploadsAFileTo($user, $source, $destination) {
+		$file = \GuzzleHttp\Psr7\stream_for(fopen($source, 'r'));
 		try {
 			$this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
 		} catch (\GuzzleHttp\Exception\ServerException $e) {
@@ -494,7 +485,7 @@ trait WebDav {
 	 * @param string $bytes
 	 * @param string $destination
 	 */
-	public function userAddsAFileTo($user, $bytes, $destination){
+	public function userAddsAFileTo($user, $bytes, $destination) {
 		$filename = "filespecificSize.txt";
 		$this->createFileSpecificSize($filename, $bytes);
 		PHPUnit_Framework_Assert::assertEquals(1, file_exists("work/$filename"));
@@ -507,9 +498,8 @@ trait WebDav {
 	/**
 	 * @When User :user uploads file with content :content to :destination
 	 */
-	public function userUploadsAFileWithContentTo($user, $content, $destination)
-	{
-		$file = \GuzzleHttp\Stream\Stream::factory($content);
+	public function userUploadsAFileWithContentTo($user, $content, $destination) {
+		$file = \GuzzleHttp\Psr7\stream_for($content);
 		try {
 			$this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
 		} catch (\GuzzleHttp\Exception\ServerException $e) {
@@ -524,7 +514,7 @@ trait WebDav {
 	 * @param string $type
 	 * @param string $file
 	 */
-	public function userDeletesFile($user, $type, $file)  {
+	public function userDeletesFile($user, $type, $file) {
 		try {
 			$this->response = $this->makeDavRequest($user, 'DELETE', $file, []);
 		} catch (\GuzzleHttp\Exception\ServerException $e) {
@@ -556,38 +546,34 @@ trait WebDav {
 	 * @param string $data
 	 * @param string $destination
 	 */
-	public function userUploadsChunkFileOfWithToWithChecksum($user, $num, $total, $data, $destination)
-	{
+	public function userUploadsChunkFileOfWithToWithChecksum($user, $num, $total, $data, $destination) {
 		$num -= 1;
-		$data = \GuzzleHttp\Stream\Stream::factory($data);
+		$data = \GuzzleHttp\Psr7\stream_for($data);
 		$file = $destination . '-chunking-42-' . $total . '-' . $num;
-		$this->makeDavRequest($user, 'PUT', $file, ['OC-Chunked' => '1'], $data,  "uploads");
+		$this->makeDavRequest($user, 'PUT', $file, ['OC-Chunked' => '1'], $data, "uploads");
 	}
 
 	/**
 	 * @Given user :user creates a new chunking upload with id :id
 	 */
-	public function userCreatesANewChunkingUploadWithId($user, $id)
-	{
-		$destination = '/uploads/'.$user.'/'.$id;
+	public function userCreatesANewChunkingUploadWithId($user, $id) {
+		$destination = '/uploads/' . $user . '/' . $id;
 		$this->makeDavRequest($user, 'MKCOL', $destination, [], null, "uploads");
 	}
 
 	/**
 	 * @Given user :user uploads new chunk file :num with :data to id :id
 	 */
-	public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id)
-	{
-		$data = \GuzzleHttp\Stream\Stream::factory($data);
-		$destination = '/uploads/'. $user .'/'. $id .'/' . $num;
+	public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id) {
+		$data = \GuzzleHttp\Psr7\stream_for($data);
+		$destination = '/uploads/' . $user . '/' . $id . '/' . $num;
 		$this->makeDavRequest($user, 'PUT', $destination, [], $data, "uploads");
 	}
 
 	/**
 	 * @Given user :user moves new chunk file with id :id to :dest
 	 */
-	public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest)
-	{
+	public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest) {
 		$source = '/uploads/' . $user . '/' . $id . '/.file';
 		$destination = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user) . $dest;
 		$this->makeDavRequest($user, 'MOVE', $source, [
@@ -598,8 +584,7 @@ trait WebDav {
 	/**
 	 * @Then user :user moves new chunk file with id :id to :dest with size :size
 	 */
-	public function userMovesNewChunkFileWithIdToMychunkedfileWithSize($user, $id, $dest, $size)
-	{
+	public function userMovesNewChunkFileWithIdToMychunkedfileWithSize($user, $id, $dest, $size) {
 		$source = '/uploads/' . $user . '/' . $id . '/.file';
 		$destination = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user) . $dest;
 
@@ -608,7 +593,7 @@ trait WebDav {
 				'Destination' => $destination,
 				'OC-Total-Length' => $size
 			], null, "uploads");
-		} catch(\GuzzleHttp\Exception\BadResponseException $ex) {
+		} catch (\GuzzleHttp\Exception\BadResponseException $ex) {
 			$this->response = $ex->getResponse();
 		}
 	}
@@ -638,19 +623,19 @@ trait WebDav {
 	/**
 	 * @When user :user favorites element :path
 	 */
-	public function userFavoritesElement($user, $path){
+	public function userFavoritesElement($user, $path) {
 		$this->response = $this->changeFavStateOfAnElement($user, $path, 1, 0, null);
 	}
 
 	/**
 	 * @When user :user unfavorites element :path
 	 */
-	public function userUnfavoritesElement($user, $path){
+	public function userUnfavoritesElement($user, $path) {
 		$this->response = $this->changeFavStateOfAnElement($user, $path, 0, 0, null);
 	}
 
 	/*Set the elements of a proppatch, $folderDepth requires 1 to see elements without children*/
-	public function changeFavStateOfAnElement($user, $path, $favOrUnfav, $folderDepth, $properties = null){
+	public function changeFavStateOfAnElement($user, $path, $favOrUnfav, $folderDepth, $properties = null) {
 		$fullUrl = substr($this->baseUrl, 0, -4);
 		$settings = [
 			'baseUri' => $fullUrl,
@@ -677,17 +662,17 @@ trait WebDav {
 	/**
 	 * @Given user :user stores etag of element :path
 	 */
-	public function userStoresEtagOfElement($user, $path){
+	public function userStoresEtagOfElement($user, $path) {
 		$propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]);
 		$this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable);
 		$pathETAG[$path] = $this->response['{DAV:}getetag'];
-		$this->storedETAG[$user]= $pathETAG;
+		$this->storedETAG[$user] = $pathETAG;
 	}
 
 	/**
 	 * @Then etag of element :path of user :user has not changed
 	 */
-	public function checkIfETAGHasNotChanged($path, $user){
+	public function checkIfETAGHasNotChanged($path, $user) {
 		$propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]);
 		$this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable);
 		PHPUnit_Framework_Assert::assertEquals($this->response['{DAV:}getetag'], $this->storedETAG[$user][$path]);
@@ -696,7 +681,7 @@ trait WebDav {
 	/**
 	 * @Then etag of element :path of user :user has changed
 	 */
-	public function checkIfETAGHasChanged($path, $user){
+	public function checkIfETAGHasChanged($path, $user) {
 		$propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]);
 		$this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable);
 		PHPUnit_Framework_Assert::assertNotEquals($this->response['{DAV:}getetag'], $this->storedETAG[$user][$path]);
@@ -724,25 +709,25 @@ trait WebDav {
 				throw new \Exception('Duplicate header found: ' . $headerName);
 			}
 		}
-    }
+	}
 
-    /**
+	/**
 	 * @Then /^user "([^"]*)" in folder "([^"]*)" should have favorited the following elements$/
 	 * @param string $user
 	 * @param string $folder
 	 * @param \Behat\Gherkin\Node\TableNode|null $expectedElements
 	 */
-	public function checkFavoritedElements($user, $folder, $expectedElements){
+	public function checkFavoritedElements($user, $folder, $expectedElements) {
 		$elementList = $this->reportFolder($user,
-											$folder,
-											'<oc:favorite/>',
-											'<oc:favorite>1</oc:favorite>');
+			$folder,
+			'<oc:favorite/>',
+			'<oc:favorite>1</oc:favorite>');
 		if ($expectedElements instanceof \Behat\Gherkin\Node\TableNode) {
 			$elementRows = $expectedElements->getRows();
 			$elementsSimplified = $this->simplifyArray($elementRows);
-			foreach($elementsSimplified as $expectedElement) {
+			foreach ($elementsSimplified as $expectedElement) {
 				$webdavPath = "/" . $this->getDavFilesPath($user) . $expectedElement;
-				if (!array_key_exists($webdavPath,$elementList)){
+				if (!array_key_exists($webdavPath, $elementList)) {
 					PHPUnit_Framework_Assert::fail("$webdavPath" . " is not in report answer");
 				}
 			}
@@ -754,12 +739,12 @@ trait WebDav {
 	 * @param string $user
 	 * @param string $folder
 	 */
-	public function userDeletesEverythingInFolder($user, $folder)  {
+	public function userDeletesEverythingInFolder($user, $folder) {
 		$elementList = $this->listFolder($user, $folder, 1);
 		$elementListKeys = array_keys($elementList);
 		array_shift($elementListKeys);
-		$davPrefix =  "/" . $this->getDavFilesPath($user);
-		foreach($elementListKeys as $element) {
+		$davPrefix = "/" . $this->getDavFilesPath($user);
+		foreach ($elementListKeys as $element) {
 			if (substr($element, 0, strlen($davPrefix)) == $davPrefix) {
 				$element = substr($element, strlen($davPrefix));
 			}
@@ -776,7 +761,7 @@ trait WebDav {
 	private function getFileIdForPath($user, $path) {
 		$propertiesTable = new \Behat\Gherkin\Node\TableNode([["{http://owncloud.org/ns}fileid"]]);
 		$this->asGetsPropertiesOfFolderWith($user, 'file', $path, $propertiesTable);
-		return (int) $this->response['{http://owncloud.org/ns}fileid'];
+		return (int)$this->response['{http://owncloud.org/ns}fileid'];
 	}
 
 	/**
diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php
index f9c6175308cadafe1303aeb1b3b24ff51e2aec4b..1496fda514076ef6f2eb6a63bb43ac243b17513a 100644
--- a/lib/private/Files/Storage/DAV.php
+++ b/lib/private/Files/Storage/DAV.php
@@ -35,7 +35,7 @@ namespace OC\Files\Storage;
 
 use Exception;
 use GuzzleHttp\Exception\RequestException;
-use GuzzleHttp\Message\ResponseInterface;
+use Psr\Http\Message\ResponseInterface;
 use Icewind\Streams\CallbackWrapper;
 use OC\Files\Filesystem;
 use Icewind\Streams\IteratorDirectory;
@@ -344,7 +344,7 @@ class DAV extends Common {
 							'auth' => [$this->user, $this->password],
 							'stream' => true
 						]);
-				} catch (RequestException $e) {
+				} catch (\GuzzleHttp\Exception\ClientException $e) {
 					if ($e->getResponse() instanceof ResponseInterface
 						&& $e->getResponse()->getStatusCode() === 404) {
 						return false;
diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php
index 4e6843d7b9fa0643181833e96d625b3fc8332095..0387fcabfafb8a982de8c819ec4edfb6e228df04 100644
--- a/lib/private/Http/Client/Client.php
+++ b/lib/private/Http/Client/Client.php
@@ -25,10 +25,13 @@ declare(strict_types=1);
 namespace OC\Http\Client;
 
 use GuzzleHttp\Client as GuzzleClient;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Middleware;
 use OCP\Http\Client\IClient;
 use OCP\Http\Client\IResponse;
 use OCP\ICertificateManager;
 use OCP\IConfig;
+use Psr\Http\Message\RequestInterface;
 
 /**
  * Class Client
@@ -43,17 +46,23 @@ class Client implements IClient {
 	/** @var ICertificateManager */
 	private $certificateManager;
 	private $configured = false;
+	/** @var HandlerStack */
+	private $stack;
 
 	/**
 	 * @param IConfig $config
 	 * @param ICertificateManager $certificateManager
 	 * @param GuzzleClient $client
 	 */
-	public function __construct(IConfig $config,
-								ICertificateManager $certificateManager,
-								GuzzleClient $client) {
+	public function __construct(
+		IConfig $config,
+		ICertificateManager $certificateManager,
+		GuzzleClient $client,
+		HandlerStack $stack
+	) {
 		$this->config = $config;
 		$this->client = $client;
+		$this->stack = $stack;
 		$this->certificateManager = $certificateManager;
 	}
 
@@ -65,25 +74,37 @@ class Client implements IClient {
 			return;
 		}
 		$this->configured = true;
-		// Either use user bundle or the system bundle if nothing is specified
+
+		$this->stack->push(Middleware::mapRequest(function (RequestInterface $request) {
+			return $request
+				->withHeader('User-Agent', 'Nextcloud Server Crawler');
+		}));
+	}
+
+	private function getRequestOptions() {
+		$options = [
+			'verify' => $this->getCertBundle(),
+		];
+		$proxyUri = $this->getProxyUri();
+		if ($proxyUri !== '') {
+			$options['proxy'] = $proxyUri;
+		}
+		return $options;
+	}
+
+	private function getCertBundle() {
 		if ($this->certificateManager->listCertificates() !== []) {
-			$this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath());
+			return $this->certificateManager->getAbsoluteBundlePath();
 		} else {
 			// If the instance is not yet setup we need to use the static path as
 			// $this->certificateManager->getAbsoluteBundlePath() tries to instantiiate
 			// a view
 			if ($this->config->getSystemValue('installed', false)) {
-				$this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath(null));
+				return $this->certificateManager->getAbsoluteBundlePath(null);
 			} else {
-				$this->client->setDefaultOption('verify', \OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
+				return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
 			}
 		}
-
-		$this->client->setDefaultOption('headers/User-Agent', 'Nextcloud Server Crawler');
-		$proxyUri = $this->getProxyUri();
-		if ($proxyUri !== '') {
-			$this->client->setDefaultOption('proxy', $proxyUri);
-		}
 	}
 
 	/**
@@ -137,7 +158,7 @@ class Client implements IClient {
 	 */
 	public function get(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->get($uri, $options);
+		$response = $this->client->request('get', $uri, array_merge($options, $this->getRequestOptions()));
 		$isStream = isset($options['stream']) && $options['stream'];
 		return new Response($response, $isStream);
 	}
@@ -168,7 +189,7 @@ class Client implements IClient {
 	 */
 	public function head(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->head($uri, $options);
+		$response = $this->client->request('head', $uri, array_merge($options, $this->getRequestOptions()));
 		return new Response($response);
 	}
 
@@ -203,7 +224,11 @@ class Client implements IClient {
 	 */
 	public function post(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->post($uri, $options);
+		if (isset($options['body']) && is_array($options['body'])) {
+			$options['form_params'] = $options['body'];
+			unset($options['body']);
+		}
+		$response = $this->client->request('post', $uri, array_merge($options, $this->getRequestOptions()));
 		return new Response($response);
 	}
 
@@ -238,7 +263,7 @@ class Client implements IClient {
 	 */
 	public function put(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->put($uri, $options);
+		$response = $this->client->request('put', $uri, array_merge($options, $this->getRequestOptions()));
 		return new Response($response);
 	}
 
@@ -273,7 +298,7 @@ class Client implements IClient {
 	 */
 	public function delete(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->delete($uri, $options);
+		$response = $this->client->request('delete', $uri, array_merge($options, $this->getRequestOptions()));
 		return new Response($response);
 	}
 
@@ -309,7 +334,7 @@ class Client implements IClient {
 	 */
 	public function options(string $uri, array $options = []): IResponse {
 		$this->setDefaultOptions();
-		$response = $this->client->options($uri, $options);
+		$response = $this->client->request('options', $uri, array_merge($options, $this->getRequestOptions()));
 		return new Response($response);
 	}
 }
diff --git a/lib/private/Http/Client/ClientService.php b/lib/private/Http/Client/ClientService.php
index 1df54010a2d32a6d6243dc58e29e8e9b4f68f95c..fa8544f07a5c1fcff75c56d2d0739485aa537c80 100644
--- a/lib/private/Http/Client/ClientService.php
+++ b/lib/private/Http/Client/ClientService.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
 namespace OC\Http\Client;
 
 use GuzzleHttp\Client as GuzzleClient;
+use GuzzleHttp\HandlerStack;
 use OCP\Http\Client\IClient;
 use OCP\Http\Client\IClientService;
 use OCP\ICertificateManager;
@@ -54,6 +55,6 @@ class ClientService implements IClientService {
 	 * @return Client
 	 */
 	public function newClient(): IClient {
-		return new Client($this->config, $this->certificateManager, new GuzzleClient());
+		return new Client($this->config, $this->certificateManager, new GuzzleClient(), HandlerStack::create());
 	}
 }
diff --git a/lib/private/Http/Client/Response.php b/lib/private/Http/Client/Response.php
index 0ce6cc98e0de23775ba5e79acc41b7115b6ab1ed..73c14c2926d42af8b1817c3646f660a93af2a6db 100644
--- a/lib/private/Http/Client/Response.php
+++ b/lib/private/Http/Client/Response.php
@@ -25,7 +25,7 @@ declare(strict_types=1);
 namespace OC\Http\Client;
 
 use OCP\Http\Client\IResponse;
-use GuzzleHttp\Message\ResponseInterface as GuzzleResponse;
+use Psr\Http\Message\ResponseInterface;
 
 /**
  * Class Response
@@ -33,7 +33,7 @@ use GuzzleHttp\Message\ResponseInterface as GuzzleResponse;
  * @package OC\Http
  */
 class Response implements IResponse {
-	/** @var GuzzleResponse */
+	/** @var ResponseInterface */
 	private $response;
 
 	/**
@@ -42,10 +42,10 @@ class Response implements IResponse {
 	private $stream;
 
 	/**
-	 * @param GuzzleResponse $response
+	 * @param ResponseInterface $response
 	 * @param bool $stream
 	 */
-	public function __construct(GuzzleResponse $response, $stream = false) {
+	public function __construct(ResponseInterface $response, $stream = false) {
 		$this->response = $response;
 		$this->stream = $stream;
 	}
@@ -71,7 +71,7 @@ class Response implements IResponse {
 	 * @return string
 	 */
 	public function getHeader(string $key): string {
-		return $this->response->getHeader($key);
+		return $this->response->getHeader($key)[0];
 	}
 
 	/**
diff --git a/tests/Settings/Controller/CheckSetupControllerTest.php b/tests/Settings/Controller/CheckSetupControllerTest.php
index 3f47819bcbda61e3dc18d7a6a7e30573c61e9303..a0ee7f6cae6b23e9a72d5b22a945555703a8c1fc 100644
--- a/tests/Settings/Controller/CheckSetupControllerTest.php
+++ b/tests/Settings/Controller/CheckSetupControllerTest.php
@@ -21,6 +21,7 @@
 
 namespace Tests\Settings\Controller;
 
+use Guzzle\Http\Message\Response;
 use OC\Settings\Controller\CheckSetupController;
 use OCP\AppFramework\Http;
 use OCP\AppFramework\Http\DataDisplayResponse;
@@ -460,7 +461,7 @@ class CheckSetupControllerTest extends TestCase {
 			->disableOriginalConstructor()->getMock();
 		$exception = $this->getMockBuilder('\GuzzleHttp\Exception\ClientException')
 			->disableOriginalConstructor()->getMock();
-		$response = $this->getMockBuilder('\GuzzleHttp\Message\ResponseInterface')
+		$response = $this->getMockBuilder(Response::class)
 			->disableOriginalConstructor()->getMock();
 		$response->expects($this->once())
 			->method('getStatusCode')
@@ -494,7 +495,7 @@ class CheckSetupControllerTest extends TestCase {
 			->disableOriginalConstructor()->getMock();
 		$exception = $this->getMockBuilder('\GuzzleHttp\Exception\ClientException')
 			->disableOriginalConstructor()->getMock();
-		$response = $this->getMockBuilder('\GuzzleHttp\Message\ResponseInterface')
+		$response = $this->getMockBuilder(Response::class)
 			->disableOriginalConstructor()->getMock();
 		$response->expects($this->once())
 			->method('getStatusCode')
diff --git a/tests/lib/Http/Client/ClientServiceTest.php b/tests/lib/Http/Client/ClientServiceTest.php
index 48330dc33c0b1b2543d157e43481b5a17360f730..1bfaf0503555d62b8618235b222021256ee29e98 100644
--- a/tests/lib/Http/Client/ClientServiceTest.php
+++ b/tests/lib/Http/Client/ClientServiceTest.php
@@ -9,6 +9,7 @@
 namespace Test\Http\Client;
 
 use GuzzleHttp\Client as GuzzleClient;
+use GuzzleHttp\HandlerStack;
 use OC\Http\Client\Client;
 use OC\Http\Client\ClientService;
 use OCP\ICertificateManager;
@@ -22,7 +23,7 @@ class ClientServiceTest extends \Test\TestCase {
 		$config = $this->createMock(IConfig::class);
 		$certificateManager = $this->createMock(ICertificateManager::class);
 
-		$expected = new Client($config, $certificateManager, new GuzzleClient());
+		$expected = new Client($config, $certificateManager, new GuzzleClient(), HandlerStack::create());
 		$clientService = new ClientService($config, $certificateManager);
 		$this->assertEquals($expected, $clientService->newClient());
 	}
diff --git a/tests/lib/Http/Client/ClientTest.php b/tests/lib/Http/Client/ClientTest.php
index 1b0a51b73959cab13d1fd106ba00196bcb49ec40..ec4ca6ec90c3ad6da8f24efd87b35c7f847c7a59 100644
--- a/tests/lib/Http/Client/ClientTest.php
+++ b/tests/lib/Http/Client/ClientTest.php
@@ -8,7 +8,8 @@
 
 namespace Test\Http\Client;
 
-use GuzzleHttp\Message\Response;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Psr7\Response;
 use OC\Http\Client\Client;
 use OC\Security\CertificateManager;
 use OCP\ICertificateManager;
@@ -37,7 +38,8 @@ class ClientTest extends \Test\TestCase {
 		$this->client = new Client(
 			$this->config,
 			$this->certificateManager,
-			$this->guzzleClient
+			$this->guzzleClient,
+			HandlerStack::create()
 		);
 	}
 
@@ -84,37 +86,37 @@ class ClientTest extends \Test\TestCase {
 	}
 
 	public function testGet() {
-		$this->guzzleClient->method('get')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->get('http://localhost/', [])->getStatusCode());
 	}
 
 	public function testPost() {
-		$this->guzzleClient->method('post')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->post('http://localhost/', [])->getStatusCode());
 	}
 
 	public function testPut() {
-		$this->guzzleClient->method('put')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->put('http://localhost/', [])->getStatusCode());
 	}
 
 	public function testDelete() {
-		$this->guzzleClient->method('delete')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->delete('http://localhost/', [])->getStatusCode());
 	}
 
 	public function testOptions() {
-		$this->guzzleClient->method('options')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->options('http://localhost/', [])->getStatusCode());
 	}
 
 	public function testHead() {
-		$this->guzzleClient->method('head')
+		$this->guzzleClient->method('request')
 			->willReturn(new Response(1337));
 		$this->assertEquals(1337, $this->client->head('http://localhost/', [])->getStatusCode());
 	}
@@ -129,16 +131,10 @@ class ClientTest extends \Test\TestCase {
 			->expects($this->once())
 			->method('listCertificates')
 			->willReturn([]);
-		$this->guzzleClient
-			->expects($this->at(0))
-			->method('setDefaultOption')
-			->with('verify', \OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
-		$this->guzzleClient
-			->expects($this->at(1))
-			->method('setDefaultOption')
-			->with('headers/User-Agent', 'Nextcloud Server Crawler');
 
-		self::invokePrivate($this->client, 'setDefaultOptions');
+		$this->assertEquals([
+			'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt'
+		], self::invokePrivate($this->client, 'getRequestOptions'));
 	}
 
 	public function testSetDefaultOptionsWithProxy() {
@@ -157,19 +153,10 @@ class ClientTest extends \Test\TestCase {
 			->method('getAbsoluteBundlePath')
 			->with(null)
 			->willReturn('/my/path.crt');
-		$this->guzzleClient
-			->expects($this->at(0))
-			->method('setDefaultOption')
-			->with('verify', '/my/path.crt');
-		$this->guzzleClient
-			->expects($this->at(1))
-			->method('setDefaultOption')
-			->with('headers/User-Agent', 'Nextcloud Server Crawler');
-		$this->guzzleClient
-			->expects($this->at(2))
-			->method('setDefaultOption')
-			->with('proxy', 'foo');
-
-		self::invokePrivate($this->client, 'setDefaultOptions');
+
+		$this->assertEquals([
+			'verify' => '/my/path.crt',
+			'proxy' => 'foo'
+		], self::invokePrivate($this->client, 'getRequestOptions'));
 	}
 }
diff --git a/tests/lib/Http/Client/ResponseTest.php b/tests/lib/Http/Client/ResponseTest.php
index 2e5a47b7f4a1b9a284e042a3f8b21ef39cebb3f6..d50f9a717d5da1e1479dd645a0a2b539808d4a2e 100644
--- a/tests/lib/Http/Client/ResponseTest.php
+++ b/tests/lib/Http/Client/ResponseTest.php
@@ -8,42 +8,42 @@
 
 namespace Test\Http\Client;
 
-use GuzzleHttp\Stream\Stream;
-use GuzzleHttp\Message\Response as GuzzleResponse;
+use function GuzzleHttp\Psr7\stream_for;
+use GuzzleHttp\Psr7\Response as GuzzleResponse;
 use OC\Http\Client\Response;
 
 /**
  * Class ResponseTest
  */
 class ResponseTest extends \Test\TestCase {
-	/** @var Response */
-	private $response;
 	/** @var GuzzleResponse */
 	private $guzzleResponse;
 
 	public function setUp() {
 		parent::setUp();
 		$this->guzzleResponse = new GuzzleResponse(1337);
-		$this->response = new Response($this->guzzleResponse);
 	}
 
 	public function testGetBody() {
-		$this->guzzleResponse->setBody(Stream::factory('MyResponse'));
-		$this->assertSame('MyResponse', $this->response->getBody());
+		$response = new Response($this->guzzleResponse->withBody(stream_for('MyResponse')));
+		$this->assertSame('MyResponse', $response->getBody());
 	}
 
 	public function testGetStatusCode() {
-		$this->assertSame(1337, $this->response->getStatusCode());
+		$response = new Response($this->guzzleResponse);
+		$this->assertSame(1337, $response->getStatusCode());
 	}
 
 	public function testGetHeader() {
-		$this->guzzleResponse->setHeader('bar', 'foo');
-		$this->assertSame('foo', $this->response->getHeader('bar'));
+		$response = new Response($this->guzzleResponse->withHeader('bar', 'foo'));
+		$this->assertSame('foo', $response->getHeader('bar'));
 	}
 
 	public function testGetHeaders() {
-		$this->guzzleResponse->setHeader('bar', 'foo');
-		$this->guzzleResponse->setHeader('x-awesome', 'yes');
+		$response = new Response($this->guzzleResponse
+			->withHeader('bar', 'foo')
+			->withHeader('x-awesome', 'yes')
+		);
 
 		$expected = [
 			'bar' => [
@@ -53,7 +53,7 @@ class ResponseTest extends \Test\TestCase {
 				0 => 'yes',
 			],
 		];
-		$this->assertSame($expected, $this->response->getHeaders());
-		$this->assertSame('yes', $this->response->getHeader('x-awesome'));
+		$this->assertSame($expected, $response->getHeaders());
+		$this->assertSame('yes', $response->getHeader('x-awesome'));
 	}
 }