diff --git a/build/integration/composer.json b/build/integration/composer.json
index 98b2f294c7ae8a223dd2ad6fa5accfc8aab81d0d..2f0f8a815cec0fb11946f5e6c51857db9d3b3c3b 100644
--- a/build/integration/composer.json
+++ b/build/integration/composer.json
@@ -1,7 +1,8 @@
 {
   "require-dev": {
     "phpunit/phpunit": "~4.6",
+    "behat/behat": "^3.0",
     "guzzlehttp/guzzle": "~5.0",
-    "behat/behat": "2.4.*@stable"
+    "jarnaiz/behat-junit-formatter": "^1.3"
   }
 }
diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml
index 8b6699cb0860eaf3d4e2998a306abfc93a3e4bc9..c9d6754a0fa8196876333c3cc12687057fc83862 100644
--- a/build/integration/config/behat.yml
+++ b/build/integration/config/behat.yml
@@ -1,18 +1,19 @@
 default:
-    paths:
-        features: ../features
-        bootstrap: %behat.paths.features%/bootstrap
+  autoload:
+    '': %paths.base%/../features/bootstrap
+  suites:
+    default:
+      paths:
+        - %paths.base%/../features
+      contexts:
+        - FeatureContext:
+            baseUrl:  http://localhost:8080/ocs/
+            admin:
+              - admin
+              - admin
+            regular_user_password: 123456
 
-    context:
-      parameters:
-        baseUrl:  http://localhost:8080/ocs/
-        admin:
-          - admin
-          - admin
-        regular_user_password: 123456
-
-ci:
-    formatter:
-        name:       pretty,junit
-        parameters:
-          output_path: null,./output
+  extensions:
+      jarnaiz\JUnitFormatter\JUnitFormatterExtension:
+          filename: report.xml
+          outputDir: %paths.base%/../output/
diff --git a/build/integration/features/bootstrap/FeatureContext.php b/build/integration/features/bootstrap/FeatureContext.php
index 70e73b66a71f0c47496324f90012303fa7f2b7cc..8633727ee04064b0ca36653ed0c4ff4d5cec65af 100644
--- a/build/integration/features/bootstrap/FeatureContext.php
+++ b/build/integration/features/bootstrap/FeatureContext.php
@@ -1,6 +1,7 @@
 <?php
 
-use Behat\Behat\Context\BehatContext;
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\SnippetAcceptingContext;
 use GuzzleHttp\Client;
 use GuzzleHttp\Message\ResponseInterface;
 
@@ -9,7 +10,7 @@ require __DIR__ . '/../../vendor/autoload.php';
 /**
  * Features context.
  */
-class FeatureContext extends BehatContext {
+class FeatureContext implements Context, SnippetAcceptingContext {
 
 	/** @var string */
 	private $baseUrl = '';
@@ -23,18 +24,18 @@ class FeatureContext extends BehatContext {
 	/** @var int */
 	private $apiVersion = 1;
 
-	/**
-	 * Initializes context.
-	 * Every scenario gets it's own context object.
-	 *
-	 * @param array $parameters context parameters (set them up through behat.yml)
-	 */
-	public function __construct(array $parameters) {
+	/** @var SimpleXMLElement */
+	private $lastShareData = null;
+
+	/** @var array */
+	private $createdUsers = [];
+
+	public function __construct($baseUrl, $admin, $regular_user_password) {
 
 		// Initialize your context here
-		$this->baseUrl = $parameters['baseUrl'];
-		$this->adminUser = $parameters['admin'];
-		$this->regularUser = $parameters['regular_user_password'];
+		$this->baseUrl = $baseUrl;
+		$this->adminUser = $admin;
+		$this->regularUser = $regular_user_password;
 
 		// in case of ci deployment we take the server url from the environment
 		$testServerUrl = getenv('TEST_SERVER_URL');
@@ -197,16 +198,27 @@ class FeatureContext extends BehatContext {
 	/**
 	 * @Given /^user "([^"]*)" exists$/
 	 */
-	public function userExists($user) {
+	public function assureUserExists($user) {
+		try {
+			$this->userExists($user);			
+		} catch (\GuzzleHttp\Exception\ClientException $ex) {
+			$previous_user = $this->currentUser;
+			$this->currentUser = "admin";
+			$this->creatingTheUser($user);
+			$this->currentUser = $previous_user;
+		}
+		$this->userExists($user);
+		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+
+	}
+
+	public function userExists($user){
 		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
 		$client = new Client();
 		$options = [];
-		if ($this->currentUser === 'admin') {
-			$options['auth'] = $this->adminUser;
-		}
+		$options['auth'] = $this->adminUser;
 
 		$this->response = $client->get($fullUrl, $options);
-		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
 	/**
@@ -284,14 +296,23 @@ class FeatureContext extends BehatContext {
 		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
-
 	/**
 	 * @Given /^user "([^"]*)" does not exist$/
 	 */
 	public function userDoesNotExist($user) {
 		try {
 			$this->userExists($user);
-			PHPUnit_Framework_Assert::fail('The user "' . $user . '" exists');
+		} catch (\GuzzleHttp\Exception\ClientException $ex) {
+			$this->response = $ex->getResponse();
+			PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+			return;
+		}
+		$previous_user = $this->currentUser;
+		$this->currentUser = "admin";
+		$this->deletingTheUser($user);
+		$this->currentUser = $previous_user;
+		try {
+			$this->userExists($user);
 		} catch (\GuzzleHttp\Exception\ClientException $ex) {
 			$this->response = $ex->getResponse();
 			PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
@@ -332,56 +353,140 @@ class FeatureContext extends BehatContext {
 		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
-	/**
-	 * @When /^creating the user "([^"]*)r"$/
-	 */
+	public function createUser($user) {
+		$this->creatingTheUser($user);
+		$this->userExists($user);
+	}
+
+	public function deleteUser($user) {
+		$this->deletingTheUser($user);
+		$this->userDoesNotExist($user);
+	}
+
+	public function createGroup($group) {
+		$this->creatingTheGroup($group);
+		$this->groupExists($group);
+	}
+
+	public function deleteGroup($group) {
+		$this->deletingTheGroup($group);
+		$this->groupDoesNotExist($group);
+	}
+
 	public function creatingTheUser($user) {
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
 		$client = new Client();
 		$options = [];
 		if ($this->currentUser === 'admin') {
 			$options['auth'] = $this->adminUser;
 		}
 
-		$this->response = $client->post($fullUrl, [
-			'form_params' => [
-				'userid' => $user,
-				'password' => '123456'
-			]
-		]);
+		$options['body'] = [
+							'userid' => $user,
+							'password' => '123456'
+							];
 
+		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+		$this->createdUsers[$user] = $user;
 	}
 
 	/**
-	 * @When /^creating the group "([^"]*)r"$/
+	 * @When /^creating the group "([^"]*)"$/
 	 */
 	public function creatingTheGroup($group) {
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/addgroup";
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups";
 		$client = new Client();
 		$options = [];
 		if ($this->currentUser === 'admin') {
 			$options['auth'] = $this->adminUser;
 		}
 
-		$this->response = $client->post($fullUrl, [
-			'form_params' => [
-				'groupid' => $user
-			]
-		]);
+		$options['body'] = [
+							'groupid' => $group,
+							];
+
+		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
 	}
 
 	/**
-	 * @Given /^group "([^"]*)" exists$/
+	 * @When /^Deleting the user "([^"]*)"$/
 	 */
-	public function groupExists($group) {
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
+	public function deletingTheUser($user) {
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
 		$client = new Client();
 		$options = [];
 		if ($this->currentUser === 'admin') {
 			$options['auth'] = $this->adminUser;
 		}
 
+		$this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+	}
+
+	/**
+	 * @When /^Deleting the group "([^"]*)"$/
+	 */
+	public function deletingTheGroup($group) {
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group";
+		$client = new Client();
+		$options = [];
+		if ($this->currentUser === 'admin') {
+			$options['auth'] = $this->adminUser;
+		}
+
+		$this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+	}
+
+	/**
+	 * @Given /^Add user "([^"]*)" to the group "([^"]*)"$/
+	 */
+	public function addUserToGroup($user, $group) {
+		$this->userExists($user);
+		$this->groupExists($group);
+		$this->addingUserToGroup($user, $group);
+
+	}
+
+	/**
+	 * @When /^User "([^"]*)" is added to the group "([^"]*)"$/
+	 */
+	public function addingUserToGroup($user, $group) {
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups";
+		$client = new Client();
+		$options = [];
+		if ($this->currentUser === 'admin') {
+			$options['auth'] = $this->adminUser;
+		}
+
+		$options['body'] = [
+							'groupid' => $group,
+							];
+
+		$this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+	}
+
+
+	public function groupExists($group) {
+		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
+		$client = new Client();
+		$options = [];
+		$options['auth'] = $this->adminUser;
+
 		$this->response = $client->get($fullUrl, $options);
+	}
+
+	/**
+	 * @Given /^group "([^"]*)" exists$/
+	 */
+	public function assureGroupExists($group) {
+		try {
+			$this->groupExists($group);			
+		} catch (\GuzzleHttp\Exception\ClientException $ex) {
+			$previous_user = $this->currentUser;
+			$this->currentUser = "admin";
+			$this->creatingTheGroup($group);
+			$this->currentUser = $previous_user;
+		}
+		$this->groupExists($group);
 		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
@@ -391,7 +496,17 @@ class FeatureContext extends BehatContext {
 	public function groupDoesNotExist($group) {
 		try {
 			$this->groupExists($group);
-			PHPUnit_Framework_Assert::fail('The group "' . $group . '" exists');
+		} catch (\GuzzleHttp\Exception\ClientException $ex) {
+			$this->response = $ex->getResponse();
+			PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+			return;
+		}
+		$previous_user = $this->currentUser;
+		$this->currentUser = "admin";
+		$this->deletingTheGroup($group);
+		$this->currentUser = $previous_user;
+		try {
+			$this->groupExists($group);
 		} catch (\GuzzleHttp\Exception\ClientException $ex) {
 			$this->response = $ex->getResponse();
 			PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
@@ -422,4 +537,81 @@ class FeatureContext extends BehatContext {
 			$this->response = $ex->getResponse();
 		}
 	}
+
+	/**
+	 * @When /^creating a public share with$/
+	 * @param \Behat\Gherkin\Node\TableNode|null $formData
+	 */
+	public function createPublicShare($body) {
+		$this->sendingToWith("POST", "/apps/files_sharing/api/v1/shares", $body);
+		$this->lastShareData = $this->response->xml();
+	}
+
+	/**
+	 * @Then /^Public shared file "([^"]*)" can be downloaded$/
+	 */
+	public function checkPublicSharedFile($filename) {
+		$client = new Client();
+		$options = [];
+		$url = $this->lastShareData->data[0]->url;
+		$fullUrl = $url . "/download";
+		$options['save_to'] = "./$filename";
+		$this->response = $client->get($fullUrl, $options);
+		$finfo = new finfo;
+		$fileinfo = $finfo->file("./$filename", FILEINFO_MIME_TYPE);
+		PHPUnit_Framework_Assert::assertEquals($fileinfo, "text/plain");
+		if (file_exists("./$filename")) {
+        	unlink("./$filename");
+        }
+	}
+
+	/**
+	 * @Then /^Public shared file "([^"]*)" with password "([^"]*)" can be downloaded$/
+	 */
+	public function checkPublicSharedFileWithPassword($filename, $password) {
+		$client = new Client();
+		$options = [];
+		$token = $this->lastShareData->data[0]->token;
+		$fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav";
+		$options['auth'] = [$token, $password];
+		$options['save_to'] = "./$filename";
+		$this->response = $client->get($fullUrl, $options);
+		$finfo = new finfo;
+		$fileinfo = $finfo->file("./$filename", FILEINFO_MIME_TYPE);
+		PHPUnit_Framework_Assert::assertEquals($fileinfo, "text/plain");
+		if (file_exists("./$filename")) {
+        	unlink("./$filename");
+        }
+	}
+
+	/**
+	 * @When /^Adding expiration date to last share$/
+	 */
+	public function addingExpirationDate() {
+		$share_id = $this->lastShareData->data[0]->id;
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->apiVersion}/shares/$share_id";
+		$client = new Client();
+		$options = [];
+		if ($this->currentUser === 'admin') {
+			$options['auth'] = $this->adminUser;
+		} else {
+			$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));
+		PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+	}
+
+	/**
+	 * @BeforeScenario
+	 * @AfterScenario
+	 */
+	public function cleanupUsers()
+	{
+		foreach($this->createdUsers as $user) {
+			$this->deleteUser($user);
+		}
+	}
+
 }
diff --git a/build/integration/features/sharing-v1.feature b/build/integration/features/sharing-v1.feature
new file mode 100644
index 0000000000000000000000000000000000000000..abf9fe1c8d88f50358f9b9d61be38def1778de7d
--- /dev/null
+++ b/build/integration/features/sharing-v1.feature
@@ -0,0 +1,60 @@
+Feature: sharing
+  Background:
+    Given using api version "1"
+
+  Scenario: Creating a new share with user
+    Given user "user0" exists
+    And user "user1" exists
+    And As an "user0"
+    When sending "POST" to "/apps/files_sharing/api/v1/shares" with
+      | path | welcome.txt |
+      | shareWith | user1 |
+      | shareType | 0 |
+    Then the OCS status code should be "100"
+    And the HTTP status code should be "200"
+
+  Scenario: Creating a share with a group
+    Given user "user0" exists
+    And user "user1" exists
+    And group "sharing-group" exists
+    And As an "user0"
+    When sending "POST" to "/apps/files_sharing/api/v1/shares" with
+      | path | welcome.txt |
+      | shareWith | sharing-group |
+      | shareType | 1 |
+    Then the OCS status code should be "100"
+    And the HTTP status code should be "200"
+
+  Scenario: Creating a new public share
+    Given user "user0" exists
+    And As an "user0"
+    When creating a public share with
+      | path | welcome.txt |
+      | shareType | 3 |
+    Then the OCS status code should be "100"
+    And the HTTP status code should be "200"
+    And Public shared file "welcome.txt" can be downloaded
+
+  Scenario: Creating a new public share with password
+    Given user "user0" exists
+    And As an "user0"
+    When creating a public share with
+      | path | welcome.txt |
+      | shareType | 3 |
+      | password | publicpw |
+    Then the OCS status code should be "100"
+    And the HTTP status code should be "200"
+    And Public shared file "welcome.txt" with password "publicpw" can be downloaded
+
+  Scenario: Creating a new public share with password and adding an expiration date
+    Given user "user0" exists
+    And As an "user0"
+    When creating a public share with
+      | path | welcome.txt |
+      | shareType | 3 |
+      | password | publicpw |
+    And Adding expiration date to last share
+    Then the OCS status code should be "100"
+    And the HTTP status code should be "200"
+    And Public shared file "welcome.txt" with password "publicpw" can be downloaded
+
diff --git a/build/integration/run.sh b/build/integration/run.sh
index 08f10b86c5f99082a01f1bb9f5dd1576443c1cca..5456a784404406d2fc13a4722e324dce7e40a719 100755
--- a/build/integration/run.sh
+++ b/build/integration/run.sh
@@ -14,6 +14,6 @@ PHPPID=$!
 echo $PHPPID
 
 export TEST_SERVER_URL="http://localhost:$PORT/ocs/"
-vendor/bin/behat --profile ci
+vendor/bin/behat -f junit -f pretty
 
 kill $PHPPID