diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5d460bc553ba866d77057bd4baa355553dc7290
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php
@@ -0,0 +1,88 @@
+<?php namespace Gitlab\Api;
+
+class IssueBoards extends AbstractApi
+{
+    /**
+     * @param int $project_id
+     * @param array $parameters
+     *
+     * @return mixed
+     */
+    public function all($project_id = null, array $parameters = [])
+    {
+        $resolver = $this->createOptionsResolver();
+
+        $path = $project_id === null ? 'boards' : $this->getProjectPath($project_id, 'boards');
+
+        return $this->get($path, $resolver->resolve($parameters));
+    }
+
+    /**
+     * @param int $project_id
+     * @param int $board_id
+     * @return mixed
+     */
+    public function allLists($project_id, $board_id)
+    {
+        return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'));
+    }
+
+
+    /**
+     * @param int $project_id
+     * @param int $board_id
+     * @param int $list_id
+     * @return mixed
+     */
+    public function showList($project_id, $board_id, $list_id)
+    {
+        return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'.$this->encodePath($list_id)));
+    }
+
+    /**
+     * @param int $project_id
+     * @param int $board_id
+     * @param int $label_id
+     * @return mixed
+     */
+    public function createList($project_id, $board_id, $label_id)
+    {
+        $params = array(
+            'id' => $project_id,
+            'board_id' => $board_id,
+            'label_id' => $label_id
+        );
+
+        return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'), $params);
+    }
+
+    /**
+     * @param int $project_id
+     * @param int $board_id
+     * @param int $list_id
+     * @param int $position
+     * @return mixed
+     */
+    public function updateList($project_id, $board_id, $list_id, $position)
+    {
+        $params = array(
+            'id' => $project_id,
+            'board_id' => $board_id,
+            'list_id' => $list_id,
+            'position' => $position
+        );
+
+        return $this->put($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id)), $params);
+    }
+
+    /**
+     * @param int $project_id
+     * @param int $board_id
+     * @param int $list_id
+     * @return mixed
+     */
+    public function deleteList($project_id, $board_id, $list_id)
+    {
+        return $this->delete($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id)));
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bec5679621145ff75b0b1bc56c55672ec0732d4
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php
@@ -0,0 +1,178 @@
+<?php namespace Gitlab\Api;
+
+use Psr\Http\Message\StreamInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class Jobs extends AbstractApi
+{
+    const SCOPE_CREATED = 'created';
+    const SCOPE_PENDING = 'pending';
+    const SCOPE_RUNNING = 'running';
+    const SCOPE_FAILED = 'failed';
+    const SCOPE_SUCCESS = 'success';
+    const SCOPE_CANCELED = 'canceled';
+    const SCOPE_SKIPPED = 'skipped';
+    const SCOPE_MANUAL = 'manual';
+
+    /**
+     * @param int|string $project_id
+     * @param array $parameters (
+     *
+     *     @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed,
+     *                                 success, canceled, skipped, manual; showing all jobs if none provided.
+     * )
+     *
+     * @return mixed
+     */
+    public function all($project_id, array $parameters = [])
+    {
+        $resolver = $this->createOptionsResolver();
+
+        return $this->get("projects/".$this->encodePath($project_id)."/jobs", $resolver->resolve($parameters));
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $pipeline_id
+     * @param array $parameters (
+     *
+     *     @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed,
+     *                                 success, canceled, skipped, manual; showing all jobs if none provided.
+     * )
+     *
+     * @return mixed
+     */
+    public function pipelineJobs($project_id, $pipeline_id, array $parameters = [])
+    {
+        $resolver = $this->createOptionsResolver();
+
+        return $this->get(
+            $this->getProjectPath($project_id, 'pipelines/').$this->encodePath($pipeline_id)."/jobs",
+            $resolver->resolve($parameters)
+        );
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function show($project_id, $job_id)
+    {
+        return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id));
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return StreamInterface
+     */
+    public function artifacts($project_id, $job_id)
+    {
+        return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts")->getBody();
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param string $ref_name
+     * @param string $job_name
+     * @return StreamInterface
+     */
+    public function artifactsByRefName($project_id, $ref_name, $job_name)
+    {
+        return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/artifacts/".$this->encodePath($ref_name)."/download", array(
+            'job' => $job_name
+        ))->getBody();
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return string
+     */
+    public function trace($project_id, $job_id)
+    {
+        return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/trace");
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function cancel($project_id, $job_id)
+    {
+        return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/cancel");
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function retry($project_id, $job_id)
+    {
+        return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/retry");
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function erase($project_id, $job_id)
+    {
+        return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/erase");
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function keepArtifacts($project_id, $job_id)
+    {
+        return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts/keep");
+    }
+
+    /**
+     * @param int|string $project_id
+     * @param int $job_id
+     * @return mixed
+     */
+    public function play($project_id, $job_id)
+    {
+        return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/play");
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function createOptionsResolver()
+    {
+        $allowedScopeValues = [
+            self::SCOPE_CANCELED,
+            self::SCOPE_CREATED,
+            self::SCOPE_FAILED,
+            self::SCOPE_MANUAL,
+            self::SCOPE_PENDING,
+            self::SCOPE_RUNNING,
+            self::SCOPE_SKIPPED,
+            self::SCOPE_SUCCESS,
+        ];
+
+        $resolver = parent::createOptionsResolver();
+        $resolver->setDefined('scope')
+            ->setAllowedTypes('scope', ['string', 'array'])
+            ->setAllowedValues('scope', $allowedScopeValues)
+            ->addAllowedValues('scope', function ($value) use ($allowedScopeValues) {
+                return is_array($value) && empty(array_diff($value, $allowedScopeValues));
+            })
+            ->setNormalizer('scope', function (OptionsResolver $resolver, $value) {
+                return (array) $value;
+            })
+        ;
+
+        return $resolver;
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc20c00f0d8604756353474517e7dbfe84e4e7c7
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Gitlab\Api;
+
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class RepositoryFiles extends AbstractApi
+{
+    /**
+     * @param int $project_id
+     * @param string $file_path
+     * @param string $ref
+     * @return mixed
+     */
+    public function getFile($project_id, $file_path, $ref)
+    {
+        return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path)), array(
+            'ref' => $ref
+        ));
+    }
+
+    /**
+     * @param int $project_id
+     * @param string $file_path
+     * @param string $ref
+     * @return mixed
+     */
+    public function getRawFile($project_id, $file_path, $ref)
+    {
+        return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path).'/raw'), array(
+            'ref' => $ref,
+        ));
+    }
+
+    /**
+     * @param int   $project_id
+     * @param array $parameters (
+     *
+     *     @var string $file_path      Url encoded full path to new file. Ex. lib%2Fclass%2Erb.
+     *     @var string $branch         Name of the branch.
+     *     @var string $start_branch   Name of the branch to start the new commit from.
+     *     @var string $encoding       Change encoding to 'base64'. Default is text.
+     *     @var string $author_email   Specify the commit author's email address.
+     *     @var string $author_name    Specify the commit author's name.
+     *     @var string $content        File content.
+     *     @var string $commit_message Commit message.
+     * )
+     *
+     * @return mixed
+     */
+    public function createFile($project_id, array $parameters = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setRequired('file_path');
+        $resolver->setRequired('branch');
+        $resolver->setDefined('start_branch');
+        $resolver->setDefined('encoding')
+            ->setAllowedValues('encoding', ['text', 'base64'])
+        ;
+        $resolver->setDefined('author_email');
+        $resolver->setDefined('author_name');
+        $resolver->setRequired('content');
+        $resolver->setRequired('commit_message');
+
+        $resolved = $resolver->resolve($parameters);
+
+        return $this->post($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved);
+    }
+
+    /**
+     * @param int   $project_id
+     * @param array $parameters (
+     *
+     *     @var string $file_path      Url encoded full path to new file. Ex. lib%2Fclass%2Erb.
+     *     @var string $branch         Name of the branch.
+     *     @var string $start_branch   Name of the branch to start the new commit from.
+     *     @var string $encoding       Change encoding to 'base64'. Default is text.
+     *     @var string $author_email   Specify the commit author's email address.
+     *     @var string $author_name    Specify the commit author's name.
+     *     @var string $content        File content.
+     *     @var string $commit_message Commit message.
+     *     @var string $last_commit_id Last known file commit id.
+     * )
+     *
+     * @return mixed
+     */
+    public function updateFile($project_id, array $parameters = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setRequired('file_path');
+        $resolver->setRequired('branch');
+        $resolver->setDefined('start_branch');
+        $resolver->setDefined('encoding')
+            ->setAllowedValues('encoding', ['text', 'base64'])
+        ;
+        $resolver->setDefined('author_email');
+        $resolver->setDefined('author_name');
+        $resolver->setRequired('content');
+        $resolver->setRequired('commit_message');
+        $resolver->setDefined('last_commit_id');
+
+        $resolved = $resolver->resolve($parameters);
+
+        return $this->put($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved);
+    }
+
+    /**
+     * @param int   $project_id
+     * @param array $parameters (
+     *
+     *     @var string $file_path      Url encoded full path to new file. Ex. lib%2Fclass%2Erb.
+     *     @var string $branch         Name of the branch.
+     *     @var string $start_branch   Name of the branch to start the new commit from.
+     *     @var string $author_email   Specify the commit author's email address.
+     *     @var string $author_name    Specify the commit author's name.
+     *     @var string $commit_message Commit message.
+     * )
+     *
+     * @return mixed
+     */
+    public function deleteFile($project_id, array $parameters = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setRequired('file_path');
+        $resolver->setRequired('branch');
+        $resolver->setDefined('start_branch');
+        $resolver->setDefined('author_email');
+        $resolver->setDefined('author_name');
+        $resolver->setRequired('commit_message');
+
+        $resolved = $resolver->resolve($parameters);
+
+        return $this->delete($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php
new file mode 100644
index 0000000000000000000000000000000000000000..15be1ff12bb8e04fcd85fa65122440cf1bf430b5
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Gitlab\HttpClient;
+
+use Http\Client\Common\HttpMethodsClient;
+use Http\Client\Common\Plugin;
+use Http\Client\Common\PluginClient;
+use Http\Client\HttpClient;
+use Http\Discovery\HttpClientDiscovery;
+use Http\Discovery\MessageFactoryDiscovery;
+use Http\Discovery\StreamFactoryDiscovery;
+use Http\Message\MessageFactory;
+use Http\Message\RequestFactory;
+use Http\Message\StreamFactory;
+
+/**
+ * A builder that builds the API client.
+ * This will allow you to fluently add and remove plugins.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+class Builder
+{
+    /**
+     * The object that sends HTTP messages.
+     *
+     * @var HttpClient
+     */
+    private $httpClient;
+
+    /**
+     * A HTTP client with all our plugins.
+     *
+     * @var HttpMethodsClient
+     */
+    private $pluginClient;
+
+    /**
+     * @var MessageFactory
+     */
+    private $requestFactory;
+
+    /**
+     * @var StreamFactory
+     */
+    private $streamFactory;
+
+    /**
+     * True if we should create a new Plugin client at next request.
+     *
+     * @var bool
+     */
+    private $httpClientModified = true;
+
+    /**
+     * @var Plugin[]
+     */
+    private $plugins = [];
+
+    /**
+     * @param HttpClient     $httpClient
+     * @param RequestFactory $requestFactory
+     * @param StreamFactory  $streamFactory
+     */
+    public function __construct(
+        HttpClient $httpClient = null,
+        RequestFactory $requestFactory = null,
+        StreamFactory $streamFactory = null
+    ) {
+        $this->httpClient = $httpClient ?: HttpClientDiscovery::find();
+        $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find();
+        $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
+    }
+
+    /**
+     * @return HttpMethodsClient
+     */
+    public function getHttpClient()
+    {
+        if ($this->httpClientModified) {
+            $this->httpClientModified = false;
+
+            $this->pluginClient = new HttpMethodsClient(
+                new PluginClient($this->httpClient, $this->plugins),
+                $this->requestFactory
+            );
+        }
+
+        return $this->pluginClient;
+    }
+
+    /**
+     * Add a new plugin to the end of the plugin chain.
+     *
+     * @param Plugin $plugin
+     */
+    public function addPlugin(Plugin $plugin)
+    {
+        $this->plugins[] = $plugin;
+        $this->httpClientModified = true;
+    }
+
+    /**
+     * Remove a plugin by its fully qualified class name (FQCN).
+     *
+     * @param string $fqcn
+     */
+    public function removePlugin($fqcn)
+    {
+        foreach ($this->plugins as $idx => $plugin) {
+            if ($plugin instanceof $fqcn) {
+                unset($this->plugins[$idx]);
+                $this->httpClientModified = true;
+            }
+        }
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..03e16a32610668223fe1d467c637fb74d65845cb
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Gitlab\HttpClient\Message;
+
+final class QueryStringBuilder
+{
+    /**
+     * Encode a query as a query string according to RFC 3986. Indexed arrays are encoded using
+     * empty squared brackets ([]) unlike http_build_query.
+     *
+     * @param mixed $query
+     *
+     * @return string
+     */
+    public static function build($query)
+    {
+        if (!is_array($query)) {
+            return static::rawurlencode($query);
+        }
+        return implode('&', array_map(function ($value, $key) {
+            return static::encode($value, $key);
+        }, $query, array_keys($query)));
+    }
+
+    /**
+     * Encode a value
+     * @param mixed $query
+     * @param string $prefix
+     *
+     * @return string
+     */
+    private static function encode($query, $prefix)
+    {
+        if (!is_array($query)) {
+            return static::rawurlencode($prefix).'='.static::rawurlencode($query);
+        }
+
+        $isIndexedArray = static::isIndexedArray($query);
+        return implode('&', array_map(function ($value, $key) use ($prefix, $isIndexedArray) {
+            $prefix = $isIndexedArray ? $prefix.'[]' : $prefix.'['.$key.']';
+            return static::encode($value, $prefix);
+        }, $query, array_keys($query)));
+    }
+
+    /**
+     * Tell if the given array is an indexed one (i.e. contains only sequential integer keys starting from 0).
+     *
+     * @param array $query
+     *
+     * @return bool
+     */
+    public static function isIndexedArray(array $query)
+    {
+        if (empty($query) || !isset($query[0])) {
+            return false;
+        }
+
+        return array_keys($query) === range(0, count($query) - 1);
+    }
+
+    /**
+     * Encode a value like rawurlencode, but return "0" when false is given.
+     *
+     * @param mixed $value
+     *
+     * @return string
+     */
+    private static function rawurlencode($value)
+    {
+        if ($value === false) {
+            return '0';
+        }
+
+        return rawurlencode($value);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php
new file mode 100644
index 0000000000000000000000000000000000000000..16bd781f07f7179bc93d508e262724da8cddc4a6
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Gitlab\HttpClient\Message;
+
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Utilities to parse response headers and content.
+ */
+class ResponseMediator
+{
+    /**
+     * Return the response body as a string or json array if content type is application/json.
+     *.
+     * @param ResponseInterface $response
+     *
+     * @return array|string
+     */
+    public static function getContent(ResponseInterface $response)
+    {
+        $body = $response->getBody()->__toString();
+        if (strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0) {
+            $content = json_decode($body, true);
+            if (JSON_ERROR_NONE === json_last_error()) {
+                return $content;
+            }
+        }
+
+        return $body;
+    }
+
+    /**
+     * Extract pagination URIs from Link header.
+     *
+     * @param ResponseInterface $response
+     *
+     * @return array|null
+     */
+    public static function getPagination(ResponseInterface $response)
+    {
+        if (!$response->hasHeader('Link')) {
+            return null;
+        }
+
+        $header = self::getHeader($response, 'Link');
+        $pagination = array();
+        foreach (explode(',', $header) as $link) {
+            preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match);
+
+            if (3 === count($match)) {
+                $pagination[$match[2]] = $match[1];
+            }
+        }
+
+        return $pagination;
+    }
+
+
+    /**
+     * Get the value for a single header.
+     *
+     * @param ResponseInterface $response
+     * @param string $name
+     *
+     * @return string|null
+     */
+    private static function getHeader(ResponseInterface $response, $name)
+    {
+        $headers = $response->getHeader($name);
+
+        return array_shift($headers);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php
new file mode 100644
index 0000000000000000000000000000000000000000..46b20e402284357dd3ee81eee9f76b1dfd854d6d
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php
@@ -0,0 +1,29 @@
+<?php
+
+
+namespace Gitlab\HttpClient\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Prefix requests path with /api/v4/ if required.
+ *
+ * @author Fabien Bourigault <bourigaultfabien@gmail.com>
+ */
+class ApiVersion implements Plugin
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $uri = $request->getUri();
+
+        if (substr($uri->getPath(), 0, 8) !== '/api/v4/') {
+            $request = $request->withUri($uri->withPath('/api/v4/'.$uri->getPath()));
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php
new file mode 100644
index 0000000000000000000000000000000000000000..aac0acc4a2e0c5a3a3cb585398bafa8dc68f6c66
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Gitlab\HttpClient\Plugin;
+
+use Gitlab\Client;
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Add authentication to the request.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ * @author Fabien Bourigault <bourigaultfabien@gmail.com>
+ */
+class Authentication implements Plugin
+{
+    /**
+     * @var string
+     */
+    private $method;
+
+    /**
+     * @var string
+     */
+    private $token;
+
+    /**
+     * @var string|null
+     */
+    private $sudo;
+
+    /**
+     * @param string      $method
+     * @param string      $token
+     * @param string|null $sudo
+     */
+    public function __construct($method, $token, $sudo = null)
+    {
+        $this->method  = $method;
+        $this->token = $token;
+        $this->sudo = $sudo;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        switch ($this->method) {
+            case Client::AUTH_HTTP_TOKEN:
+                $request = $request->withHeader('PRIVATE-TOKEN', $this->token);
+                if (!is_null($this->sudo)) {
+                    $request = $request->withHeader('SUDO', $this->sudo);
+                }
+                break;
+
+            case Client::AUTH_URL_TOKEN:
+                $uri = $request->getUri();
+                $query = $uri->getQuery();
+
+                $parameters = [
+                    'private_token' => $this->token,
+                ];
+
+                if (!is_null($this->sudo)) {
+                    $parameters['sudo'] = $this->sudo;
+                }
+
+                $query .= empty($query) ? '' : '&';
+                $query .= utf8_encode(http_build_query($parameters, '', '&'));
+
+                $uri = $uri->withQuery($query);
+                $request = $request->withUri($uri);
+                break;
+
+            case Client::AUTH_OAUTH_TOKEN:
+                $request = $request->withHeader('Authorization', 'Bearer '.$this->token);
+                if (!is_null($this->sudo)) {
+                    $request = $request->withHeader('SUDO', $this->sudo);
+                }
+                break;
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb61e31219f9650a90e8e52980c1e94d666c1bf3
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Gitlab\HttpClient\Plugin;
+
+use Gitlab\Exception\ErrorException;
+use Gitlab\Exception\RuntimeException;
+use Gitlab\HttpClient\Message\ResponseMediator;
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * A plugin to remember the last response.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ * @author Fabien Bourigault <bourigaultfabien@gmail.com>
+ */
+class GitlabExceptionThrower implements Plugin
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        return $next($request)->then(function (ResponseInterface $response) {
+            if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 600) {
+                $content = ResponseMediator::getContent($response);
+                if (is_array($content) && isset($content['message'])) {
+                    if (400 == $response->getStatusCode()) {
+                        $message = $this->parseMessage($content['message']);
+
+                        throw new ErrorException($message, 400);
+                    }
+                }
+
+                $errorMessage = null;
+                if (isset($content['error'])) {
+                    $errorMessage = $content['error'];
+                    if (is_array($content['error'])) {
+                        $errorMessage = implode("\n", $content['error']);
+                    }
+                } elseif (isset($content['message'])) {
+                    $errorMessage = $this->parseMessage($content['message']);
+                } else {
+                    $errorMessage = $content;
+                }
+
+                throw new RuntimeException($errorMessage, $response->getStatusCode());
+            }
+
+            return $response;
+        });
+    }
+
+    /**
+     * @param mixed $message
+     *
+     * @return string
+     */
+    private function parseMessage($message)
+    {
+        $string = $message;
+
+        if (is_array($message)) {
+            $format = '"%s" %s';
+            $errors = array();
+
+            foreach ($message as $field => $messages) {
+                if (is_array($messages)) {
+                    $messages = array_unique($messages);
+                    foreach ($messages as $error) {
+                        $errors[] = sprintf($format, $field, $error);
+                    }
+                } elseif (is_integer($field)) {
+                    $errors[] = $messages;
+                } else {
+                    $errors[] = sprintf($format, $field, $messages);
+                }
+            }
+
+            $string = implode(', ', $errors);
+        }
+
+        return $string;
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php
new file mode 100644
index 0000000000000000000000000000000000000000..8412356fdae09fea78832a5593bba3f3c187ddf9
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Gitlab\HttpClient\Plugin;
+
+use Http\Client\Common\Plugin\Journal;
+use Http\Client\Exception;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * A plugin to remember the last response.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+class History implements Journal
+{
+    /**
+     * @var ResponseInterface
+     */
+    private $lastResponse;
+
+    /**
+     * @return ResponseInterface|null
+     */
+    public function getLastResponse()
+    {
+        return $this->lastResponse;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addSuccess(RequestInterface $request, ResponseInterface $response)
+    {
+        $this->lastResponse = $response;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addFailure(RequestInterface $request, Exception $exception)
+    {
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php
new file mode 100644
index 0000000000000000000000000000000000000000..586e3a31185baf94ec1ef05b5edc5bf087446084
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php
@@ -0,0 +1,83 @@
+<?php namespace Gitlab\Model;
+
+use Gitlab\Client;
+
+/**
+ * Class Commit
+ *
+ * @property-read Commit $commit
+ * @property-read int $id
+ * @property-read string $coverage
+ * @property-read string $created_at
+ * @property-read string $artifacts_file
+ * @property-read string $finished_at
+ * @property-read string $name
+ * @property-read Pipeline $pipeline
+ * @property-read string $ref
+ * @property-read string $runner
+ * @property-read string $stage
+ * @property-read string $started_at
+ * @property-read string $status
+ * @property-read string|bool $tag
+ * @property-read User $user
+ */
+class Job extends AbstractModel
+{
+    /**
+     * @var array
+     */
+    protected static $properties = array(
+        'id',
+        'commit',
+        'coverage',
+        'created_at',
+        'artifacts_file',
+        'finished_at',
+        'name',
+        'pipeline',
+        'ref',
+        'runner',
+        'stage',
+        'started_at',
+        'status',
+        'tag',
+        'user'
+    );
+
+    /**
+     * @param Client  $client
+     * @param Project $project
+     * @param array   $data
+     * @return Job
+     */
+    public static function fromArray(Client $client, Project $project, array $data)
+    {
+        $job = new static($project, $data['id'], $client);
+
+        if (isset($data['user'])) {
+            $data['user'] = User::fromArray($client, $data['user']);
+        }
+
+        if (isset($data['commit'])) {
+            $data['commit'] = Commit::fromArray($client, $project, $data['commit']);
+        }
+
+        if (isset($data['pipeline'])) {
+            $data['pipeline'] = Pipeline::fromArray($client, $project, $data['pipeline']);
+        }
+
+        return $job->hydrate($data);
+    }
+
+    /**
+     * @param Project $project
+     * @param int $id
+     * @param Client  $client
+     */
+    public function __construct(Project $project, $id = null, Client $client = null)
+    {
+        $this->setClient($client);
+        $this->setData('project', $project);
+        $this->setData('id', $id);
+    }
+}
diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php
new file mode 100644
index 0000000000000000000000000000000000000000..efeccbc9879f78fe2a50df6b51ba0987c6c1ed22
--- /dev/null
+++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php
@@ -0,0 +1,49 @@
+<?php namespace Gitlab\Model;
+
+use Gitlab\Client;
+
+/**
+ * Class Commit
+ *
+ * @property-read int $id
+ * @property-read string $ref
+ * @property-read string $sha
+ * @property-read string $status
+ */
+class Pipeline extends AbstractModel
+{
+    /**
+     * @var array
+     */
+    protected static $properties = array(
+        'id',
+        'ref',
+        'sha',
+        'status'
+    );
+
+    /**
+     * @param Client  $client
+     * @param Project $project
+     * @param array   $data
+     * @return Pipeline
+     */
+    public static function fromArray(Client $client, Project $project, array $data)
+    {
+        $pipeline = new static($project, $data['id'], $client);
+
+        return $pipeline->hydrate($data);
+    }
+
+    /**
+     * @param Project $project
+     * @param int $id
+     * @param Client  $client
+     */
+    public function __construct(Project $project, $id = null, Client $client = null)
+    {
+        $this->setClient($client);
+        $this->setData('project', $project);
+        $this->setData('id', $id);
+    }
+}
diff --git a/vendor/php-http/client-common/CHANGELOG.md b/vendor/php-http/client-common/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..3031720c6d59e8b3362a4eda3370af07f98f56d9
--- /dev/null
+++ b/vendor/php-http/client-common/CHANGELOG.md
@@ -0,0 +1,137 @@
+# Change Log
+
+## 1.7.0 - 2017-11-30
+
+### Added 
+
+- Symfony 4 support
+
+### Changed
+
+- Strict comparison in DecoderPlugin
+
+## 1.6.0 - 2017-10-16
+
+### Added
+
+- Add HttpClientPool client to leverage load balancing and fallback mechanism [see the documentation](http://docs.php-http.org/en/latest/components/client-common.html) for more details.
+- `PluginClientFactory` to create `PluginClient` instances.
+- Added new option 'delay' for `RetryPlugin`.
+- Added new option 'decider' for `RetryPlugin`.
+- Supports more cookie date formats in the Cookie Plugin
+
+### Changed
+
+- The `RetryPlugin` does now wait between retries. To disable/change this feature you must write something like: 
+ 
+```php
+$plugin = new RetryPlugin(['delay' => function(RequestInterface $request, Exception $e, $retries) { 
+  return 0; 
+}); 
+```
+
+### Deprecated
+
+- The `debug_plugins` option for `PluginClient` is deprecated and will be removed in 2.0. Use the decorator design pattern instead like in [ProfilePlugin](https://github.com/php-http/HttplugBundle/blob/de33f9c14252f22093a5ec7d84f17535ab31a384/Collector/ProfilePlugin.php).
+
+## 1.5.0 - 2017-03-30
+
+### Added
+
+- `QueryDefaultsPlugin` to add default query parameters.
+
+## 1.4.2 - 2017-03-18
+
+### Deprecated
+
+- `DecoderPlugin` does not longer claim to support `compress` content encoding
+
+### Fixed
+
+- `CookiePlugin` allows main domain cookies to be sent/stored for subdomains
+- `DecoderPlugin` uses the right `FilteredStream` to handle `deflate` content encoding
+
+
+## 1.4.1 - 2017-02-20
+
+### Fixed
+
+- Cast return value of `StreamInterface::getSize` to string in `ContentLengthPlugin`
+
+
+## 1.4.0 - 2016-11-04
+
+### Added
+
+- Add Path plugin
+- Base URI plugin that combines Add Host and Add Path plugins
+
+
+## 1.3.0 - 2016-10-16
+
+### Changed
+
+- Fix Emulated Trait to use Http based promise which respect the HttpAsyncClient interface
+- Require Httplug 1.1 where we use HTTP specific promises.
+- RedirectPlugin: use the full URL instead of the URI to properly keep track of redirects
+- Add AddPathPlugin for API URLs with base path
+- Add BaseUriPlugin that combines AddHostPlugin and AddPathPlugin
+
+
+## 1.2.1 - 2016-07-26
+
+### Changed
+
+- AddHostPlugin also sets the port if specified
+
+
+## 1.2.0 - 2016-07-14
+
+### Added
+
+- Suggest separate plugins in composer.json
+- Introduced `debug_plugins` option for `PluginClient`
+
+
+## 1.1.0 - 2016-05-04
+
+### Added
+
+- Add a flexible http client providing both contract, and only emulating what's necessary
+- HTTP Client Router: route requests to underlying clients
+- Plugin client and core plugins moved here from `php-http/plugins`
+
+### Deprecated
+
+- Extending client classes, they will be made final in version 2.0
+
+
+## 1.0.0 - 2016-01-27
+
+### Changed
+
+- Remove useless interface in BatchException
+
+
+## 0.2.0 - 2016-01-12
+
+### Changed
+
+- Updated package files
+- Updated HTTPlug to RC1
+
+
+## 0.1.1 - 2015-12-26
+
+### Added
+
+- Emulated clients
+
+
+## 0.1.0 - 2015-12-25
+
+### Added
+
+- Batch client from utils
+- Methods client from utils
+- Emulators and decorators from client-tools
diff --git a/vendor/php-http/client-common/LICENSE b/vendor/php-http/client-common/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4558d6f06306fce15add8bc10e29152bc4ad5355
--- /dev/null
+++ b/vendor/php-http/client-common/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2016 PHP HTTP Team <team@php-http.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/client-common/README.md b/vendor/php-http/client-common/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..017bfcec93b5f7d436bffaade7e051ec0570ccb1
--- /dev/null
+++ b/vendor/php-http/client-common/README.md
@@ -0,0 +1,55 @@
+# HTTP Client Common
+
+[![Latest Version](https://img.shields.io/github/release/php-http/client-common.svg?style=flat-square)](https://github.com/php-http/client-common/releases)
+[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
+[![Build Status](https://img.shields.io/travis/php-http/client-common.svg?style=flat-square)](https://travis-ci.org/php-http/client-common)
+[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/php-http/client-common.svg?style=flat-square)](https://scrutinizer-ci.com/g/php-http/client-common)
+[![Quality Score](https://img.shields.io/scrutinizer/g/php-http/client-common.svg?style=flat-square)](https://scrutinizer-ci.com/g/php-http/client-common)
+[![Total Downloads](https://img.shields.io/packagist/dt/php-http/client-common.svg?style=flat-square)](https://packagist.org/packages/php-http/client-common)
+
+**Common HTTP Client implementations and tools for HTTPlug.**
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/client-common
+```
+
+
+## Usage
+
+This package provides common tools for HTTP Clients:
+
+- BatchClient to handle sending requests in parallel
+- A convenience client with HTTP method names as class methods
+- Emulator, decorator layers for sync/async clients
+
+
+## Documentation
+
+Please see the [official documentation](http://docs.php-http.org/en/latest/components/client-common.html).
+
+
+## Testing
+
+``` bash
+$ composer test
+```
+
+
+## Contributing
+
+Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html).
+
+
+## Security
+
+If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org).
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/client-common/composer.json b/vendor/php-http/client-common/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..fc5fc5fb4ea5e4927b72b29e406b5b47f3f691fa
--- /dev/null
+++ b/vendor/php-http/client-common/composer.json
@@ -0,0 +1,43 @@
+{
+    "name": "php-http/client-common",
+    "description": "Common HTTP Client implementations and tools for HTTPlug",
+    "license": "MIT",
+    "keywords": ["http", "client", "httplug", "common"],
+    "homepage": "http://httplug.io",
+    "authors": [
+        {
+            "name": "Márk Sági-Kazár",
+            "email": "mark.sagikazar@gmail.com"
+        }
+    ],
+    "require": {
+        "php": "^5.4 || ^7.0",
+        "php-http/httplug": "^1.1",
+        "php-http/message-factory": "^1.0",
+        "php-http/message": "^1.6",
+        "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0"
+    },
+    "require-dev": {
+        "phpspec/phpspec": "^2.5 || ^3.4 || ^4.2",
+        "guzzlehttp/psr7": "^1.4"
+    },
+    "suggest": {
+        "php-http/logger-plugin": "PSR-3 Logger plugin",
+        "php-http/cache-plugin": "PSR-6 Cache plugin",
+        "php-http/stopwatch-plugin": "Symfony Stopwatch plugin"
+    },
+    "autoload": {
+        "psr-4": {
+            "Http\\Client\\Common\\": "src/"
+        }
+    },
+    "scripts": {
+        "test": "vendor/bin/phpspec run",
+        "test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.7-dev"
+        }
+    }
+}
diff --git a/vendor/php-http/client-common/src/BatchClient.php b/vendor/php-http/client-common/src/BatchClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..2036355b604746ea942b0c69a95ba768723ae0e5
--- /dev/null
+++ b/vendor/php-http/client-common/src/BatchClient.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Exception;
+use Http\Client\HttpClient;
+use Http\Client\Common\Exception\BatchException;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * BatchClient allow to sends multiple request and retrieve a Batch Result.
+ *
+ * This implementation simply loops over the requests and uses sendRequest with each of them.
+ *
+ * @author Joel Wurtz <jwurtz@jolicode.com>
+ */
+class BatchClient implements HttpClient
+{
+    /**
+     * @var HttpClient
+     */
+    private $client;
+
+    /**
+     * @param HttpClient $client
+     */
+    public function __construct(HttpClient $client)
+    {
+        $this->client = $client;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        return $this->client->sendRequest($request);
+    }
+
+    /**
+     * Send several requests.
+     *
+     * You may not assume that the requests are executed in a particular order. If the order matters
+     * for your application, use sendRequest sequentially.
+     *
+     * @param RequestInterface[] The requests to send
+     *
+     * @return BatchResult Containing one result per request
+     *
+     * @throws BatchException If one or more requests fails. The exception gives access to the
+     *                        BatchResult with a map of request to result for success, request to
+     *                        exception for failures
+     */
+    public function sendRequests(array $requests)
+    {
+        $batchResult = new BatchResult();
+
+        foreach ($requests as $request) {
+            try {
+                $response = $this->sendRequest($request);
+                $batchResult = $batchResult->addResponse($request, $response);
+            } catch (Exception $e) {
+                $batchResult = $batchResult->addException($request, $e);
+            }
+        }
+
+        if ($batchResult->hasExceptions()) {
+            throw new BatchException($batchResult);
+        }
+
+        return $batchResult;
+    }
+}
diff --git a/vendor/php-http/client-common/src/BatchResult.php b/vendor/php-http/client-common/src/BatchResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..710611d6d00ff6b3069eff19a26f2daab6ec1e7e
--- /dev/null
+++ b/vendor/php-http/client-common/src/BatchResult.php
@@ -0,0 +1,181 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Exception;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Responses and exceptions returned from parallel request execution.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+final class BatchResult
+{
+    /**
+     * @var \SplObjectStorage
+     */
+    private $responses;
+
+    /**
+     * @var \SplObjectStorage
+     */
+    private $exceptions;
+
+    public function __construct()
+    {
+        $this->responses = new \SplObjectStorage();
+        $this->exceptions = new \SplObjectStorage();
+    }
+
+    /**
+     * Checks if there are any successful responses at all.
+     *
+     * @return bool
+     */
+    public function hasResponses()
+    {
+        return $this->responses->count() > 0;
+    }
+
+    /**
+     * Returns all successful responses.
+     *
+     * @return ResponseInterface[]
+     */
+    public function getResponses()
+    {
+        $responses = [];
+
+        foreach ($this->responses as $request) {
+            $responses[] = $this->responses[$request];
+        }
+
+        return $responses;
+    }
+
+    /**
+     * Checks if there is a successful response for a request.
+     *
+     * @param RequestInterface $request
+     *
+     * @return bool
+     */
+    public function isSuccessful(RequestInterface $request)
+    {
+        return $this->responses->contains($request);
+    }
+
+    /**
+     * Returns the response for a successful request.
+     *
+     * @param RequestInterface $request
+     *
+     * @return ResponseInterface
+     *
+     * @throws \UnexpectedValueException If request was not part of the batch or failed
+     */
+    public function getResponseFor(RequestInterface $request)
+    {
+        try {
+            return $this->responses[$request];
+        } catch (\UnexpectedValueException $e) {
+            throw new \UnexpectedValueException('Request not found', $e->getCode(), $e);
+        }
+    }
+
+    /**
+     * Adds a response in an immutable way.
+     *
+     * @param RequestInterface  $request
+     * @param ResponseInterface $response
+     *
+     * @return BatchResult the new BatchResult with this request-response pair added to it
+     */
+    public function addResponse(RequestInterface $request, ResponseInterface $response)
+    {
+        $new = clone $this;
+        $new->responses->attach($request, $response);
+
+        return $new;
+    }
+
+    /**
+     * Checks if there are any unsuccessful requests at all.
+     *
+     * @return bool
+     */
+    public function hasExceptions()
+    {
+        return $this->exceptions->count() > 0;
+    }
+
+    /**
+     * Returns all exceptions for the unsuccessful requests.
+     *
+     * @return Exception[]
+     */
+    public function getExceptions()
+    {
+        $exceptions = [];
+
+        foreach ($this->exceptions as $request) {
+            $exceptions[] = $this->exceptions[$request];
+        }
+
+        return $exceptions;
+    }
+
+    /**
+     * Checks if there is an exception for a request, meaning the request failed.
+     *
+     * @param RequestInterface $request
+     *
+     * @return bool
+     */
+    public function isFailed(RequestInterface $request)
+    {
+        return $this->exceptions->contains($request);
+    }
+
+    /**
+     * Returns the exception for a failed request.
+     *
+     * @param RequestInterface $request
+     *
+     * @return Exception
+     *
+     * @throws \UnexpectedValueException If request was not part of the batch or was successful
+     */
+    public function getExceptionFor(RequestInterface $request)
+    {
+        try {
+            return $this->exceptions[$request];
+        } catch (\UnexpectedValueException $e) {
+            throw new \UnexpectedValueException('Request not found', $e->getCode(), $e);
+        }
+    }
+
+    /**
+     * Adds an exception in an immutable way.
+     *
+     * @param RequestInterface $request
+     * @param Exception        $exception
+     *
+     * @return BatchResult the new BatchResult with this request-exception pair added to it
+     */
+    public function addException(RequestInterface $request, Exception $exception)
+    {
+        $new = clone $this;
+        $new->exceptions->attach($request, $exception);
+
+        return $new;
+    }
+
+    public function __clone()
+    {
+        $this->responses = clone $this->responses;
+        $this->exceptions = clone $this->exceptions;
+    }
+}
diff --git a/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php b/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b163167e6dfcfb23076e3a9ad4a19b96a86abfe
--- /dev/null
+++ b/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+
+/**
+ * Emulates an async HTTP client.
+ *
+ * This should be replaced by an anonymous class in PHP 7.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient
+{
+    use HttpAsyncClientEmulator;
+    use HttpClientDecorator;
+
+    /**
+     * @param HttpClient $httpClient
+     */
+    public function __construct(HttpClient $httpClient)
+    {
+        $this->httpClient = $httpClient;
+    }
+}
diff --git a/vendor/php-http/client-common/src/EmulatedHttpClient.php b/vendor/php-http/client-common/src/EmulatedHttpClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..01046c83e4c29a0578e6132da47ce378e8e71698
--- /dev/null
+++ b/vendor/php-http/client-common/src/EmulatedHttpClient.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+
+/**
+ * Emulates an HTTP client.
+ *
+ * This should be replaced by an anonymous class in PHP 7.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+class EmulatedHttpClient implements HttpClient, HttpAsyncClient
+{
+    use HttpAsyncClientDecorator;
+    use HttpClientEmulator;
+
+    /**
+     * @param HttpAsyncClient $httpAsyncClient
+     */
+    public function __construct(HttpAsyncClient $httpAsyncClient)
+    {
+        $this->httpAsyncClient = $httpAsyncClient;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Exception/BatchException.php b/vendor/php-http/client-common/src/Exception/BatchException.php
new file mode 100644
index 0000000000000000000000000000000000000000..66a92719e4ae05be21567ce08d5ecb84c716e808
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/BatchException.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\TransferException;
+use Http\Client\Common\BatchResult;
+
+/**
+ * This exception is thrown when HttpClient::sendRequests led to at least one failure.
+ *
+ * It gives access to a BatchResult with the request-exception and request-response pairs.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+final class BatchException extends TransferException
+{
+    /**
+     * @var BatchResult
+     */
+    private $result;
+
+    /**
+     * @param BatchResult $result
+     */
+    public function __construct(BatchResult $result)
+    {
+        $this->result = $result;
+    }
+
+    /**
+     * Returns the BatchResult that contains all responses and exceptions.
+     *
+     * @return BatchResult
+     */
+    public function getResult()
+    {
+        return $this->result;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php b/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php
new file mode 100644
index 0000000000000000000000000000000000000000..73ec521e17348e898ff895a172947e68bce93fce
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\HttpException;
+
+/**
+ * Thrown when circular redirection is detected.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class CircularRedirectionException extends HttpException
+{
+}
diff --git a/vendor/php-http/client-common/src/Exception/ClientErrorException.php b/vendor/php-http/client-common/src/Exception/ClientErrorException.php
new file mode 100644
index 0000000000000000000000000000000000000000..b1f6cc855eba0e100f9701f6d7d66269984661e2
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/ClientErrorException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\HttpException;
+
+/**
+ * Thrown when there is a client error (4xx).
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class ClientErrorException extends HttpException
+{
+}
diff --git a/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php b/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d33f9838360395298b9e8ca3ecfbc155f6b9b3f
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\TransferException;
+
+/**
+ * Thrown when a http client cannot be chosen in a pool.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class HttpClientNotFoundException extends TransferException
+{
+}
diff --git a/vendor/php-http/client-common/src/Exception/LoopException.php b/vendor/php-http/client-common/src/Exception/LoopException.php
new file mode 100644
index 0000000000000000000000000000000000000000..e834124df607bbe10f381cb432598e668771ca7e
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/LoopException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\RequestException;
+
+/**
+ * Thrown when the Plugin Client detects an endless loop.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class LoopException extends RequestException
+{
+}
diff --git a/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php b/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae514cd738c64fa063284a5823e31e06124bdc45
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\HttpException;
+
+/**
+ * Redirect location cannot be chosen.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class MultipleRedirectionException extends HttpException
+{
+}
diff --git a/vendor/php-http/client-common/src/Exception/ServerErrorException.php b/vendor/php-http/client-common/src/Exception/ServerErrorException.php
new file mode 100644
index 0000000000000000000000000000000000000000..665d72418b0b71403da4f8e8e6ce48c37bf38022
--- /dev/null
+++ b/vendor/php-http/client-common/src/Exception/ServerErrorException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Http\Client\Common\Exception;
+
+use Http\Client\Exception\HttpException;
+
+/**
+ * Thrown when there is a server error (5xx).
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class ServerErrorException extends HttpException
+{
+}
diff --git a/vendor/php-http/client-common/src/FlexibleHttpClient.php b/vendor/php-http/client-common/src/FlexibleHttpClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..58f88132d26f185881bf3bbf6e0b1f45b19842e7
--- /dev/null
+++ b/vendor/php-http/client-common/src/FlexibleHttpClient.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+
+/**
+ * A flexible http client, which implements both interface and will emulate
+ * one contract, the other, or none at all depending on the injected client contract.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class FlexibleHttpClient implements HttpClient, HttpAsyncClient
+{
+    use HttpClientDecorator;
+    use HttpAsyncClientDecorator;
+
+    /**
+     * @param HttpClient|HttpAsyncClient $client
+     */
+    public function __construct($client)
+    {
+        if (!($client instanceof HttpClient) && !($client instanceof HttpAsyncClient)) {
+            throw new \LogicException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient');
+        }
+
+        $this->httpClient = $client;
+        $this->httpAsyncClient = $client;
+
+        if (!($this->httpClient instanceof HttpClient)) {
+            $this->httpClient = new EmulatedHttpClient($this->httpClient);
+        }
+
+        if (!($this->httpAsyncClient instanceof HttpAsyncClient)) {
+            $this->httpAsyncClient = new EmulatedHttpAsyncClient($this->httpAsyncClient);
+        }
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php b/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php
new file mode 100644
index 0000000000000000000000000000000000000000..6eb576cdb154bb59098cece31e8e0508aad5bdc6
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Decorates an HTTP Async Client.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+trait HttpAsyncClientDecorator
+{
+    /**
+     * @var HttpAsyncClient
+     */
+    protected $httpAsyncClient;
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpAsyncClient::sendAsyncRequest
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        return $this->httpAsyncClient->sendAsyncRequest($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php b/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0ba354f87c401d2e70c13cefcceb00e153d018f
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Exception;
+use Http\Client\Promise;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Emulates an HTTP Async Client in an HTTP Client.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+trait HttpAsyncClientEmulator
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpClient::sendRequest
+     */
+    abstract public function sendRequest(RequestInterface $request);
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpAsyncClient::sendAsyncRequest
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        try {
+            return new Promise\HttpFulfilledPromise($this->sendRequest($request));
+        } catch (Exception $e) {
+            return new Promise\HttpRejectedPromise($e);
+        }
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientDecorator.php b/vendor/php-http/client-common/src/HttpClientDecorator.php
new file mode 100644
index 0000000000000000000000000000000000000000..a33d5efd79eb717d8c55f237c48068672d715fde
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientDecorator.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpClient;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Decorates an HTTP Client.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+trait HttpClientDecorator
+{
+    /**
+     * @var HttpClient
+     */
+    protected $httpClient;
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpClient::sendRequest
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        return $this->httpClient->sendRequest($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientEmulator.php b/vendor/php-http/client-common/src/HttpClientEmulator.php
new file mode 100644
index 0000000000000000000000000000000000000000..dbec1aba330324dde3cb758ad79cb8f6cedb091f
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientEmulator.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Emulates an HTTP Client in an HTTP Async Client.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+trait HttpClientEmulator
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpClient::sendRequest
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        $promise = $this->sendAsyncRequest($request);
+
+        return $promise->wait();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see HttpAsyncClient::sendAsyncRequest
+     */
+    abstract public function sendAsyncRequest(RequestInterface $request);
+}
diff --git a/vendor/php-http/client-common/src/HttpClientPool.php b/vendor/php-http/client-common/src/HttpClientPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ac292ca138fe31b4830268607e451bc6adfd5a4
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientPool.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Common\Exception\HttpClientNotFoundException;
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * A http client pool allows to send requests on a pool of different http client using a specific strategy (least used,
+ * round robin, ...).
+ */
+abstract class HttpClientPool implements HttpAsyncClient, HttpClient
+{
+    /**
+     * @var HttpClientPoolItem[]
+     */
+    protected $clientPool = [];
+
+    /**
+     * Add a client to the pool.
+     *
+     * @param HttpClient|HttpAsyncClient|HttpClientPoolItem $client
+     */
+    public function addHttpClient($client)
+    {
+        if (!$client instanceof HttpClientPoolItem) {
+            $client = new HttpClientPoolItem($client);
+        }
+
+        $this->clientPool[] = $client;
+    }
+
+    /**
+     * Return an http client given a specific strategy.
+     *
+     * @throws HttpClientNotFoundException When no http client has been found into the pool
+     *
+     * @return HttpClientPoolItem Return a http client that can do both sync or async
+     */
+    abstract protected function chooseHttpClient();
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        return $this->chooseHttpClient()->sendAsyncRequest($request);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        return $this->chooseHttpClient()->sendRequest($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..6299cceb60fafb9f70e89ea0323f2ba0d38f7647
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Http\Client\Common\HttpClientPool;
+
+use Http\Client\Common\Exception\HttpClientNotFoundException;
+use Http\Client\Common\HttpClientPool;
+use Http\Client\Common\HttpClientPoolItem;
+
+/**
+ * LeastUsedClientPool will choose the client with the less current request in the pool.
+ *
+ * This strategy is only useful when doing async request
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class LeastUsedClientPool extends HttpClientPool
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function chooseHttpClient()
+    {
+        $clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) {
+            return !$clientPoolItem->isDisabled();
+        });
+
+        if (0 === count($clientPool)) {
+            throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool');
+        }
+
+        usort($clientPool, function (HttpClientPoolItem $clientA, HttpClientPoolItem $clientB) {
+            if ($clientA->getSendingRequestCount() === $clientB->getSendingRequestCount()) {
+                return 0;
+            }
+
+            if ($clientA->getSendingRequestCount() < $clientB->getSendingRequestCount()) {
+                return -1;
+            }
+
+            return 1;
+        });
+
+        return reset($clientPool);
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..3255f865df369dfb2a6d388d28a3705390048274
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Http\Client\Common\HttpClientPool;
+
+use Http\Client\Common\Exception\HttpClientNotFoundException;
+use Http\Client\Common\HttpClientPool;
+use Http\Client\Common\HttpClientPoolItem;
+
+/**
+ * RoundRobinClientPool will choose the next client in the pool.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class RandomClientPool extends HttpClientPool
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function chooseHttpClient()
+    {
+        $clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) {
+            return !$clientPoolItem->isDisabled();
+        });
+
+        if (0 === count($clientPool)) {
+            throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool');
+        }
+
+        return $clientPool[array_rand($clientPool)];
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d8e40a013b036621ae0a9ef6729e7812bc04f3f
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Http\Client\Common\HttpClientPool;
+
+use Http\Client\Common\Exception\HttpClientNotFoundException;
+use Http\Client\Common\HttpClientPool;
+
+/**
+ * RoundRobinClientPool will choose the next client in the pool.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class RoundRobinClientPool extends HttpClientPool
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function chooseHttpClient()
+    {
+        $last = current($this->clientPool);
+
+        do {
+            $client = next($this->clientPool);
+
+            if (false === $client) {
+                $client = reset($this->clientPool);
+
+                if (false === $client) {
+                    throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool');
+                }
+            }
+
+            // Case when there is only one and the last one has been disabled
+            if ($last === $client && $client->isDisabled()) {
+                throw new HttpClientNotFoundException('Cannot choose a http client as there is no one enabled in the pool');
+            }
+        } while ($client->isDisabled());
+
+        return $client;
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientPoolItem.php b/vendor/php-http/client-common/src/HttpClientPoolItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..09cd6ddf1c96f4bea9817b25c2d1544497dcc617
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientPoolItem.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+use Psr\Http\Message\RequestInterface;
+use Http\Client\Exception;
+
+/**
+ * A HttpClientPoolItem represent a HttpClient inside a Pool.
+ *
+ * It is disabled when a request failed and can be reenable after a certain number of seconds
+ * It also keep tracks of the current number of request the client is currently sending (only usable for async method)
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class HttpClientPoolItem implements HttpClient, HttpAsyncClient
+{
+    /**
+     * @var int Number of request this client is currently sending
+     */
+    private $sendingRequestCount = 0;
+
+    /**
+     * @var \DateTime|null Time when this client has been disabled or null if enable
+     */
+    private $disabledAt;
+
+    /**
+     * @var int|null Number of seconds after this client is reenable, by default null: never reenable this client
+     */
+    private $reenableAfter;
+
+    /**
+     * @var FlexibleHttpClient A http client responding to async and sync request
+     */
+    private $client;
+
+    /**
+     * @param HttpClient|HttpAsyncClient $client
+     * @param null|int                   $reenableAfter Number of seconds after this client is reenable
+     */
+    public function __construct($client, $reenableAfter = null)
+    {
+        $this->client = new FlexibleHttpClient($client);
+        $this->reenableAfter = $reenableAfter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        if ($this->isDisabled()) {
+            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
+        }
+
+        try {
+            $this->incrementRequestCount();
+            $response = $this->client->sendRequest($request);
+            $this->decrementRequestCount();
+        } catch (Exception $e) {
+            $this->disable();
+            $this->decrementRequestCount();
+
+            throw $e;
+        }
+
+        return $response;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        if ($this->isDisabled()) {
+            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
+        }
+
+        $this->incrementRequestCount();
+
+        return $this->client->sendAsyncRequest($request)->then(function ($response) {
+            $this->decrementRequestCount();
+
+            return $response;
+        }, function ($exception) {
+            $this->disable();
+            $this->decrementRequestCount();
+
+            throw $exception;
+        });
+    }
+
+    /**
+     * Whether this client is disabled or not.
+     *
+     * Will also reactivate this client if possible
+     *
+     * @internal
+     *
+     * @return bool
+     */
+    public function isDisabled()
+    {
+        $disabledAt = $this->getDisabledAt();
+
+        if (null !== $this->reenableAfter && null !== $disabledAt) {
+            // Reenable after a certain time
+            $now = new \DateTime();
+
+            if (($now->getTimestamp() - $disabledAt->getTimestamp()) >= $this->reenableAfter) {
+                $this->enable();
+
+                return false;
+            }
+
+            return true;
+        }
+
+        return null !== $disabledAt;
+    }
+
+    /**
+     * Get current number of request that is send by the underlying http client.
+     *
+     * @internal
+     *
+     * @return int
+     */
+    public function getSendingRequestCount()
+    {
+        return $this->sendingRequestCount;
+    }
+
+    /**
+     * Return when this client has been disabled or null if it's enabled.
+     *
+     * @return \DateTime|null
+     */
+    private function getDisabledAt()
+    {
+        return $this->disabledAt;
+    }
+
+    /**
+     * Increment the request count.
+     */
+    private function incrementRequestCount()
+    {
+        ++$this->sendingRequestCount;
+    }
+
+    /**
+     * Decrement the request count.
+     */
+    private function decrementRequestCount()
+    {
+        --$this->sendingRequestCount;
+    }
+
+    /**
+     * Enable the current client.
+     */
+    private function enable()
+    {
+        $this->disabledAt = null;
+    }
+
+    /**
+     * Disable the current client.
+     */
+    private function disable()
+    {
+        $this->disabledAt = new \DateTime('now');
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpClientRouter.php b/vendor/php-http/client-common/src/HttpClientRouter.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f721336a172a5ab3f75fe70899a9081503f4618
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpClientRouter.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Exception\RequestException;
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+use Http\Message\RequestMatcher;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Route a request to a specific client in the stack based using a RequestMatcher.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class HttpClientRouter implements HttpClient, HttpAsyncClient
+{
+    /**
+     * @var array
+     */
+    private $clients = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        $client = $this->chooseHttpClient($request);
+
+        return $client->sendRequest($request);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        $client = $this->chooseHttpClient($request);
+
+        return $client->sendAsyncRequest($request);
+    }
+
+    /**
+     * Add a client to the router.
+     *
+     * @param HttpClient|HttpAsyncClient $client
+     * @param RequestMatcher             $requestMatcher
+     */
+    public function addClient($client, RequestMatcher $requestMatcher)
+    {
+        $this->clients[] = [
+            'matcher' => $requestMatcher,
+            'client' => new FlexibleHttpClient($client),
+        ];
+    }
+
+    /**
+     * Choose an HTTP client given a specific request.
+     *
+     * @param RequestInterface $request
+     *
+     * @return HttpClient|HttpAsyncClient
+     */
+    protected function chooseHttpClient(RequestInterface $request)
+    {
+        foreach ($this->clients as $client) {
+            if ($client['matcher']->matches($request)) {
+                return $client['client'];
+            }
+        }
+
+        throw new RequestException('No client found for the specified request', $request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/HttpMethodsClient.php b/vendor/php-http/client-common/src/HttpMethodsClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..58804fc243f89c9a3a78d16fa0d3200c66c020d6
--- /dev/null
+++ b/vendor/php-http/client-common/src/HttpMethodsClient.php
@@ -0,0 +1,205 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Exception;
+use Http\Client\HttpClient;
+use Http\Message\RequestFactory;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Convenience HTTP client that integrates the MessageFactory in order to send
+ * requests in the following form:.
+ *
+ * $client
+ *     ->get('/foo')
+ *     ->post('/bar')
+ * ;
+ *
+ * The client also exposes the sendRequest methods of the wrapped HttpClient.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ * @author David Buchmann <mail@davidbu.ch>
+ */
+class HttpMethodsClient implements HttpClient
+{
+    /**
+     * @var HttpClient
+     */
+    private $httpClient;
+
+    /**
+     * @var RequestFactory
+     */
+    private $requestFactory;
+
+    /**
+     * @param HttpClient     $httpClient     The client to send requests with
+     * @param RequestFactory $requestFactory The message factory to create requests
+     */
+    public function __construct(HttpClient $httpClient, RequestFactory $requestFactory)
+    {
+        $this->httpClient = $httpClient;
+        $this->requestFactory = $requestFactory;
+    }
+
+    /**
+     * Sends a GET request.
+     *
+     * @param string|UriInterface $uri
+     * @param array               $headers
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function get($uri, array $headers = [])
+    {
+        return $this->send('GET', $uri, $headers, null);
+    }
+
+    /**
+     * Sends an HEAD request.
+     *
+     * @param string|UriInterface $uri
+     * @param array               $headers
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function head($uri, array $headers = [])
+    {
+        return $this->send('HEAD', $uri, $headers, null);
+    }
+
+    /**
+     * Sends a TRACE request.
+     *
+     * @param string|UriInterface $uri
+     * @param array               $headers
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function trace($uri, array $headers = [])
+    {
+        return $this->send('TRACE', $uri, $headers, null);
+    }
+
+    /**
+     * Sends a POST request.
+     *
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function post($uri, array $headers = [], $body = null)
+    {
+        return $this->send('POST', $uri, $headers, $body);
+    }
+
+    /**
+     * Sends a PUT request.
+     *
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function put($uri, array $headers = [], $body = null)
+    {
+        return $this->send('PUT', $uri, $headers, $body);
+    }
+
+    /**
+     * Sends a PATCH request.
+     *
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function patch($uri, array $headers = [], $body = null)
+    {
+        return $this->send('PATCH', $uri, $headers, $body);
+    }
+
+    /**
+     * Sends a DELETE request.
+     *
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function delete($uri, array $headers = [], $body = null)
+    {
+        return $this->send('DELETE', $uri, $headers, $body);
+    }
+
+    /**
+     * Sends an OPTIONS request.
+     *
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function options($uri, array $headers = [], $body = null)
+    {
+        return $this->send('OPTIONS', $uri, $headers, $body);
+    }
+
+    /**
+     * Sends a request with any HTTP method.
+     *
+     * @param string                      $method  HTTP method to use
+     * @param string|UriInterface         $uri
+     * @param array                       $headers
+     * @param string|StreamInterface|null $body
+     *
+     * @throws Exception
+     *
+     * @return ResponseInterface
+     */
+    public function send($method, $uri, array $headers = [], $body = null)
+    {
+        return $this->sendRequest($this->requestFactory->createRequest(
+            $method,
+            $uri,
+            $headers,
+            $body
+        ));
+    }
+
+    /**
+     * Forward to the underlying HttpClient.
+     *
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        return $this->httpClient->sendRequest($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin.php b/vendor/php-http/client-common/src/Plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..89a2a622d46c69f9a7ffb47042c4667e46ef556f
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Promise\Promise;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * A plugin is a middleware to transform the request and/or the response.
+ *
+ * The plugin can:
+ *  - break the chain and return a response
+ *  - dispatch the request to the next middleware
+ *  - restart the request
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+interface Plugin
+{
+    /**
+     * Handle the request and return the response coming from the next callable.
+     *
+     * @see http://docs.php-http.org/en/latest/plugins/build-your-own.html
+     *
+     * @param RequestInterface $request
+     * @param callable         $next    Next middleware in the chain, the request is passed as the first argument
+     * @param callable         $first   First middleware in the chain, used to to restart a request
+     *
+     * @return Promise Resolves a PSR-7 Response or fails with an Http\Client\Exception (The same as HttpAsyncClient).
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first);
+}
diff --git a/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php b/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..29ab8ae84097e9c6ad748d0acba3db2f3911a8b4
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\UriInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Add schema, host and port to a request. Can be set to overwrite the schema and host if desired.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+final class AddHostPlugin implements Plugin
+{
+    /**
+     * @var UriInterface
+     */
+    private $host;
+
+    /**
+     * @var bool
+     */
+    private $replace;
+
+    /**
+     * @param UriInterface $host
+     * @param array        $config {
+     *
+     *     @var bool $replace True will replace all hosts, false will only add host when none is specified.
+     * }
+     */
+    public function __construct(UriInterface $host, array $config = [])
+    {
+        if ('' === $host->getHost()) {
+            throw new \LogicException('Host can not be empty');
+        }
+
+        $this->host = $host;
+
+        $resolver = new OptionsResolver();
+        $this->configureOptions($resolver);
+        $options = $resolver->resolve($config);
+
+        $this->replace = $options['replace'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        if ($this->replace || '' === $request->getUri()->getHost()) {
+            $uri = $request->getUri()
+                ->withHost($this->host->getHost())
+                ->withScheme($this->host->getScheme())
+                ->withPort($this->host->getPort())
+            ;
+
+            $request = $request->withUri($uri);
+        }
+
+        return $next($request);
+    }
+
+    /**
+     * @param OptionsResolver $resolver
+     */
+    private function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults([
+            'replace' => false,
+        ]);
+        $resolver->setAllowedTypes('replace', 'bool');
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php b/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..e24d61a4e42a89c60e4ed07c54c93e31b949533d
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Prepend a base path to the request URI. Useful for base API URLs like http://domain.com/api.
+ *
+ * @author Sullivan Senechal <soullivaneuh@gmail.com>
+ */
+final class AddPathPlugin implements Plugin
+{
+    /**
+     * @var UriInterface
+     */
+    private $uri;
+
+    /**
+     * @param UriInterface $uri
+     */
+    public function __construct(UriInterface $uri)
+    {
+        if ('' === $uri->getPath()) {
+            throw new \LogicException('URI path cannot be empty');
+        }
+
+        if ('/' === substr($uri->getPath(), -1)) {
+            throw new \LogicException('URI path cannot end with a slash.');
+        }
+
+        $this->uri = $uri;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $request = $request->withUri($request->getUri()
+            ->withPath($this->uri->getPath().$request->getUri()->getPath())
+        );
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php b/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..194712fcde024fa81991162084fa041c6fae2827
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Message\Authentication;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Send an authenticated request.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class AuthenticationPlugin implements Plugin
+{
+    /**
+     * @var Authentication An authentication system
+     */
+    private $authentication;
+
+    /**
+     * @param Authentication $authentication
+     */
+    public function __construct(Authentication $authentication)
+    {
+        $this->authentication = $authentication;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $request = $this->authentication->authenticate($request);
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php b/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c2a7752cf466b2a8061dd1093970c59687317b3
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Combines the AddHostPlugin and AddPathPlugin.
+ *
+ * @author Sullivan Senechal <soullivaneuh@gmail.com>
+ */
+final class BaseUriPlugin implements Plugin
+{
+    /**
+     * @var AddHostPlugin
+     */
+    private $addHostPlugin;
+
+    /**
+     * @var AddPathPlugin|null
+     */
+    private $addPathPlugin = null;
+
+    /**
+     * @param UriInterface $uri        Has to contain a host name and cans have a path.
+     * @param array        $hostConfig Config for AddHostPlugin. @see AddHostPlugin::configureOptions
+     */
+    public function __construct(UriInterface $uri, array $hostConfig = [])
+    {
+        $this->addHostPlugin = new AddHostPlugin($uri, $hostConfig);
+
+        if (rtrim($uri->getPath(), '/')) {
+            $this->addPathPlugin = new AddPathPlugin($uri);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $addHostNext = function (RequestInterface $request) use ($next, $first) {
+            return $this->addHostPlugin->handleRequest($request, $next, $first);
+        };
+
+        if ($this->addPathPlugin) {
+            return $this->addPathPlugin->handleRequest($request, $addHostNext, $first);
+        }
+
+        return $addHostNext($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php b/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f7aafaeda3197f4571dabd6996b22e2f4e26eec
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Message\Encoding\ChunkStream;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Allow to set the correct content length header on the request or to transfer it as a chunk if not possible.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class ContentLengthPlugin implements Plugin
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        if (!$request->hasHeader('Content-Length')) {
+            $stream = $request->getBody();
+
+            // Cannot determine the size so we use a chunk stream
+            if (null === $stream->getSize()) {
+                $stream = new ChunkStream($stream);
+                $request = $request->withBody($stream);
+                $request = $request->withAddedHeader('Transfer-Encoding', 'chunked');
+            } else {
+                $request = $request->withHeader('Content-Length', (string) $stream->getSize());
+            }
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php b/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ef1d62b34b0dd36cbf21769fda7b4d8de37088b
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\StreamInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Allow to set the correct content type header on the request automatically only if it is not set.
+ *
+ * @author Karim Pinchon <karim.pinchon@gmail.com>
+ */
+final class ContentTypePlugin implements Plugin
+{
+    /**
+     * Allow to disable the content type detection when stream is too large (as it can consume a lot of resource).
+     *
+     * @var bool
+     *
+     * true     skip the content type detection
+     * false    detect the content type (default value)
+     */
+    protected $skipDetection;
+
+    /**
+     * Determine the size stream limit for which the detection as to be skipped (default to 16Mb).
+     *
+     * @var int
+     */
+    protected $sizeLimit;
+
+    /**
+     * @param array $config {
+     *
+     *     @var bool $skip_detection True skip detection if stream size is bigger than $size_limit.
+     *     @var int $size_limit size stream limit for which the detection as to be skipped.
+     * }
+     */
+    public function __construct(array $config = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setDefaults([
+            'skip_detection' => false,
+            'size_limit' => 16000000,
+        ]);
+        $resolver->setAllowedTypes('skip_detection', 'bool');
+        $resolver->setAllowedTypes('size_limit', 'int');
+
+        $options = $resolver->resolve($config);
+
+        $this->skipDetection = $options['skip_detection'];
+        $this->sizeLimit = $options['size_limit'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        if (!$request->hasHeader('Content-Type')) {
+            $stream = $request->getBody();
+            $streamSize = $stream->getSize();
+
+            if (!$stream->isSeekable()) {
+                return $next($request);
+            }
+
+            if (0 === $streamSize) {
+                return $next($request);
+            }
+
+            if ($this->skipDetection && (null === $streamSize || $streamSize >= $this->sizeLimit)) {
+                return $next($request);
+            }
+
+            if ($this->isJson($stream)) {
+                $request = $request->withHeader('Content-Type', 'application/json');
+
+                return $next($request);
+            }
+
+            if ($this->isXml($stream)) {
+                $request = $request->withHeader('Content-Type', 'application/xml');
+
+                return $next($request);
+            }
+        }
+
+        return $next($request);
+    }
+
+    /**
+     * @param $stream StreamInterface
+     *
+     * @return bool
+     */
+    private function isJson($stream)
+    {
+        $stream->rewind();
+
+        json_decode($stream->getContents());
+
+        return JSON_ERROR_NONE === json_last_error();
+    }
+
+    /**
+     * @param $stream StreamInterface
+     *
+     * @return \SimpleXMLElement|false
+     */
+    private function isXml($stream)
+    {
+        $stream->rewind();
+
+        $previousValue = libxml_use_internal_errors(true);
+        $isXml = simplexml_load_string($stream->getContents());
+        libxml_use_internal_errors($previousValue);
+
+        return $isXml;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/CookiePlugin.php b/vendor/php-http/client-common/src/Plugin/CookiePlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..59ee90da19d21ea442596a95fa427c630bc41874
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/CookiePlugin.php
@@ -0,0 +1,180 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Client\Exception\TransferException;
+use Http\Message\Cookie;
+use Http\Message\CookieJar;
+use Http\Message\CookieUtil;
+use Http\Message\Exception\UnexpectedValueException;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Handle request cookies.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class CookiePlugin implements Plugin
+{
+    /**
+     * Cookie storage.
+     *
+     * @var CookieJar
+     */
+    private $cookieJar;
+
+    /**
+     * @param CookieJar $cookieJar
+     */
+    public function __construct(CookieJar $cookieJar)
+    {
+        $this->cookieJar = $cookieJar;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->cookieJar->getCookies() as $cookie) {
+            if ($cookie->isExpired()) {
+                continue;
+            }
+
+            if (!$cookie->matchDomain($request->getUri()->getHost())) {
+                continue;
+            }
+
+            if (!$cookie->matchPath($request->getUri()->getPath())) {
+                continue;
+            }
+
+            if ($cookie->isSecure() && ('https' !== $request->getUri()->getScheme())) {
+                continue;
+            }
+
+            $request = $request->withAddedHeader('Cookie', sprintf('%s=%s', $cookie->getName(), $cookie->getValue()));
+        }
+
+        return $next($request)->then(function (ResponseInterface $response) use ($request) {
+            if ($response->hasHeader('Set-Cookie')) {
+                $setCookies = $response->getHeader('Set-Cookie');
+
+                foreach ($setCookies as $setCookie) {
+                    $cookie = $this->createCookie($request, $setCookie);
+
+                    // Cookie invalid do not use it
+                    if (null === $cookie) {
+                        continue;
+                    }
+
+                    // Restrict setting cookie from another domain
+                    if (!preg_match("/\.{$cookie->getDomain()}$/", '.'.$request->getUri()->getHost())) {
+                        continue;
+                    }
+
+                    $this->cookieJar->addCookie($cookie);
+                }
+            }
+
+            return $response;
+        });
+    }
+
+    /**
+     * Creates a cookie from a string.
+     *
+     * @param RequestInterface $request
+     * @param $setCookie
+     *
+     * @return Cookie|null
+     *
+     * @throws TransferException
+     */
+    private function createCookie(RequestInterface $request, $setCookie)
+    {
+        $parts = array_map('trim', explode(';', $setCookie));
+
+        if (empty($parts) || !strpos($parts[0], '=')) {
+            return;
+        }
+
+        list($name, $cookieValue) = $this->createValueKey(array_shift($parts));
+
+        $maxAge = null;
+        $expires = null;
+        $domain = $request->getUri()->getHost();
+        $path = $request->getUri()->getPath();
+        $secure = false;
+        $httpOnly = false;
+
+        // Add the cookie pieces into the parsed data array
+        foreach ($parts as $part) {
+            list($key, $value) = $this->createValueKey($part);
+
+            switch (strtolower($key)) {
+                case 'expires':
+                    try {
+                        $expires = CookieUtil::parseDate($value);
+                    } catch (UnexpectedValueException $e) {
+                        throw new TransferException(
+                            sprintf(
+                                'Cookie header `%s` expires value `%s` could not be converted to date',
+                                $name,
+                                $value
+                            ),
+                            null,
+                            $e
+                        );
+                    }
+
+                    break;
+
+                case 'max-age':
+                    $maxAge = (int) $value;
+
+                    break;
+
+                case 'domain':
+                    $domain = $value;
+
+                    break;
+
+                case 'path':
+                    $path = $value;
+
+                    break;
+
+                case 'secure':
+                    $secure = true;
+
+                    break;
+
+                case 'httponly':
+                    $httpOnly = true;
+
+                    break;
+            }
+        }
+
+        return new Cookie($name, $cookieValue, $maxAge, $domain, $path, $secure, $httpOnly, $expires);
+    }
+
+    /**
+     * Separates key/value pair from cookie.
+     *
+     * @param $part
+     *
+     * @return array
+     */
+    private function createValueKey($part)
+    {
+        $parts = explode('=', $part, 2);
+        $key = trim($parts[0]);
+        $value = isset($parts[1]) ? trim($parts[1]) : true;
+
+        return [$key, $value];
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php b/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..b661b613ac72a6235f272bdcfb8a5660a95a24e0
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Message\Encoding;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Allow to decode response body with a chunk, deflate, compress or gzip encoding.
+ *
+ * If zlib is not installed, only chunked encoding can be handled.
+ *
+ * If Content-Encoding is not disabled, the plugin will add an Accept-Encoding header for the encoding methods it supports.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class DecoderPlugin implements Plugin
+{
+    /**
+     * @var bool Whether this plugin decode stream with value in the Content-Encoding header (default to true).
+     *
+     * If set to false only the Transfer-Encoding header will be used
+     */
+    private $useContentEncoding;
+
+    /**
+     * @param array $config {
+     *
+     *    @var bool $use_content_encoding Whether this plugin should look at the Content-Encoding header first or only at the Transfer-Encoding (defaults to true).
+     * }
+     */
+    public function __construct(array $config = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setDefaults([
+            'use_content_encoding' => true,
+        ]);
+        $resolver->setAllowedTypes('use_content_encoding', 'bool');
+        $options = $resolver->resolve($config);
+
+        $this->useContentEncoding = $options['use_content_encoding'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $encodings = extension_loaded('zlib') ? ['gzip', 'deflate'] : ['identity'];
+
+        if ($this->useContentEncoding) {
+            $request = $request->withHeader('Accept-Encoding', $encodings);
+        }
+        $encodings[] = 'chunked';
+        $request = $request->withHeader('TE', $encodings);
+
+        return $next($request)->then(function (ResponseInterface $response) {
+            return $this->decodeResponse($response);
+        });
+    }
+
+    /**
+     * Decode a response body given its Transfer-Encoding or Content-Encoding value.
+     *
+     * @param ResponseInterface $response Response to decode
+     *
+     * @return ResponseInterface New response decoded
+     */
+    private function decodeResponse(ResponseInterface $response)
+    {
+        $response = $this->decodeOnEncodingHeader('Transfer-Encoding', $response);
+
+        if ($this->useContentEncoding) {
+            $response = $this->decodeOnEncodingHeader('Content-Encoding', $response);
+        }
+
+        return $response;
+    }
+
+    /**
+     * Decode a response on a specific header (content encoding or transfer encoding mainly).
+     *
+     * @param string            $headerName Name of the header
+     * @param ResponseInterface $response   Response
+     *
+     * @return ResponseInterface A new instance of the response decoded
+     */
+    private function decodeOnEncodingHeader($headerName, ResponseInterface $response)
+    {
+        if ($response->hasHeader($headerName)) {
+            $encodings = $response->getHeader($headerName);
+            $newEncodings = [];
+
+            while ($encoding = array_pop($encodings)) {
+                $stream = $this->decorateStream($encoding, $response->getBody());
+
+                if (false === $stream) {
+                    array_unshift($newEncodings, $encoding);
+
+                    continue;
+                }
+
+                $response = $response->withBody($stream);
+            }
+
+            $response = $response->withHeader($headerName, $newEncodings);
+        }
+
+        return $response;
+    }
+
+    /**
+     * Decorate a stream given an encoding.
+     *
+     * @param string          $encoding
+     * @param StreamInterface $stream
+     *
+     * @return StreamInterface|false A new stream interface or false if encoding is not supported
+     */
+    private function decorateStream($encoding, StreamInterface $stream)
+    {
+        if ('chunked' === strtolower($encoding)) {
+            return new Encoding\DechunkStream($stream);
+        }
+
+        if ('deflate' === strtolower($encoding)) {
+            return new Encoding\DecompressStream($stream);
+        }
+
+        if ('gzip' === strtolower($encoding)) {
+            return new Encoding\GzipDecodeStream($stream);
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php b/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..f09d3b161a8883947e2ba6458a46a20c676ba38f
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Exception\ClientErrorException;
+use Http\Client\Common\Exception\ServerErrorException;
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Throw exception when the response of a request is not acceptable.
+ *
+ * Status codes 400-499 lead to a ClientErrorException, status 500-599 to a ServerErrorException.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class ErrorPlugin implements Plugin
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $promise = $next($request);
+
+        return $promise->then(function (ResponseInterface $response) use ($request) {
+            return $this->transformResponseToException($request, $response);
+        });
+    }
+
+    /**
+     * Transform response to an error if possible.
+     *
+     * @param RequestInterface  $request  Request of the call
+     * @param ResponseInterface $response Response of the call
+     *
+     * @throws ClientErrorException If response status code is a 4xx
+     * @throws ServerErrorException If response status code is a 5xx
+     *
+     * @return ResponseInterface If status code is not in 4xx or 5xx return response
+     */
+    protected function transformResponseToException(RequestInterface $request, ResponseInterface $response)
+    {
+        if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 500) {
+            throw new ClientErrorException($response->getReasonPhrase(), $request, $response);
+        }
+
+        if ($response->getStatusCode() >= 500 && $response->getStatusCode() < 600) {
+            throw new ServerErrorException($response->getReasonPhrase(), $request, $response);
+        }
+
+        return $response;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..26fd813458564a612d2730ec0735a9ca3930b362
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Append headers to the request.
+ *
+ * If the header already exists the value will be appended to the current value.
+ *
+ * This only makes sense for headers that can have multiple values like 'Forwarded'
+ *
+ * @see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
+ *
+ * @author Soufiane Ghzal <sghzal@gmail.com>
+ */
+final class HeaderAppendPlugin implements Plugin
+{
+    /**
+     * @var array
+     */
+    private $headers = [];
+
+    /**
+     * @param array $headers Hashmap of header name to header value
+     */
+    public function __construct(array $headers)
+    {
+        $this->headers = $headers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->headers as $header => $headerValue) {
+            $request = $request->withAddedHeader($header, $headerValue);
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dfc1115a06a099d641b90aa2eb1e9357f2d5d71
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Set header to default value if it does not exist.
+ *
+ * If a given header already exists the value wont be replaced and the request wont be changed.
+ *
+ * @author Soufiane Ghzal <sghzal@gmail.com>
+ */
+final class HeaderDefaultsPlugin implements Plugin
+{
+    /**
+     * @var array
+     */
+    private $headers = [];
+
+    /**
+     * @param array $headers Hashmap of header name to header value
+     */
+    public function __construct(array $headers)
+    {
+        $this->headers = $headers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->headers as $header => $headerValue) {
+            if (!$request->hasHeader($header)) {
+                $request = $request->withHeader($header, $headerValue);
+            }
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc9c19d1aadabf34c1287a9ed97b78f78ebbbc74
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Removes headers from the request.
+ *
+ * @author Soufiane Ghzal <sghzal@gmail.com>
+ */
+final class HeaderRemovePlugin implements Plugin
+{
+    /**
+     * @var array
+     */
+    private $headers = [];
+
+    /**
+     * @param array $headers List of header names to remove from the request
+     */
+    public function __construct(array $headers)
+    {
+        $this->headers = $headers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->headers as $header) {
+            if ($request->hasHeader($header)) {
+                $request = $request->withoutHeader($header);
+            }
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..75f11d40aaae9c7ded7edf960b1dcc99deae9bd8
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Set headers on the request.
+ *
+ * If the header does not exist it wil be set, if the header already exists it will be replaced.
+ *
+ * @author Soufiane Ghzal <sghzal@gmail.com>
+ */
+final class HeaderSetPlugin implements Plugin
+{
+    /**
+     * @var array
+     */
+    private $headers = [];
+
+    /**
+     * @param array $headers Hashmap of header name to header value
+     */
+    public function __construct(array $headers)
+    {
+        $this->headers = $headers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->headers as $header => $headerValue) {
+            $request = $request->withHeader($header, $headerValue);
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php b/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..5abddbd84128d6a95617ed2410d3b6817736a884
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Client\Exception;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Record HTTP calls.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class HistoryPlugin implements Plugin
+{
+    /**
+     * Journal use to store request / responses / exception.
+     *
+     * @var Journal
+     */
+    private $journal;
+
+    /**
+     * @param Journal $journal
+     */
+    public function __construct(Journal $journal)
+    {
+        $this->journal = $journal;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $journal = $this->journal;
+
+        return $next($request)->then(function (ResponseInterface $response) use ($request, $journal) {
+            $journal->addSuccess($request, $response);
+
+            return $response;
+        }, function (Exception $exception) use ($request, $journal) {
+            $journal->addFailure($request, $exception);
+
+            throw $exception;
+        });
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/Journal.php b/vendor/php-http/client-common/src/Plugin/Journal.php
new file mode 100644
index 0000000000000000000000000000000000000000..15f309569fb9842a58ed0c13feb27374f26de40f
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/Journal.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Exception;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Records history of HTTP calls.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+interface Journal
+{
+    /**
+     * Record a successful call.
+     *
+     * @param RequestInterface  $request  Request use to make the call
+     * @param ResponseInterface $response Response returned by the call
+     */
+    public function addSuccess(RequestInterface $request, ResponseInterface $response);
+
+    /**
+     * Record a failed call.
+     *
+     * @param RequestInterface $request   Request use to make the call
+     * @param Exception        $exception Exception returned by the call
+     */
+    public function addFailure(RequestInterface $request, Exception $exception);
+}
diff --git a/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php b/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c1e32cd307fefe0960c80bf1e6ce57dab518d34
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Set query to default value if it does not exist.
+ *
+ * If a given query parameter already exists the value wont be replaced and the request wont be changed.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+final class QueryDefaultsPlugin implements Plugin
+{
+    /**
+     * @var array
+     */
+    private $queryParams = [];
+
+    /**
+     * @param array $queryParams Hashmap of query name to query value. Names and values must not be url encoded as
+     *                           this plugin will encode them
+     */
+    public function __construct(array $queryParams)
+    {
+        $this->queryParams = $queryParams;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        foreach ($this->queryParams as $name => $value) {
+            $uri = $request->getUri();
+            $array = [];
+            parse_str($uri->getQuery(), $array);
+
+            // If query value is not found
+            if (!isset($array[$name])) {
+                $array[$name] = $value;
+
+                // Create a new request with the new URI with the added query param
+                $request = $request->withUri(
+                    $uri->withQuery(http_build_query($array))
+                );
+            }
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php b/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2f442edb8fe95cc9676ef0295e64e2427df9748
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php
@@ -0,0 +1,270 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Exception\CircularRedirectionException;
+use Http\Client\Common\Exception\MultipleRedirectionException;
+use Http\Client\Common\Plugin;
+use Http\Client\Exception\HttpException;
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Follow redirections.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+class RedirectPlugin implements Plugin
+{
+    /**
+     * Rule on how to redirect, change method for the new request.
+     *
+     * @var array
+     */
+    protected $redirectCodes = [
+        300 => [
+            'switch' => [
+                'unless' => ['GET', 'HEAD'],
+                'to' => 'GET',
+            ],
+            'multiple' => true,
+            'permanent' => false,
+        ],
+        301 => [
+            'switch' => [
+                'unless' => ['GET', 'HEAD'],
+                'to' => 'GET',
+            ],
+            'multiple' => false,
+            'permanent' => true,
+        ],
+        302 => [
+            'switch' => [
+                'unless' => ['GET', 'HEAD'],
+                'to' => 'GET',
+            ],
+            'multiple' => false,
+            'permanent' => false,
+        ],
+        303 => [
+            'switch' => [
+                'unless' => ['GET', 'HEAD'],
+                'to' => 'GET',
+            ],
+            'multiple' => false,
+            'permanent' => false,
+        ],
+        307 => [
+            'switch' => false,
+            'multiple' => false,
+            'permanent' => false,
+        ],
+        308 => [
+            'switch' => false,
+            'multiple' => false,
+            'permanent' => true,
+        ],
+    ];
+
+    /**
+     * Determine how header should be preserved from old request.
+     *
+     * @var bool|array
+     *
+     * true     will keep all previous headers (default value)
+     * false    will ditch all previous headers
+     * string[] will keep only headers with the specified names
+     */
+    protected $preserveHeader;
+
+    /**
+     * Store all previous redirect from 301 / 308 status code.
+     *
+     * @var array
+     */
+    protected $redirectStorage = [];
+
+    /**
+     * Whether the location header must be directly used for a multiple redirection status code (300).
+     *
+     * @var bool
+     */
+    protected $useDefaultForMultiple;
+
+    /**
+     * @var array
+     */
+    protected $circularDetection = [];
+
+    /**
+     * @param array $config {
+     *
+     *     @var bool|string[] $preserve_header True keeps all headers, false remove all of them, an array is interpreted as a list of header names to keep
+     *     @var bool $use_default_for_multiple Whether the location header must be directly used for a multiple redirection status code (300).
+     * }
+     */
+    public function __construct(array $config = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setDefaults([
+            'preserve_header' => true,
+            'use_default_for_multiple' => true,
+        ]);
+        $resolver->setAllowedTypes('preserve_header', ['bool', 'array']);
+        $resolver->setAllowedTypes('use_default_for_multiple', 'bool');
+        $resolver->setNormalizer('preserve_header', function (OptionsResolver $resolver, $value) {
+            if (is_bool($value) && false === $value) {
+                return [];
+            }
+
+            return $value;
+        });
+        $options = $resolver->resolve($config);
+
+        $this->preserveHeader = $options['preserve_header'];
+        $this->useDefaultForMultiple = $options['use_default_for_multiple'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        // Check in storage
+        if (array_key_exists((string) $request->getUri(), $this->redirectStorage)) {
+            $uri = $this->redirectStorage[(string) $request->getUri()]['uri'];
+            $statusCode = $this->redirectStorage[(string) $request->getUri()]['status'];
+            $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode);
+
+            return $first($redirectRequest);
+        }
+
+        return $next($request)->then(function (ResponseInterface $response) use ($request, $first) {
+            $statusCode = $response->getStatusCode();
+
+            if (!array_key_exists($statusCode, $this->redirectCodes)) {
+                return $response;
+            }
+
+            $uri = $this->createUri($response, $request);
+            $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode);
+            $chainIdentifier = spl_object_hash((object) $first);
+
+            if (!array_key_exists($chainIdentifier, $this->circularDetection)) {
+                $this->circularDetection[$chainIdentifier] = [];
+            }
+
+            $this->circularDetection[$chainIdentifier][] = (string) $request->getUri();
+
+            if (in_array((string) $redirectRequest->getUri(), $this->circularDetection[$chainIdentifier])) {
+                throw new CircularRedirectionException('Circular redirection detected', $request, $response);
+            }
+
+            if ($this->redirectCodes[$statusCode]['permanent']) {
+                $this->redirectStorage[(string) $request->getUri()] = [
+                    'uri' => $uri,
+                    'status' => $statusCode,
+                ];
+            }
+
+            // Call redirect request in synchrone
+            $redirectPromise = $first($redirectRequest);
+
+            return $redirectPromise->wait();
+        });
+    }
+
+    /**
+     * Builds the redirect request.
+     *
+     * @param RequestInterface $request    Original request
+     * @param UriInterface     $uri        New uri
+     * @param int              $statusCode Status code from the redirect response
+     *
+     * @return MessageInterface|RequestInterface
+     */
+    protected function buildRedirectRequest(RequestInterface $request, UriInterface $uri, $statusCode)
+    {
+        $request = $request->withUri($uri);
+
+        if (false !== $this->redirectCodes[$statusCode]['switch'] && !in_array($request->getMethod(), $this->redirectCodes[$statusCode]['switch']['unless'])) {
+            $request = $request->withMethod($this->redirectCodes[$statusCode]['switch']['to']);
+        }
+
+        if (is_array($this->preserveHeader)) {
+            $headers = array_keys($request->getHeaders());
+
+            foreach ($headers as $name) {
+                if (!in_array($name, $this->preserveHeader)) {
+                    $request = $request->withoutHeader($name);
+                }
+            }
+        }
+
+        return $request;
+    }
+
+    /**
+     * Creates a new Uri from the old request and the location header.
+     *
+     * @param ResponseInterface $response The redirect response
+     * @param RequestInterface  $request  The original request
+     *
+     * @throws HttpException                If location header is not usable (missing or incorrect)
+     * @throws MultipleRedirectionException If a 300 status code is received and default location cannot be resolved (doesn't use the location header or not present)
+     *
+     * @return UriInterface
+     */
+    private function createUri(ResponseInterface $response, RequestInterface $request)
+    {
+        if ($this->redirectCodes[$response->getStatusCode()]['multiple'] && (!$this->useDefaultForMultiple || !$response->hasHeader('Location'))) {
+            throw new MultipleRedirectionException('Cannot choose a redirection', $request, $response);
+        }
+
+        if (!$response->hasHeader('Location')) {
+            throw new HttpException('Redirect status code, but no location header present in the response', $request, $response);
+        }
+
+        $location = $response->getHeaderLine('Location');
+        $parsedLocation = parse_url($location);
+
+        if (false === $parsedLocation) {
+            throw new HttpException(sprintf('Location %s could not be parsed', $location), $request, $response);
+        }
+
+        $uri = $request->getUri();
+
+        if (array_key_exists('scheme', $parsedLocation)) {
+            $uri = $uri->withScheme($parsedLocation['scheme']);
+        }
+
+        if (array_key_exists('host', $parsedLocation)) {
+            $uri = $uri->withHost($parsedLocation['host']);
+        }
+
+        if (array_key_exists('port', $parsedLocation)) {
+            $uri = $uri->withPort($parsedLocation['port']);
+        }
+
+        if (array_key_exists('path', $parsedLocation)) {
+            $uri = $uri->withPath($parsedLocation['path']);
+        }
+
+        if (array_key_exists('query', $parsedLocation)) {
+            $uri = $uri->withQuery($parsedLocation['query']);
+        } else {
+            $uri = $uri->withQuery('');
+        }
+
+        if (array_key_exists('fragment', $parsedLocation)) {
+            $uri = $uri->withFragment($parsedLocation['fragment']);
+        } else {
+            $uri = $uri->withFragment('');
+        }
+
+        return $uri;
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php b/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f72b02d8ac6973ba659ab9d4bf1f7f1eaf97eba
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Message\RequestMatcher;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Apply a delegated plugin based on a request match.
+ *
+ * @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
+ */
+final class RequestMatcherPlugin implements Plugin
+{
+    /**
+     * @var RequestMatcher
+     */
+    private $requestMatcher;
+
+    /**
+     * @var Plugin
+     */
+    private $delegatedPlugin;
+
+    /**
+     * @param RequestMatcher $requestMatcher
+     * @param Plugin         $delegatedPlugin
+     */
+    public function __construct(RequestMatcher $requestMatcher, Plugin $delegatedPlugin)
+    {
+        $this->requestMatcher = $requestMatcher;
+        $this->delegatedPlugin = $delegatedPlugin;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        if ($this->requestMatcher->matches($request)) {
+            return $this->delegatedPlugin->handleRequest($request, $next, $first);
+        }
+
+        return $next($request);
+    }
+}
diff --git a/vendor/php-http/client-common/src/Plugin/RetryPlugin.php b/vendor/php-http/client-common/src/Plugin/RetryPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..8446246e673c4cab2cb3685f894a18220b14f385
--- /dev/null
+++ b/vendor/php-http/client-common/src/Plugin/RetryPlugin.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Http\Client\Common\Plugin;
+
+use Http\Client\Common\Plugin;
+use Http\Client\Exception;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * Retry the request if an exception is thrown.
+ *
+ * By default will retry only one time.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class RetryPlugin implements Plugin
+{
+    /**
+     * Number of retry before sending an exception.
+     *
+     * @var int
+     */
+    private $retry;
+
+    /**
+     * @var callable
+     */
+    private $delay;
+
+    /**
+     * @var callable
+     */
+    private $decider;
+
+    /**
+     * Store the retry counter for each request.
+     *
+     * @var array
+     */
+    private $retryStorage = [];
+
+    /**
+     * @param array $config {
+     *
+     *     @var int $retries Number of retries to attempt if an exception occurs before letting the exception bubble up.
+     *     @var callable $decider A callback that gets a request and an exception to decide after a failure whether the request should be retried.
+     *     @var callable $delay A callback that gets a request, an exception and the number of retries and returns how many microseconds we should wait before trying again.
+     * }
+     */
+    public function __construct(array $config = [])
+    {
+        $resolver = new OptionsResolver();
+        $resolver->setDefaults([
+            'retries' => 1,
+            'decider' => function (RequestInterface $request, Exception $e) {
+                return true;
+            },
+            'delay' => __CLASS__.'::defaultDelay',
+        ]);
+        $resolver->setAllowedTypes('retries', 'int');
+        $resolver->setAllowedTypes('decider', 'callable');
+        $resolver->setAllowedTypes('delay', 'callable');
+        $options = $resolver->resolve($config);
+
+        $this->retry = $options['retries'];
+        $this->decider = $options['decider'];
+        $this->delay = $options['delay'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleRequest(RequestInterface $request, callable $next, callable $first)
+    {
+        $chainIdentifier = spl_object_hash((object) $first);
+
+        return $next($request)->then(function (ResponseInterface $response) use ($request, $chainIdentifier) {
+            if (array_key_exists($chainIdentifier, $this->retryStorage)) {
+                unset($this->retryStorage[$chainIdentifier]);
+            }
+
+            return $response;
+        }, function (Exception $exception) use ($request, $next, $first, $chainIdentifier) {
+            if (!array_key_exists($chainIdentifier, $this->retryStorage)) {
+                $this->retryStorage[$chainIdentifier] = 0;
+            }
+
+            if ($this->retryStorage[$chainIdentifier] >= $this->retry) {
+                unset($this->retryStorage[$chainIdentifier]);
+
+                throw $exception;
+            }
+
+            if (!call_user_func($this->decider, $request, $exception)) {
+                throw $exception;
+            }
+
+            $time = call_user_func($this->delay, $request, $exception, $this->retryStorage[$chainIdentifier]);
+            usleep($time);
+
+            // Retry in synchrone
+            ++$this->retryStorage[$chainIdentifier];
+            $promise = $this->handleRequest($request, $next, $first);
+
+            return $promise->wait();
+        });
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param Exception        $e
+     * @param int              $retries The number of retries we made before. First time this get called it will be 0.
+     *
+     * @return int
+     */
+    public static function defaultDelay(RequestInterface $request, Exception $e, $retries)
+    {
+        return pow(2, $retries) * 500000;
+    }
+}
diff --git a/vendor/php-http/client-common/src/PluginClient.php b/vendor/php-http/client-common/src/PluginClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..93aea8f2fda0c2ead27a5de67006a43a7a0c51d5
--- /dev/null
+++ b/vendor/php-http/client-common/src/PluginClient.php
@@ -0,0 +1,179 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\Common\Exception\LoopException;
+use Http\Client\Exception as HttplugException;
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+use Http\Client\Promise\HttpFulfilledPromise;
+use Http\Client\Promise\HttpRejectedPromise;
+use Psr\Http\Message\RequestInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * The client managing plugins and providing a decorator around HTTP Clients.
+ *
+ * @author Joel Wurtz <joel.wurtz@gmail.com>
+ */
+final class PluginClient implements HttpClient, HttpAsyncClient
+{
+    /**
+     * An HTTP async client.
+     *
+     * @var HttpAsyncClient
+     */
+    private $client;
+
+    /**
+     * The plugin chain.
+     *
+     * @var Plugin[]
+     */
+    private $plugins;
+
+    /**
+     * A list of options.
+     *
+     * @var array
+     */
+    private $options;
+
+    /**
+     * @param HttpClient|HttpAsyncClient $client
+     * @param Plugin[]                   $plugins
+     * @param array                      $options {
+     *
+     *     @var int      $max_restarts
+     *     @var Plugin[] $debug_plugins an array of plugins that are injected between each normal plugin
+     * }
+     *
+     * @throws \RuntimeException if client is not an instance of HttpClient or HttpAsyncClient
+     */
+    public function __construct($client, array $plugins = [], array $options = [])
+    {
+        if ($client instanceof HttpAsyncClient) {
+            $this->client = $client;
+        } elseif ($client instanceof HttpClient) {
+            $this->client = new EmulatedHttpAsyncClient($client);
+        } else {
+            throw new \RuntimeException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient');
+        }
+
+        $this->plugins = $plugins;
+        $this->options = $this->configure($options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendRequest(RequestInterface $request)
+    {
+        // If we don't have an http client, use the async call
+        if (!($this->client instanceof HttpClient)) {
+            return $this->sendAsyncRequest($request)->wait();
+        }
+
+        // Else we want to use the synchronous call of the underlying client, and not the async one in the case
+        // we have both an async and sync call
+        $pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) {
+            try {
+                return new HttpFulfilledPromise($this->client->sendRequest($request));
+            } catch (HttplugException $exception) {
+                return new HttpRejectedPromise($exception);
+            }
+        });
+
+        return $pluginChain($request)->wait();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function sendAsyncRequest(RequestInterface $request)
+    {
+        $pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) {
+            return $this->client->sendAsyncRequest($request);
+        });
+
+        return $pluginChain($request);
+    }
+
+    /**
+     * Configure the plugin client.
+     *
+     * @param array $options
+     *
+     * @return array
+     */
+    private function configure(array $options = [])
+    {
+        if (isset($options['debug_plugins'])) {
+            @trigger_error('The "debug_plugins" option is deprecated since 1.5 and will be removed in 2.0.', E_USER_DEPRECATED);
+        }
+
+        $resolver = new OptionsResolver();
+        $resolver->setDefaults([
+            'max_restarts' => 10,
+            'debug_plugins' => [],
+        ]);
+
+        $resolver
+            ->setAllowedTypes('debug_plugins', 'array')
+            ->setAllowedValues('debug_plugins', function (array $plugins) {
+                foreach ($plugins as $plugin) {
+                    // Make sure each object passed with the `debug_plugins` is an instance of Plugin.
+                    if (!$plugin instanceof Plugin) {
+                        return false;
+                    }
+                }
+
+                return true;
+            });
+
+        return $resolver->resolve($options);
+    }
+
+    /**
+     * Create the plugin chain.
+     *
+     * @param Plugin[] $pluginList     A list of plugins
+     * @param callable $clientCallable Callable making the HTTP call
+     *
+     * @return callable
+     */
+    private function createPluginChain($pluginList, callable $clientCallable)
+    {
+        $firstCallable = $lastCallable = $clientCallable;
+
+        /*
+         * Inject debug plugins between each plugin.
+         */
+        $pluginListWithDebug = $this->options['debug_plugins'];
+        foreach ($pluginList as $plugin) {
+            $pluginListWithDebug[] = $plugin;
+            $pluginListWithDebug = array_merge($pluginListWithDebug, $this->options['debug_plugins']);
+        }
+
+        while ($plugin = array_pop($pluginListWithDebug)) {
+            $lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable, &$firstCallable) {
+                return $plugin->handleRequest($request, $lastCallable, $firstCallable);
+            };
+
+            $firstCallable = $lastCallable;
+        }
+
+        $firstCalls = 0;
+        $firstCallable = function (RequestInterface $request) use ($lastCallable, &$firstCalls) {
+            if ($firstCalls > $this->options['max_restarts']) {
+                throw new LoopException('Too many restarts in plugin client', $request);
+            }
+
+            ++$firstCalls;
+
+            return $lastCallable($request);
+        };
+
+        return $firstCallable;
+    }
+}
diff --git a/vendor/php-http/client-common/src/PluginClientFactory.php b/vendor/php-http/client-common/src/PluginClientFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd4c08f9a62530a792022e7830a0ecd681e7c828
--- /dev/null
+++ b/vendor/php-http/client-common/src/PluginClientFactory.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Http\Client\Common;
+
+use Http\Client\HttpAsyncClient;
+use Http\Client\HttpClient;
+
+/**
+ * Factory to create PluginClient instances. Using this factory instead of calling PluginClient constructor will enable
+ * the Symfony profiling without any configuration.
+ *
+ * @author Fabien Bourigault <bourigaultfabien@gmail.com>
+ */
+final class PluginClientFactory
+{
+    /**
+     * @var callable
+     */
+    private static $factory;
+
+    /**
+     * Set the factory to use.
+     * The callable to provide must have the same arguments and return type as PluginClientFactory::createClient.
+     * This is used by the HTTPlugBundle to provide a better Symfony integration.
+     * Unlike the createClient method, this one is static to allow zero configuration profiling by hooking into early
+     * application execution.
+     *
+     * @internal
+     *
+     * @param callable $factory
+     */
+    public static function setFactory(callable $factory)
+    {
+        static::$factory = $factory;
+    }
+
+    /**
+     * @param HttpClient|HttpAsyncClient $client
+     * @param Plugin[]                   $plugins
+     * @param array                      $options {
+     *
+     *     @var string $client_name to give client a name which may be used when displaying client information  like in
+     *         the HTTPlugBundle profiler.
+     * }
+     *
+     * @see PluginClient constructor for PluginClient specific $options.
+     *
+     * @return PluginClient
+     */
+    public function createClient($client, array $plugins = [], array $options = [])
+    {
+        if (static::$factory) {
+            $factory = static::$factory;
+
+            return $factory($client, $plugins, $options);
+        }
+
+        unset($options['client_name']);
+
+        return new PluginClient($client, $plugins, $options);
+    }
+}
diff --git a/vendor/php-http/multipart-stream-builder/CHANGELOG.md b/vendor/php-http/multipart-stream-builder/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..1f0ee3d7f32e2bc04227bb2988081ba0fbd2af08
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/CHANGELOG.md
@@ -0,0 +1,60 @@
+# Change Log
+
+## 1.0.0 - 2017-05-21
+
+No changes from 0.2.0.
+
+## 0.2.0 - 2017-02-20
+
+You may do a BC update to version 0.2.0 if you are sure that you are not adding
+multiple resources with the same name to the Builder. 
+
+### Fixed
+
+- Make sure one can add resources with same name without overwrite. 
+
+## 0.1.6 - 2017-02-16
+
+### Fixed
+
+- Performance improvements by avoid using `uniqid()`. 
+
+## 0.1.5 - 2017-02-14
+
+### Fixed
+
+- Support for non-readable streams. This fix was needed because flaws in Guzzle, Zend and Slims implementations of PSR-7. 
+
+## 0.1.4 - 2016-12-31
+
+### Added
+
+- Added support for resetting the builder
+
+## 0.1.3 - 2016-12-22
+
+### Added
+
+- Added `CustomMimetypeHelper` to allow you to configure custom mimetypes. 
+
+### Changed
+
+- Using regular expression instead of `basename($filename)` because basename is depending on locale.
+
+## 0.1.2 - 2016-08-31
+
+### Added
+
+- Support for Outlook msg files. 
+
+## 0.1.1 - 2016-08-10
+
+### Added
+
+- Support for Apple passbook. 
+
+## 0.1.0 - 2016-07-19
+
+### Added
+
+- Initial release
diff --git a/vendor/php-http/multipart-stream-builder/LICENSE b/vendor/php-http/multipart-stream-builder/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..8e2c4a0b85c31bf132105920cc90ba371025eb8a
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 PHP HTTP Team <team@php-http.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/multipart-stream-builder/README.md b/vendor/php-http/multipart-stream-builder/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..10ad0588b4b7e9a43e9eaced1ecda28c7b4cf372
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/README.md
@@ -0,0 +1,37 @@
+# PSR-7 Multipart Stream Builder
+
+[![Latest Version](https://img.shields.io/github/release/php-http/multipart-stream-builder.svg?style=flat-square)](https://github.com/php-http/multipart-stream-builder/releases)
+[![Build Status](https://img.shields.io/travis/php-http/multipart-stream-builder.svg?style=flat-square)](https://travis-ci.org/php-http/multipart-stream-builder)
+[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/php-http/multipart-stream-builder.svg?style=flat-square)](https://scrutinizer-ci.com/g/php-http/multipart-stream-builder)
+[![Quality Score](https://img.shields.io/scrutinizer/g/php-http/multipart-stream-builder.svg?style=flat-square)](https://scrutinizer-ci.com/g/php-http/multipart-stream-builder)
+[![Total Downloads](https://img.shields.io/packagist/dt/php-http/multipart-stream-builder.svg?style=flat-square)](https://packagist.org/packages/php-http/multipart-stream-builder)
+
+**A builder for Multipart PSR-7 Streams. The builder create streams independenly form any PSR-7 implementation.**
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/multipart-stream-builder
+```
+
+## Documentation
+
+Please see the [official documentation](http://php-http.readthedocs.org/en/latest/components/multipart-stream-builder.html).
+
+
+## Contributing
+
+Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.
+
+
+## Security
+
+If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org).
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/multipart-stream-builder/appveyor.yml b/vendor/php-http/multipart-stream-builder/appveyor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8d7af73f722812a369260d79a9078c2b01a02393
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/appveyor.yml
@@ -0,0 +1,39 @@
+build: false
+platform:
+  - x86
+  - x64
+
+clone_folder: c:\projects\php-http\multipart-stream-builder
+
+cache:
+  - c:\tools\php -> appveyor.yml
+
+init:
+  - SET PATH=c:\php;%PATH%
+  - SET COMPOSER_NO_INTERACTION=1
+  - SET PHP=1
+
+
+install:
+  - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
+  - cd c:\php
+  - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-7.0.0-nts-Win32-VC14-x86.zip
+  - IF %PHP%==1 7z x php-7.0.0-nts-Win32-VC14-x86.zip -y >nul
+  - IF %PHP%==1 del /Q *.zip
+  - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat
+  - IF %PHP%==1 copy /Y php.ini-development php.ini
+  - IF %PHP%==1 echo max_execution_time=1200 >> php.ini
+  - IF %PHP%==1 echo date.timezone="UTC" >> php.ini
+  - IF %PHP%==1 echo extension_dir=ext >> php.ini
+  - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini
+  - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini
+  - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini
+  - appveyor DownloadFile https://getcomposer.org/composer.phar
+  - cd c:\projects\php-http\multipart-stream-builder
+  - mkdir %APPDATA%\Composer
+  - composer update --prefer-dist --no-progress --ansi
+
+test_script:
+  - cd c:\projects\php-http\multipart-stream-builder
+  - vendor\bin\phpunit.bat --verbose
+
diff --git a/vendor/php-http/multipart-stream-builder/composer.json b/vendor/php-http/multipart-stream-builder/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ada3605c54bd13ede3523d86fd9ac8a4cb31fbd
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/composer.json
@@ -0,0 +1,43 @@
+{
+    "name": "php-http/multipart-stream-builder",
+    "description": "A builder class that help you create a multipart stream",
+    "license": "MIT",
+    "keywords": ["http", "factory", "message", "stream", "multipart stream"],
+    "homepage": "http://php-http.org",
+    "authors": [
+        {
+            "name": "Tobias Nyholm",
+            "email": "tobias.nyholm@gmail.com"
+        }
+    ],
+    "require": {
+        "php": "^5.5 || ^7.0",
+        "psr/http-message": "^1.0",
+        "php-http/message-factory": "^1.0.2",
+        "php-http/discovery": "^1.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^4.8 || ^5.4",
+        "php-http/message": "^1.5",
+        "zendframework/zend-diactoros": "^1.3.5"
+    },
+    "autoload": {
+        "psr-4": {
+            "Http\\Message\\MultipartStream\\": "src/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "tests\\Http\\Message\\MultipartStream\\": "tests/"
+        }
+    },
+    "scripts": {
+        "test": "vendor/bin/phpunit",
+        "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "0.3-dev"
+        }
+    }
+}
diff --git a/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e4ca660246f5fdc929ca455e3e30b1ddc6c639b
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace Http\Message\MultipartStream;
+
+/**
+ * This class helps to find the proper mime types. The source of this file is taken
+ * from Guzzle.
+ *
+ * @author Michael Dowling and contributors to guzzlehttp/psr7
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+class ApacheMimetypeHelper implements MimetypeHelper
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @see http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
+     */
+    public function getMimetypeFromFilename($filename)
+    {
+        return $this->getMimetypeFromExtension(pathinfo($filename, PATHINFO_EXTENSION));
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
+     */
+    public function getMimetypeFromExtension($extension)
+    {
+        static $mimetypes = [
+            '7z' => 'application/x-7z-compressed',
+            'aac' => 'audio/x-aac',
+            'ai' => 'application/postscript',
+            'aif' => 'audio/x-aiff',
+            'asc' => 'text/plain',
+            'asf' => 'video/x-ms-asf',
+            'atom' => 'application/atom+xml',
+            'avi' => 'video/x-msvideo',
+            'bmp' => 'image/bmp',
+            'bz2' => 'application/x-bzip2',
+            'cer' => 'application/pkix-cert',
+            'crl' => 'application/pkix-crl',
+            'crt' => 'application/x-x509-ca-cert',
+            'css' => 'text/css',
+            'csv' => 'text/csv',
+            'cu' => 'application/cu-seeme',
+            'deb' => 'application/x-debian-package',
+            'doc' => 'application/msword',
+            'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+            'dvi' => 'application/x-dvi',
+            'eot' => 'application/vnd.ms-fontobject',
+            'eps' => 'application/postscript',
+            'epub' => 'application/epub+zip',
+            'etx' => 'text/x-setext',
+            'flac' => 'audio/flac',
+            'flv' => 'video/x-flv',
+            'gif' => 'image/gif',
+            'gz' => 'application/gzip',
+            'htm' => 'text/html',
+            'html' => 'text/html',
+            'ico' => 'image/x-icon',
+            'ics' => 'text/calendar',
+            'ini' => 'text/plain',
+            'iso' => 'application/x-iso9660-image',
+            'jar' => 'application/java-archive',
+            'jpe' => 'image/jpeg',
+            'jpeg' => 'image/jpeg',
+            'jpg' => 'image/jpeg',
+            'js' => 'text/javascript',
+            'json' => 'application/json',
+            'latex' => 'application/x-latex',
+            'log' => 'text/plain',
+            'm4a' => 'audio/mp4',
+            'm4v' => 'video/mp4',
+            'mid' => 'audio/midi',
+            'midi' => 'audio/midi',
+            'mov' => 'video/quicktime',
+            'mp3' => 'audio/mpeg',
+            'mp4' => 'video/mp4',
+            'mp4a' => 'audio/mp4',
+            'mp4v' => 'video/mp4',
+            'mpe' => 'video/mpeg',
+            'mpeg' => 'video/mpeg',
+            'mpg' => 'video/mpeg',
+            'mpg4' => 'video/mp4',
+            'oga' => 'audio/ogg',
+            'ogg' => 'audio/ogg',
+            'ogv' => 'video/ogg',
+            'ogx' => 'application/ogg',
+            'pbm' => 'image/x-portable-bitmap',
+            'pdf' => 'application/pdf',
+            'pgm' => 'image/x-portable-graymap',
+            'png' => 'image/png',
+            'pnm' => 'image/x-portable-anymap',
+            'ppm' => 'image/x-portable-pixmap',
+            'ppt' => 'application/vnd.ms-powerpoint',
+            'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+            'ps' => 'application/postscript',
+            'qt' => 'video/quicktime',
+            'rar' => 'application/x-rar-compressed',
+            'ras' => 'image/x-cmu-raster',
+            'rss' => 'application/rss+xml',
+            'rtf' => 'application/rtf',
+            'sgm' => 'text/sgml',
+            'sgml' => 'text/sgml',
+            'svg' => 'image/svg+xml',
+            'swf' => 'application/x-shockwave-flash',
+            'tar' => 'application/x-tar',
+            'tif' => 'image/tiff',
+            'tiff' => 'image/tiff',
+            'torrent' => 'application/x-bittorrent',
+            'ttf' => 'application/x-font-ttf',
+            'txt' => 'text/plain',
+            'wav' => 'audio/x-wav',
+            'webm' => 'video/webm',
+            'wma' => 'audio/x-ms-wma',
+            'wmv' => 'video/x-ms-wmv',
+            'woff' => 'application/x-font-woff',
+            'wsdl' => 'application/wsdl+xml',
+            'xbm' => 'image/x-xbitmap',
+            'xls' => 'application/vnd.ms-excel',
+            'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+            'xml' => 'application/xml',
+            'xpm' => 'image/x-xpixmap',
+            'xwd' => 'image/x-xwindowdump',
+            'yaml' => 'text/yaml',
+            'yml' => 'text/yaml',
+            'zip' => 'application/zip',
+
+            // Non-Apache standard
+            'pkpass' => 'application/vnd.apple.pkpass',
+            'msg' => 'application/vnd.ms-outlook',
+        ];
+
+        $extension = strtolower($extension);
+
+        return isset($mimetypes[$extension])
+            ? $mimetypes[$extension]
+            : null;
+    }
+}
diff --git a/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f3f0d9211e563aeabcb59b6e34912de7ae1779e
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Http\Message\MultipartStream;
+
+/**
+ * Let you add your own mimetypes. The mimetype lookup will fallback on the ApacheMimeTypeHelper.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+class CustomMimetypeHelper extends ApacheMimetypeHelper
+{
+    /**
+     * @var array
+     */
+    private $mimetypes = [];
+
+    /**
+     * @param array $mimetypes should be of type extension => mimetype
+     */
+    public function __construct(array $mimetypes = [])
+    {
+        $this->mimetypes = $mimetypes;
+    }
+
+    /**
+     * @param string $extension
+     * @param string $mimetype
+     *
+     * @return $this
+     */
+    public function addMimetype($extension, $mimetype)
+    {
+        $this->mimetypes[$extension] = $mimetype;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * Check if we have any defined mimetypes and of not fallback to ApacheMimetypeHelper
+     */
+    public function getMimetypeFromExtension($extension)
+    {
+        $extension = strtolower($extension);
+
+        return isset($this->mimetypes[$extension])
+            ? $this->mimetypes[$extension]
+            : parent::getMimetypeFromExtension($extension);
+    }
+}
diff --git a/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa7cf18003720731c5391e572537fb42795802e4
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Http\Message\MultipartStream;
+
+/**
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+interface MimetypeHelper
+{
+    /**
+     * Determines the mimetype of a file by looking at its extension.
+     *
+     * @param string $filename
+     *
+     * @return null|string
+     */
+    public function getMimetypeFromFilename($filename);
+
+    /**
+     * Maps a file extensions to a mimetype.
+     *
+     * @param string $extension The file extension
+     *
+     * @return string|null
+     */
+    public function getMimetypeFromExtension($extension);
+}
diff --git a/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php b/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..3421d73487438866f3d037abfd041244927f8b50
--- /dev/null
+++ b/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php
@@ -0,0 +1,278 @@
+<?php
+
+namespace Http\Message\MultipartStream;
+
+use Http\Discovery\StreamFactoryDiscovery;
+use Http\Message\StreamFactory;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Build your own Multipart stream. A Multipart stream is a collection of streams separated with a $bounary. This
+ * class helps you to create a Multipart stream with stream implementations from any PSR7 library.
+ *
+ * @author Michael Dowling and contributors to guzzlehttp/psr7
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+class MultipartStreamBuilder
+{
+    /**
+     * @var StreamFactory
+     */
+    private $streamFactory;
+
+    /**
+     * @var MimetypeHelper
+     */
+    private $mimetypeHelper;
+
+    /**
+     * @var string
+     */
+    private $boundary;
+
+    /**
+     * @var array Element where each Element is an array with keys ['contents', 'headers', 'filename']
+     */
+    private $data = [];
+
+    /**
+     * @param StreamFactory|null $streamFactory
+     */
+    public function __construct(StreamFactory $streamFactory = null)
+    {
+        $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
+    }
+
+    /**
+     * Add a resource to the Multipart Stream.
+     *
+     * @param string                          $name     the formpost name
+     * @param string|resource|StreamInterface $resource
+     * @param array                           $options  {
+     *
+     *     @var array $headers additional headers ['header-name' => 'header-value']
+     *     @var string $filename
+     * }
+     *
+     * @return MultipartStreamBuilder
+     */
+    public function addResource($name, $resource, array $options = [])
+    {
+        $stream = $this->streamFactory->createStream($resource);
+
+        // validate options['headers'] exists
+        if (!isset($options['headers'])) {
+            $options['headers'] = [];
+        }
+
+        // Try to add filename if it is missing
+        if (empty($options['filename'])) {
+            $options['filename'] = null;
+            $uri = $stream->getMetadata('uri');
+            if (substr($uri, 0, 6) !== 'php://') {
+                $options['filename'] = $uri;
+            }
+        }
+
+        $this->prepareHeaders($name, $stream, $options['filename'], $options['headers']);
+        $this->data[] = ['contents' => $stream, 'headers' => $options['headers'], 'filename' => $options['filename']];
+
+        return $this;
+    }
+
+    /**
+     * Build the stream.
+     *
+     * @return StreamInterface
+     */
+    public function build()
+    {
+        $streams = '';
+        foreach ($this->data as $data) {
+            // Add start and headers
+            $streams .= "--{$this->getBoundary()}\r\n".
+                $this->getHeaders($data['headers'])."\r\n";
+
+            // Convert the stream to string
+            /* @var $contentStream StreamInterface */
+            $contentStream = $data['contents'];
+            if ($contentStream->isSeekable()) {
+                $streams .= $contentStream->__toString();
+            } else {
+                $streams .= $contentStream->getContents();
+            }
+
+            $streams .= "\r\n";
+        }
+
+        // Append end
+        $streams .= "--{$this->getBoundary()}--\r\n";
+
+        return $this->streamFactory->createStream($streams);
+    }
+
+    /**
+     * Add extra headers if they are missing.
+     *
+     * @param string          $name
+     * @param StreamInterface $stream
+     * @param string          $filename
+     * @param array           &$headers
+     */
+    private function prepareHeaders($name, StreamInterface $stream, $filename, array &$headers)
+    {
+        $hasFilename = $filename === '0' || $filename;
+
+        // Set a default content-disposition header if one was not provided
+        if (!$this->hasHeader($headers, 'content-disposition')) {
+            $headers['Content-Disposition'] = sprintf('form-data; name="%s"', $name);
+            if ($hasFilename) {
+                $headers['Content-Disposition'] .= sprintf('; filename="%s"', $this->basename($filename));
+            }
+        }
+
+        // Set a default content-length header if one was not provided
+        if (!$this->hasHeader($headers, 'content-length')) {
+            if ($length = $stream->getSize()) {
+                $headers['Content-Length'] = (string) $length;
+            }
+        }
+
+        // Set a default Content-Type if one was not provided
+        if (!$this->hasHeader($headers, 'content-type') && $hasFilename) {
+            if ($type = $this->getMimetypeHelper()->getMimetypeFromFilename($filename)) {
+                $headers['Content-Type'] = $type;
+            }
+        }
+    }
+
+    /**
+     * Get the headers formatted for the HTTP message.
+     *
+     * @param array $headers
+     *
+     * @return string
+     */
+    private function getHeaders(array $headers)
+    {
+        $str = '';
+        foreach ($headers as $key => $value) {
+            $str .= sprintf("%s: %s\r\n", $key, $value);
+        }
+
+        return $str;
+    }
+
+    /**
+     * Check if header exist.
+     *
+     * @param array  $headers
+     * @param string $key     case insensitive
+     *
+     * @return bool
+     */
+    private function hasHeader(array $headers, $key)
+    {
+        $lowercaseHeader = strtolower($key);
+        foreach ($headers as $k => $v) {
+            if (strtolower($k) === $lowercaseHeader) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the boundary that separates the streams.
+     *
+     * @return string
+     */
+    public function getBoundary()
+    {
+        if ($this->boundary === null) {
+            $this->boundary = uniqid('', true);
+        }
+
+        return $this->boundary;
+    }
+
+    /**
+     * @param string $boundary
+     *
+     * @return MultipartStreamBuilder
+     */
+    public function setBoundary($boundary)
+    {
+        $this->boundary = $boundary;
+
+        return $this;
+    }
+
+    /**
+     * @return MimetypeHelper
+     */
+    private function getMimetypeHelper()
+    {
+        if ($this->mimetypeHelper === null) {
+            $this->mimetypeHelper = new ApacheMimetypeHelper();
+        }
+
+        return $this->mimetypeHelper;
+    }
+
+    /**
+     * If you have custom file extension you may overwrite the default MimetypeHelper with your own.
+     *
+     * @param MimetypeHelper $mimetypeHelper
+     *
+     * @return MultipartStreamBuilder
+     */
+    public function setMimetypeHelper(MimetypeHelper $mimetypeHelper)
+    {
+        $this->mimetypeHelper = $mimetypeHelper;
+
+        return $this;
+    }
+
+    /**
+     * Reset and clear all stored data. This allows you to use builder for a subsequent request.
+     *
+     * @return MultipartStreamBuilder
+     */
+    public function reset()
+    {
+        $this->data = [];
+        $this->boundary = null;
+
+        return $this;
+    }
+
+    /**
+     * Gets the filename from a given path.
+     *
+     * PHP's basename() does not properly support streams or filenames beginning with a non-US-ASCII character.
+     *
+     * @author Drupal 8.2
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    private function basename($path)
+    {
+        $separators = '/';
+        if (DIRECTORY_SEPARATOR != '/') {
+            // For Windows OS add special separator.
+            $separators .= DIRECTORY_SEPARATOR;
+        }
+
+        // Remove right-most slashes when $path points to directory.
+        $path = rtrim($path, $separators);
+
+        // Returns the trailing part of the $path starting after one of the directory separators.
+        $filename = preg_match('@[^'.preg_quote($separators, '@').']+$@', $path, $matches) ? $matches[0] : '';
+
+        return $filename;
+    }
+}
diff --git a/vendor/respect/validation/docs/Age.md b/vendor/respect/validation/docs/Age.md
new file mode 100644
index 0000000000000000000000000000000000000000..740d7279b676e08c6062a1fdae87bc675fc6bbbc
--- /dev/null
+++ b/vendor/respect/validation/docs/Age.md
@@ -0,0 +1,46 @@
+# Age
+
+- `v::age(int $minAge)`
+- `v::age(int $minAge, int $maxAge)`
+- `v::age(null, int $maxAge)`
+
+Validates ranges of years.
+
+The validated values can be any date value; internally they will be transformed
+into [DateTime](http://php.net/manual/en/class.datetime.php) objects according
+to the defined locale settings.
+
+The examples below validate if the given dates are lower or equal to 18 years ago:
+```php
+v::age(18)->validate('17 years ago'); // false
+v::age(18)->validate('18 years ago'); // true
+v::age(18)->validate('19 years ago'); // true
+v::age(18)->validate('1970-01-01'); // true
+v::age(18)->validate('today'); // false
+```
+
+The examples below validate if the given dates are between 10 and 50 years ago:
+```php
+v::age(10, 50)->validate('9 years ago'); // false
+v::age(10, 50)->validate('10 years ago'); // true
+v::age(10, 50)->validate('30 years ago'); // true
+v::age(10, 50)->validate('50 years ago'); // true
+v::age(10, 50)->validate('51 years ago'); // false
+```
+
+The examples below validate if the given dates are greater than or equal to 70 years ago:
+```php
+v::age(null, 70)->validate('today'); // true
+v::age(null, 70)->validate('70 years ago'); // true
+v::age(null, 70)->validate('71 years ago'); // false
+```
+
+Message template for this validator includes `{{minAge}}` and `{{maxAge}}`.
+
+***
+See also:
+
+  * [Between](Between.md)
+  * [Date](Date.md)
+  * [Max](Max.md)
+  * [Min](Min.md)
diff --git a/vendor/respect/validation/docs/AllOf.md b/vendor/respect/validation/docs/AllOf.md
new file mode 100644
index 0000000000000000000000000000000000000000..7bd2ecf0203be63de28fd5a27c59f0eb7dbe8ddc
--- /dev/null
+++ b/vendor/respect/validation/docs/AllOf.md
@@ -0,0 +1,30 @@
+# AllOf
+
+- `v::allOf(v $v1, v $v2, v $v3...)`
+
+Will validate if all inner validators validates.
+
+```php
+v::allOf(
+    v::intVal(),
+    v::positive()
+)->validate(15); // true
+```
+
+This is similar to the chain (which is an allOf already), but
+its syntax allows you to set custom names for every node:
+
+```php
+v::allOf(
+    v::intVal()->setName('Account Number'),
+    v::positive()->setName('Higher Than Zero')
+)->setName('Positive integer')
+ ->validate(15); // true
+```
+
+***
+See also:
+
+  * [OneOf](OneOf.md)
+  * [NoneOf](NoneOf.md)
+  * [When](When.md)
diff --git a/vendor/respect/validation/docs/Alnum.md b/vendor/respect/validation/docs/Alnum.md
new file mode 100644
index 0000000000000000000000000000000000000000..184c1e2cfb64c88fc4ee5340077c6a22e8a3710c
--- /dev/null
+++ b/vendor/respect/validation/docs/Alnum.md
@@ -0,0 +1,44 @@
+# Alnum
+
+- `v::alnum()`
+- `v::alnum(string $additionalChars)`
+
+Validates alphanumeric characters from a-Z and 0-9.
+
+```php
+v::alnum()->validate('foo 123'); // true
+v::alnum()->validate('number 100%'); // false
+v::alnum('%')->validate('number 100%'); // true
+```
+
+Because this rule allows whitespaces by default, you can separate additional
+characters with a whitespace:
+
+```php
+v::alnum('- ! :')->validate('foo :- 123 !'); // true
+```
+
+This validator allows whitespace, if you want to
+remove them add `->noWhitespace()` to the chain:
+
+```php
+v::alnum()->noWhitespace()->validate('foo 123'); // false
+```
+
+You can restrict case using the `->lowercase()` and
+`->uppercase()` validators:
+
+```php
+v::alnum()->uppercase()->validate('aaa'); // false
+```
+
+Message template for this validator includes `{{additionalChars}}` as
+the string of extra chars passed as the parameter.
+
+***
+See also:
+
+  * [Alpha](Alpha.md)
+  * [Digit](Digit.md)
+  * [Consonant](Consonant.md)
+  * [Vowel](Vowel.md)
diff --git a/vendor/respect/validation/docs/Alpha.md b/vendor/respect/validation/docs/Alpha.md
new file mode 100644
index 0000000000000000000000000000000000000000..44f4dc3714c3ebfd64c46a9da17bfa8a91c091f4
--- /dev/null
+++ b/vendor/respect/validation/docs/Alpha.md
@@ -0,0 +1,14 @@
+# Alpha
+
+- `v::alpha()`
+- `v::alpha(string $additionalChars)`
+
+This is similar to `v::alnum()`, but it doesn't allow numbers.
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Digit](Digit.md)
+  * [Consonant](Consonant.md)
+  * [Vowel](Vowel.md)
diff --git a/vendor/respect/validation/docs/AlwaysInvalid.md b/vendor/respect/validation/docs/AlwaysInvalid.md
new file mode 100644
index 0000000000000000000000000000000000000000..34b364deb352ea110706b05ade042e04f0ee079f
--- /dev/null
+++ b/vendor/respect/validation/docs/AlwaysInvalid.md
@@ -0,0 +1,14 @@
+# AlwaysInvalid
+
+- `v::alwaysInvalid()`
+
+Always return false.
+
+```php
+v::alwaysInvalid()->validate($whatever); // false
+```
+
+***
+See also:
+
+  * [AlwaysValid](AlwaysValid.md)
diff --git a/vendor/respect/validation/docs/AlwaysValid.md b/vendor/respect/validation/docs/AlwaysValid.md
new file mode 100644
index 0000000000000000000000000000000000000000..6a020bb420dfde6d6fe61722c7a15bbccd39a0bd
--- /dev/null
+++ b/vendor/respect/validation/docs/AlwaysValid.md
@@ -0,0 +1,14 @@
+# AlwaysValid
+
+- `v::alwaysValid()`
+
+Always returns true.
+
+```php
+v::alwaysValid()->validate($whatever); // true
+```
+
+***
+See also:
+
+  * [AlwaysInvalid](AlwaysInvalid.md)
diff --git a/vendor/respect/validation/docs/ArrayType.md b/vendor/respect/validation/docs/ArrayType.md
new file mode 100644
index 0000000000000000000000000000000000000000..ed72eb393ccccd6ccfdb443b8c9c94891a5d7fa9
--- /dev/null
+++ b/vendor/respect/validation/docs/ArrayType.md
@@ -0,0 +1,27 @@
+# ArrayType
+
+- `v::arrayType()`
+
+Validates whether the type of an input is array.
+
+```php
+v::arrayType()->validate([]); // true
+v::arrayType()->validate([1, 2, 3]); // true
+v::arrayType()->validate(new ArrayObject()); // false
+```
+
+***
+See also:
+
+  * [ArrayVal](ArrayVal.md)
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [Countable](Countable.md)
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [IterableType](IterableType.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/ArrayVal.md b/vendor/respect/validation/docs/ArrayVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..ec9eaf066a3b42a0ea67dd7351b818bf828f0cd6
--- /dev/null
+++ b/vendor/respect/validation/docs/ArrayVal.md
@@ -0,0 +1,22 @@
+# ArrayVal
+
+- `v::arrayVal()`
+
+Validates if the input is an array or if the input can be used as an array
+(instance of `ArrayAccess`).
+
+```php
+v::arrayVal()->validate([]); // true
+v::arrayVal()->validate(new ArrayObject); // true
+```
+
+***
+See also:
+
+  * [ArrayType](ArrayType.md)
+  * [Countable](Countable.md)
+  * [Each](Each.md)
+  * [IterableType](IterableType.md)
+  * [Key](Key.md)
+  * [KeySet](KeySet.md)
+  * [KeyValue](KeyValue.md)
diff --git a/vendor/respect/validation/docs/Attribute.md b/vendor/respect/validation/docs/Attribute.md
new file mode 100644
index 0000000000000000000000000000000000000000..e48b6b664bb2c58027149a4870bacf6468659b4a
--- /dev/null
+++ b/vendor/respect/validation/docs/Attribute.md
@@ -0,0 +1,33 @@
+# Attribute
+
+- `v::attribute(string $name)`
+- `v::attribute(string $name, v $validator)`
+- `v::attribute(string $name, v $validator, boolean $mandatory = true)`
+
+Validates an object attribute.
+
+```php
+$obj = new stdClass;
+$obj->foo = 'bar';
+
+v::attribute('foo')->validate($obj); // true
+```
+
+You can also validate the attribute itself:
+
+```php
+v::attribute('foo', v::equals('bar'))->validate($obj); // true
+```
+
+Third parameter makes the attribute presence optional:
+
+```php
+v::attribute('lorem', v::stringType(), false)->validate($obj); // true
+```
+
+The name of this validator is automatically set to the attribute name.
+
+***
+See also:
+
+  * [Key](Key.md)
diff --git a/vendor/respect/validation/docs/Bank.md b/vendor/respect/validation/docs/Bank.md
new file mode 100644
index 0000000000000000000000000000000000000000..028d71985d50b871bffeb9a9889c0cd8d81b27f2
--- /dev/null
+++ b/vendor/respect/validation/docs/Bank.md
@@ -0,0 +1,20 @@
+# Bank
+
+- `v::bank(string $countryCode)`
+
+Validates a bank.
+
+```php
+v::bank("de")->validate("70169464"); // true
+v::bank("de")->validate("12345"); // false
+```
+
+These country codes are supported:
+
+ * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file.
+
+***
+See also:
+
+  * [BankAccount](BankAccount.md)
+  * [Bic](Bic.md)
diff --git a/vendor/respect/validation/docs/BankAccount.md b/vendor/respect/validation/docs/BankAccount.md
new file mode 100644
index 0000000000000000000000000000000000000000..f9d319d7f82c2ba7d6d681ab7f33ed43df3abfa4
--- /dev/null
+++ b/vendor/respect/validation/docs/BankAccount.md
@@ -0,0 +1,20 @@
+# BankAccount
+
+- `v::bankAccount(string $countryCode, string $bank)`
+
+Validates a bank account for a given bank.
+
+```php
+v::bankAccount("de", "70169464")->validate("1112"); // true
+v::bankAccount("de", "70169464")->validate("1234"); // false
+```
+
+These country codes are supported:
+
+ * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file.
+
+***
+See also:
+
+  * [Bank](Bank.md)
+  * [Bic](Bic.md)
diff --git a/vendor/respect/validation/docs/Between.md b/vendor/respect/validation/docs/Between.md
new file mode 100644
index 0000000000000000000000000000000000000000..5c0204afc9aed1fb1834d82d0050cb274b060152
--- /dev/null
+++ b/vendor/respect/validation/docs/Between.md
@@ -0,0 +1,44 @@
+# Between
+
+- `v::between(mixed $start, mixed $end)`
+- `v::between(mixed $start, mixed $end, boolean $inclusive = true)`
+
+Validates ranges. Most simple example:
+
+```php
+v::intVal()->between(10, 20)->validate(15); // true
+```
+
+The type as the first validator in a chain is a good practice,
+since between accepts many types:
+
+```php
+v::stringType()->between('a', 'f')->validate('c'); // true
+```
+
+Also very powerful with dates:
+
+```php
+v::date()->between('2009-01-01', '2013-01-01')->validate('2010-01-01'); // true
+```
+
+Date ranges accept strtotime values:
+
+```php
+v::date()->between('yesterday', 'tomorrow')->validate('now'); // true
+```
+
+A third parameter may be passed to validate the passed values inclusive:
+
+```php
+v::date()->between(10, 20, true)->validate(20); // true
+```
+
+Message template for this validator includes `{{minValue}}` and `{{maxValue}}`.
+
+***
+See also:
+
+  * [Length](Length.md)
+  * [Min](Min.md)
+  * [Max](Max.md)
diff --git a/vendor/respect/validation/docs/Bic.md b/vendor/respect/validation/docs/Bic.md
new file mode 100644
index 0000000000000000000000000000000000000000..82c67e8810a5caaadcd36cf798b35969935b1567
--- /dev/null
+++ b/vendor/respect/validation/docs/Bic.md
@@ -0,0 +1,20 @@
+# Bic
+
+- `v::bic(string $countryCode)`
+
+Validates a BIC (Bank Identifier Code) for a given country.
+
+```php
+v::bic("de")->validate("VZVDDED1XXX"); // true
+v::bic("de")->validate("VZVDDED1"); // true
+```
+
+Theses country codes are supported:
+
+ * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file.
+
+***
+See also:
+
+  * [Bank](Bank.md)
+  * [BankAccount](BankAccount.md)
diff --git a/vendor/respect/validation/docs/BoolType.md b/vendor/respect/validation/docs/BoolType.md
new file mode 100644
index 0000000000000000000000000000000000000000..979562189815b5d858b03e316120796971063de5
--- /dev/null
+++ b/vendor/respect/validation/docs/BoolType.md
@@ -0,0 +1,27 @@
+# BoolType
+
+- `v::boolType()`
+
+Validates if the input is a boolean value:
+
+```php
+v::boolType()->validate(true); // true
+v::boolType()->validate(false); // true
+```
+
+***
+See also:
+
+  * [ArrayType](ArrayType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [FloatVal](FloatVal.md)
+  * [IntType](IntType.md)
+  * [No](No.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [TrueVal](TrueVal.md)
+  * [Type](Type.md)
+  * [Yes](Yes.md)
diff --git a/vendor/respect/validation/docs/BoolVal.md b/vendor/respect/validation/docs/BoolVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..26bf9a6d0d137efdb9707647190daf17041886ba
--- /dev/null
+++ b/vendor/respect/validation/docs/BoolVal.md
@@ -0,0 +1,31 @@
+# BoolVal
+
+- `v::boolVal()`
+
+Validates if the input results in a boolean value:
+
+```php
+v::boolVal()->validate('on'); // true
+v::boolVal()->validate('off'); // true
+v::boolVal()->validate('yes'); // true
+v::boolVal()->validate('no'); // true
+v::boolVal()->validate(1); // true
+v::boolVal()->validate(0); // true
+```
+
+***
+See also:
+
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [FloatVal](FloatVal.md)
+  * [IntType](IntType.md)
+  * [No](No.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [TrueVal](TrueVal.md)
+  * [Type](Type.md)
+  * [Yes](Yes.md)
diff --git a/vendor/respect/validation/docs/Bsn.md b/vendor/respect/validation/docs/Bsn.md
new file mode 100644
index 0000000000000000000000000000000000000000..e67f55e70d22aeddfe110578ff0cd57ff05fb2e3
--- /dev/null
+++ b/vendor/respect/validation/docs/Bsn.md
@@ -0,0 +1,16 @@
+# Bsn
+
+- `v::bsn()`
+
+Validates a Dutch citizen service number ([BSN](https://nl.wikipedia.org/wiki/Burgerservicenummer)).
+
+```php
+v::bsn()->validate('612890053'); // true
+```
+
+***
+See also:
+
+  * [Cnh](Cnh.md)
+  * [Cnpj](Cnpj.md)
+  * [Cpf](Cpf.md)
diff --git a/vendor/respect/validation/docs/CONCRETE_API.md b/vendor/respect/validation/docs/CONCRETE_API.md
new file mode 100644
index 0000000000000000000000000000000000000000..735b6283d558ed32516a61b8ef6e5c87a2ee75da
--- /dev/null
+++ b/vendor/respect/validation/docs/CONCRETE_API.md
@@ -0,0 +1,77 @@
+# Concrete API
+
+There are many micro-frameworks that rely on magic methods. We don't. In this
+document we're gonna explore the Respect\Validation API without fluent interfaces
+or magic methods. We'll use a traditional dependency injection approach.
+
+```php
+use Respect\Validation\Validator as v;
+
+$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
+$usernameValidator->validate('alganet'); // true
+```
+
+If you `var_dump($usernameValidator)`, you'll see a composite of objects with
+`Respect\Validation\Rules\Alnum`, `Respect\Validation\Rules\NoWhitespace` and
+`Respect\Validation\Rules\Length`. There is a specific object for each rule, and
+the chain only builds the structure. You can build it by yourself:
+
+```php
+use Respect\Validation\Rules;
+
+$usernameValidator = new Rules\AllOf(
+    new Rules\Alnum(),
+    new Rules\NoWhitespace(),
+    new Rules\Length(1, 15)
+);
+$usernameValidator->validate('alganet'); // true
+```
+
+This is still a very lean API. You can use it in any dependency injection
+container or test it in the way you want. Nesting is still possible:
+
+```php
+use Respect\Validation\Rules;
+
+$usernameValidator = new Rules\AllOf(
+    new Rules\Alnum(),
+    new Rules\NoWhitespace(),
+    new Rules\Length(1, 15)
+);
+$userValidator = new Rules\Key('name', $usernameValidator);
+$userValidator->validate(['name' => 'alganet']); // true
+```
+
+## How It Works?
+
+The Respect\Validation chain is an
+[internal DSL](http://martinfowler.com/bliki/InternalDslStyle.html).
+It acts in the creational realm of objects (where Abstract Factories and Builders
+live), and it's only job is to make rule construction terse and fluent.
+
+## FAQ
+
+> Is `v` in `v::something` a class name?
+
+No! The class is `Respect\Validation\Validator`, we suggest `v` as a very short alias.
+
+> Is `v::something()` a static call?
+
+Yes. Just like the default `DateTime::createFromFormat()` or
+`Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration()`. It builds
+something complex and returns for you.
+
+> I really don't like static calls, can I avoid it?
+
+Yes. Just use `$validator = new Validator();` each time you want a new validator,
+and continue from there.
+
+> Do you have a static method for each rule?
+
+No. We use `__callStatic()`.
+
+> Magic methods are slow! Why do you use them?
+
+They're optional. If you use the `new` interface, they won't be called.
+
+(still, do some benchmarks, you'd be surprised with our implementation).
diff --git a/vendor/respect/validation/docs/Call.md b/vendor/respect/validation/docs/Call.md
new file mode 100644
index 0000000000000000000000000000000000000000..f56b0a8e5e73b80188026d98206c916ae0fe8969
--- /dev/null
+++ b/vendor/respect/validation/docs/Call.md
@@ -0,0 +1,51 @@
+# Call
+
+- `v::call(callable $callback)`
+
+This is a very low level validator. It calls a function, method or closure
+for the input and then validates it. Consider the following variable:
+
+```php
+$url = 'http://www.google.com/search?q=respect.github.com'
+```
+
+To validate every part of this URL we could use the native `parse_url`
+function to break its parts:
+
+```php
+$parts = parse_url($url);
+```
+
+This function returns an array containing `scheme`, `host`, `path` and `query`.
+We can validate them this way:
+
+```php
+v::arrayVal()->key('scheme', v::startsWith('http'))
+        ->key('host',   v::domain())
+        ->key('path',   v::stringType())
+        ->key('query',  v::notEmpty());
+```
+
+Using `v::call()` you can do this in a single chain:
+
+```php
+v::call(
+    'parse_url',
+     v::arrayVal()->key('scheme', v::startsWith('http'))
+        ->key('host',   v::domain())
+        ->key('path',   v::stringType())
+        ->key('query',  v::notEmpty())
+)->validate($url);
+```
+
+It is possible to call methods and closures as the first parameter:
+
+```php
+v::call([$myObj, 'methodName'], v::intVal())->validate($myInput);
+v::call(function($input) {}, v::intVal())->validate($myInput);
+```
+
+***
+See also:
+
+  * [Callback](Callback.md)
diff --git a/vendor/respect/validation/docs/CallableType.md b/vendor/respect/validation/docs/CallableType.md
new file mode 100644
index 0000000000000000000000000000000000000000..7f24dca7b0dfcbb4ae4591061d75f75793d35709
--- /dev/null
+++ b/vendor/respect/validation/docs/CallableType.md
@@ -0,0 +1,25 @@
+# CallableType
+
+- `v::callableType()`
+
+Validates if the input is a callable value.
+
+```php
+v::callableType()->validate(function () {}); // true
+v::callableType()->validate('trim'); // true
+v::callableType()->validate([new ObjectType, 'methodName']); // true
+```
+
+***
+See also:
+
+  * [ArrayType](ArrayType.md)
+  * [BoolType](BoolType.md)
+  * [Callback](Callback.md)
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Callback.md b/vendor/respect/validation/docs/Callback.md
new file mode 100644
index 0000000000000000000000000000000000000000..d5ec6b86c62bea13d0b8b1e999129775b67e20e2
--- /dev/null
+++ b/vendor/respect/validation/docs/Callback.md
@@ -0,0 +1,21 @@
+# Callback
+
+- `v::callback(callable $callback)`
+
+This is a wildcard validator, it uses a function name, method or closure
+to validate something:
+
+```php
+v::callback('is_int')->validate(10); // true
+```
+
+(Please note that this is a sample, the `v::intVal()` validator is much better).
+
+As in `v::call()`, you can pass a method or closure to it.
+
+***
+See also:
+
+  * [Call](Call.md)
+  * [CallableType](CallableType.md)
+  * [FilterVar](FilterVar.md)
diff --git a/vendor/respect/validation/docs/Charset.md b/vendor/respect/validation/docs/Charset.md
new file mode 100644
index 0000000000000000000000000000000000000000..43d889bdc687c4221eb82510f6fada2b39db8048
--- /dev/null
+++ b/vendor/respect/validation/docs/Charset.md
@@ -0,0 +1,19 @@
+# Charset
+
+- `v::charset(mixed $charset)`
+
+Validates if a string is in a specific charset.
+
+```php
+v::charset('ASCII')->validate('açúcar'); // false
+v::charset('ASCII')->validate('sugar');  //true
+v::charset(['ISO-8859-1', 'EUC-JP'])->validate('日本国'); // true
+```
+
+The array format is a logic OR, not AND.
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
diff --git a/vendor/respect/validation/docs/Cnh.md b/vendor/respect/validation/docs/Cnh.md
new file mode 100644
index 0000000000000000000000000000000000000000..6815929a3910d537c8e5131828dd68fd176d9d29
--- /dev/null
+++ b/vendor/respect/validation/docs/Cnh.md
@@ -0,0 +1,15 @@
+# Cnh
+
+- `v::cnh()`
+
+Validates a Brazillian driver's license.
+
+```php
+v::cnh()->validate('02650306461'); // true
+```
+
+***
+See also:
+
+  * [Cnpj](Cnpj.md)
+  * [Cpf](Cpf.md)
diff --git a/vendor/respect/validation/docs/Cnpj.md b/vendor/respect/validation/docs/Cnpj.md
new file mode 100644
index 0000000000000000000000000000000000000000..846d391762c2523cc527c61829c227ea3909f502
--- /dev/null
+++ b/vendor/respect/validation/docs/Cnpj.md
@@ -0,0 +1,12 @@
+# Cnpj
+
+- `v::cnpj()`
+
+Validates the Brazillian CNPJ number. Ignores non-digit chars, so
+use `->digit()` if needed.
+
+***
+See also:
+
+  * [Cpf](Cpf.md)
+  * [Cnh](Cnh.md)
diff --git a/vendor/respect/validation/docs/Cntrl.md b/vendor/respect/validation/docs/Cntrl.md
new file mode 100644
index 0000000000000000000000000000000000000000..7a6552aa8e0529dcbc08cd4017f9bd65434a1dc2
--- /dev/null
+++ b/vendor/respect/validation/docs/Cntrl.md
@@ -0,0 +1,17 @@
+# Cntrl
+
+- `v::cntrl()`
+- `v::cntrl(string $additionalChars)`
+
+This is similar to `v::alnum()`, but only accepts control characters:
+
+```php
+v::cntrl()->validate("\n\r\t"); // true
+```
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Prnt](Prnt.md)
+  * [Space](Space.md)
diff --git a/vendor/respect/validation/docs/Consonant.md b/vendor/respect/validation/docs/Consonant.md
new file mode 100644
index 0000000000000000000000000000000000000000..fac1fe53319d7ba5afe0f39aef44f4116a1b6c71
--- /dev/null
+++ b/vendor/respect/validation/docs/Consonant.md
@@ -0,0 +1,18 @@
+# Consonant
+
+- `v::consonant()`
+- `v::consonant(string $additionalChars)`
+
+Similar to `v::alnum()`. Validates strings that contain only consonants:
+
+```php
+v::consonant()->validate('xkcd'); // true
+```
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Digit](Digit.md)
+  * [Alpha](Alpha.md)
+  * [Vowel](Vowel.md)
diff --git a/vendor/respect/validation/docs/Contains.md b/vendor/respect/validation/docs/Contains.md
new file mode 100644
index 0000000000000000000000000000000000000000..6036494fe43cbbb06015a2e7edcc9fd4871d6d00
--- /dev/null
+++ b/vendor/respect/validation/docs/Contains.md
@@ -0,0 +1,28 @@
+# Contains
+
+- `v::contains(mixed $value)`
+- `v::contains(mixed $value, boolean $identical = false)`
+
+For strings:
+
+```php
+v::contains('ipsum')->validate('lorem ipsum'); // true
+```
+
+For arrays:
+
+```php
+v::contains('ipsum')->validate(['ipsum', 'lorem']); // true
+```
+
+A second parameter may be passed for identical comparison instead
+of equal comparison.
+
+Message template for this validator includes `{{containsValue}}`.
+
+***
+See also:
+
+  * [StartsWith](StartsWith.md)
+  * [EndsWith](EndsWith.md)
+  * [In](In.md)
diff --git a/vendor/respect/validation/docs/Countable.md b/vendor/respect/validation/docs/Countable.md
new file mode 100644
index 0000000000000000000000000000000000000000..0353de4d7a748ed9f490149b8f07d1343f084036
--- /dev/null
+++ b/vendor/respect/validation/docs/Countable.md
@@ -0,0 +1,19 @@
+# Countable
+
+- `v::countable()`
+
+Validates if the input is countable, in other words, if you're allowed to use
+[count()](http://php.net/count) function on it.
+
+```php
+v::countable()->validate([]); // true
+v::countable()->validate(new ArrayObject()); // true
+v::countable()->validate('string'); // false
+```
+
+***
+See also:
+
+  * [ArrayVal](ArrayVal.md)
+  * [Instance](Instance.md)
+  * [IterableType](IterableType.md)
diff --git a/vendor/respect/validation/docs/CountryCode.md b/vendor/respect/validation/docs/CountryCode.md
new file mode 100644
index 0000000000000000000000000000000000000000..469313db2dcb66a7306d53510b54c136afa758a8
--- /dev/null
+++ b/vendor/respect/validation/docs/CountryCode.md
@@ -0,0 +1,14 @@
+# CountryCode
+
+- `v::countryCode()`
+
+Validates an ISO country code like US or BR.
+
+```php
+v::countryCode()->validate('BR'); // true
+```
+
+***
+See also:
+
+  * [Tld](Tld.md)
diff --git a/vendor/respect/validation/docs/Cpf.md b/vendor/respect/validation/docs/Cpf.md
new file mode 100644
index 0000000000000000000000000000000000000000..0fc3a717af13febc2d111218e534d9f61271e037
--- /dev/null
+++ b/vendor/respect/validation/docs/Cpf.md
@@ -0,0 +1,28 @@
+# Cpf
+
+- `v::cpf()`
+
+Validates a Brazillian CPF number.
+
+```php
+v::cpf()->validate('44455566820'); // true
+```
+
+It ignores any non-digit char:
+
+```php
+v::cpf()->validate('444.555.668-20'); // true
+```
+
+If you need to validate digits only, add `->digit()` to
+the chain:
+
+```php
+v::digit()->cpf()->validate('44455566820'); // true
+```
+
+***
+See also:
+
+  * [Cnpj](Cnpj.md)
+  * [Cnh](Cnh.md)
diff --git a/vendor/respect/validation/docs/CreditCard.md b/vendor/respect/validation/docs/CreditCard.md
new file mode 100644
index 0000000000000000000000000000000000000000..aa9783a23304444b5871f7965eec499ec9de7408
--- /dev/null
+++ b/vendor/respect/validation/docs/CreditCard.md
@@ -0,0 +1,39 @@
+# CreditCard
+
+- `v::creditCard()`
+- `v::creditCard(string $brand)`
+
+Validates a credit card number.
+
+```php
+v::creditCard()->validate('5376 7473 9720 8720'); // true
+
+v::creditCard('American Express')->validate('340316193809364'); // true
+v::creditCard('Diners Club')->validate('30351042633884'); // true
+v::creditCard('Discover')->validate('6011000990139424'); // true
+v::creditCard('JCB')->validate('3566002020360505'); // true
+v::creditCard('Master')->validate('5376747397208720'); // true
+v::creditCard('Visa')->validate('4024007153361885'); // true
+```
+
+The current supported brands are:
+
+- American Express
+- Diners Club
+- Discover
+- JCB
+- MasterCard
+- Visa
+
+It ignores any non-digit chars, so use `->digit()` when appropriate.
+
+```php
+v::digit()->creditCard()->validate('5376747397208720'); // true
+```
+
+***
+See also:
+
+  * [Bank](Bank.md)
+  * [BankAccount](BankAccount.md)
+  * [Bic](Bic.md)
diff --git a/vendor/respect/validation/docs/CurrencyCode.md b/vendor/respect/validation/docs/CurrencyCode.md
new file mode 100644
index 0000000000000000000000000000000000000000..95c13fae47325b977071590ec7304b7afdd5b3b6
--- /dev/null
+++ b/vendor/respect/validation/docs/CurrencyCode.md
@@ -0,0 +1,15 @@
+# CurrencyCode
+
+- `v::currencyCode()`
+
+Validates an [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code like GBP or EUR.
+
+```php
+v::currencyCode()->validate('GBP'); // true
+```
+
+***
+See also:
+
+  * [CountryCode](CountryCode.md)
+  * [SubdivisionCode](SubdivisionCode.md)
diff --git a/vendor/respect/validation/docs/Date.md b/vendor/respect/validation/docs/Date.md
new file mode 100644
index 0000000000000000000000000000000000000000..4afb9ecbd56a4b49614375508f38bc18cb1b5170
--- /dev/null
+++ b/vendor/respect/validation/docs/Date.md
@@ -0,0 +1,40 @@
+# Date
+
+- `v::date()`
+- `v::date(string $format)`
+
+Validates if input is a date:
+
+```php
+v::date()->validate('2009-01-01'); // true
+```
+
+Also accepts strtotime values:
+
+```php
+v::date()->validate('now'); // true
+```
+
+And DateTime instances:
+
+```php
+v::date()->validate(new DateTime); // true
+```
+
+You can pass a format when validating strings:
+
+```php
+v::date('Y-m-d')->validate('01-01-2009'); // false
+```
+
+Format has no effect when validating DateTime instances.
+
+Message template for this validator includes `{{format}}`.
+
+***
+See also:
+
+  * [Between](Between.md)
+  * [MinimumAge](MinimumAge.md)
+  * [LeapDate](LeapDate.md)
+  * [LeapYear](LeapYear.md)
diff --git a/vendor/respect/validation/docs/Digit.md b/vendor/respect/validation/docs/Digit.md
new file mode 100644
index 0000000000000000000000000000000000000000..c4638483f4d6734817263c9891263a1ea2d41deb
--- /dev/null
+++ b/vendor/respect/validation/docs/Digit.md
@@ -0,0 +1,13 @@
+# Digit
+
+- `v::digit()`
+
+This is similar to `v::alnum()`, but it doesn't allow a-Z.
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
+  * [Vowel](Vowel.md)
+  * [Consonant](Consonant.md)
diff --git a/vendor/respect/validation/docs/Directory.md b/vendor/respect/validation/docs/Directory.md
new file mode 100644
index 0000000000000000000000000000000000000000..7d49c63b726e0bec8c8d615092d3ed7ce275755c
--- /dev/null
+++ b/vendor/respect/validation/docs/Directory.md
@@ -0,0 +1,30 @@
+# Directory
+
+- `v::directory()`
+
+Validates directories.
+
+```php
+v::directory()->validate(__DIR__); // true
+v::directory()->validate(__FILE__); // false
+```
+
+This validator will consider SplFileInfo instances, so you can do something like:
+
+```php
+v::directory()->validate(new \SplFileInfo($directory));
+```
+
+***
+See also:
+
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Domain.md b/vendor/respect/validation/docs/Domain.md
new file mode 100644
index 0000000000000000000000000000000000000000..ac5d76a7b77d89952de912a75c614fa3479f99aa
--- /dev/null
+++ b/vendor/respect/validation/docs/Domain.md
@@ -0,0 +1,40 @@
+# Domain
+
+- `v::domain()`
+- `v::domain(boolean $tldCheck = true)`
+
+Validates domain names.
+
+```php
+v::domain()->validate('google.com');
+```
+
+You can skip *top level domain* (TLD) checks to validate internal
+domain names:
+
+```php
+v::domain(false)->validate('dev.machine.local');
+```
+
+This is a composite validator, it validates several rules
+internally:
+
+  * If input is an IP address, it fails.
+  * If input contains whitespace, it fails.
+  * If input does not contain any dots, it fails.
+  * If input has less than two parts, it fails.
+  * Input must end with a top-level-domain to pass (if not skipped).
+  * Each part must be alphanumeric and not start with an hyphen.
+  * [PunnyCode][] is accepted for [Internationalizing Domain Names in Applications][IDNA].
+
+Messages for this validator will reflect rules above.
+
+***
+See also:
+
+  * [Ip](Ip.md)
+  * [MacAddress](MacAddress.md)
+  * [Tld](Tld.md)
+
+[PunnyCode]: http://en.wikipedia.org/wiki/Punycode "Wikipedia: Punnycode"
+[IDNA]: http://en.wikipedia.org/wiki/Internationalized_domain_name#Internationalizing_Domain_Names_in_Applications "Wikipedia: Internationalized domain name"
diff --git a/vendor/respect/validation/docs/Each.md b/vendor/respect/validation/docs/Each.md
new file mode 100644
index 0000000000000000000000000000000000000000..ecc1c666359e921a9a33cdebe1a2c3ee5a6c4a92
--- /dev/null
+++ b/vendor/respect/validation/docs/Each.md
@@ -0,0 +1,27 @@
+# Each
+
+- `v::each(v $validatorForValue)`
+- `v::each(null, v $validatorForKey)`
+- `v::each(v $validatorForValue, v $validatorForKey)`
+
+Iterates over an array or Iterator and validates the value or key
+of each entry:
+
+```php
+$releaseDates = [
+    'validation' => '2010-01-01',
+    'template'   => '2011-01-01',
+    'relational' => '2011-02-05',
+];
+
+v::arrayVal()->each(v::date())->validate($releaseDates); // true
+v::arrayVal()->each(v::date(), v::stringType()->lowercase())->validate($releaseDates); // true
+```
+
+Using `arrayVal()` before `each()` is a best practice.
+
+***
+See also:
+
+  * [Key](Key.md)
+  * [ArrayVal](ArrayVal.md)
diff --git a/vendor/respect/validation/docs/Email.md b/vendor/respect/validation/docs/Email.md
new file mode 100644
index 0000000000000000000000000000000000000000..64a4d7cf3c4896dd1786e20c99b74bd89adbf184
--- /dev/null
+++ b/vendor/respect/validation/docs/Email.md
@@ -0,0 +1,16 @@
+# Email
+
+- `v::email()`
+
+Validates an email address.
+
+```php
+v::email()->validate('alexandre@gaigalas.net'); // true
+```
+
+***
+See also:
+
+  * [Phone](Phone.md)
+  * [Url](Url.md)
+  * [VideoUrl](VideoUrl.md)
diff --git a/vendor/respect/validation/docs/EndsWith.md b/vendor/respect/validation/docs/EndsWith.md
new file mode 100644
index 0000000000000000000000000000000000000000..99ec5b215a194760e80132ea1083bd791b903b0e
--- /dev/null
+++ b/vendor/respect/validation/docs/EndsWith.md
@@ -0,0 +1,31 @@
+# EndsWith
+
+- `v::endsWith(mixed $value)`
+- `v::endsWith(mixed $value, boolean $identical = false)`
+
+This validator is similar to `v::contains()`, but validates
+only if the value is at the end of the input.
+
+For strings:
+
+```php
+v::endsWith('ipsum')->validate('lorem ipsum'); // true
+```
+
+For arrays:
+
+```php
+v::endsWith('ipsum')->validate(['lorem', 'ipsum']); // true
+```
+
+A second parameter may be passed for identical comparison instead
+of equal comparison.
+
+Message template for this validator includes `{{endValue}}`.
+
+***
+See also:
+
+  * [StartsWith](StartsWith.md)
+  * [Contains](Contains.md)
+  * [In](In.md)
diff --git a/vendor/respect/validation/docs/Equals.md b/vendor/respect/validation/docs/Equals.md
new file mode 100644
index 0000000000000000000000000000000000000000..e28f783dfcfd4128c7eecba94307e4ae53aeff1c
--- /dev/null
+++ b/vendor/respect/validation/docs/Equals.md
@@ -0,0 +1,17 @@
+# Equals
+
+- `v::equals(mixed $value)`
+
+Validates if the input is equal to some value.
+
+```php
+v::equals('alganet')->validate('alganet'); // true
+```
+
+Message template for this validator includes `{{compareTo}}`.
+
+***
+See also:
+
+  * [Contains](Contains.md)
+  * [Identical](Identical.md)
diff --git a/vendor/respect/validation/docs/Even.md b/vendor/respect/validation/docs/Even.md
new file mode 100644
index 0000000000000000000000000000000000000000..da52597b85c0793e85862dd42611df0f4da6a7cd
--- /dev/null
+++ b/vendor/respect/validation/docs/Even.md
@@ -0,0 +1,17 @@
+# Even
+
+- `v::even()`
+
+Validates an even number.
+
+```php
+v::intVal()->even()->validate(2); // true
+```
+
+Using `int()` before `even()` is a best practice.
+
+***
+See also:
+
+  * [Odd](Odd.md)
+  * [Multiple](Multiple.md)
diff --git a/vendor/respect/validation/docs/Executable.md b/vendor/respect/validation/docs/Executable.md
new file mode 100644
index 0000000000000000000000000000000000000000..7c1e1303dc350d4034dc1f8c6454e835943187e2
--- /dev/null
+++ b/vendor/respect/validation/docs/Executable.md
@@ -0,0 +1,23 @@
+# Executable
+
+- `v::executable()`
+
+Validates if a file is an executable.
+
+```php
+v::email()->executable('script.sh'); // true
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Exists.md b/vendor/respect/validation/docs/Exists.md
new file mode 100644
index 0000000000000000000000000000000000000000..681c50743b70cd7b36548571ca47ae2d51cc4075
--- /dev/null
+++ b/vendor/respect/validation/docs/Exists.md
@@ -0,0 +1,30 @@
+# Exists
+
+- `v::exists()`
+
+Validates files or directories.
+
+```php
+v::exists()->validate(__FILE__); // true
+v::exists()->validate(__DIR__); // true
+```
+
+This validator will consider SplFileInfo instances, so you can do something like:
+
+```php
+v::exists()->validate(new \SplFileInfo($file));
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Extension.md b/vendor/respect/validation/docs/Extension.md
new file mode 100644
index 0000000000000000000000000000000000000000..4abc0d5ba51f701827dd166daac098ec79c65e3f
--- /dev/null
+++ b/vendor/respect/validation/docs/Extension.md
@@ -0,0 +1,25 @@
+# Extension
+
+- `v::extension(string $extension)`
+
+Validates if the file extension matches the expected one:
+
+```php
+v::extension('png')->validate('image.png'); // true
+```
+
+This rule is case-sensitive.
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Factor.md b/vendor/respect/validation/docs/Factor.md
new file mode 100644
index 0000000000000000000000000000000000000000..1e04276432d1bc8583fa89da6c004d43abdb2568
--- /dev/null
+++ b/vendor/respect/validation/docs/Factor.md
@@ -0,0 +1,19 @@
+# Factor
+
+- `v::factor(int $dividend)`
+
+Validates if the input is a factor of the defined dividend.
+
+```php
+v::factor(0)->validate(5); // true
+v::factor(4)->validate(2); // true
+v::factor(4)->validate(3); // false
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Finite](Finite.md)
+  * [Infinite](Infinite.md)
+  * [Numeric](Numeric.md)
diff --git a/vendor/respect/validation/docs/FalseVal.md b/vendor/respect/validation/docs/FalseVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..6ca060d33ca40dd587efb0e4583b7606b1000f03
--- /dev/null
+++ b/vendor/respect/validation/docs/FalseVal.md
@@ -0,0 +1,21 @@
+# FalseVal
+
+- `v::falseVal()`
+
+Validates if a value is considered as `false`.
+
+```php
+v::falseVal()->validate(false); // true
+v::falseVal()->validate(0); // true
+v::falseVal()->validate('0'); // true
+v::falseVal()->validate('false'); // true
+v::falseVal()->validate('off'); // true
+v::falseVal()->validate('no'); // true
+v::falseVal()->validate('0.5'); // false
+v::falseVal()->validate('2'); // false
+```
+
+***
+See also:
+
+  * [TrueVal](TrueVal.md)
diff --git a/vendor/respect/validation/docs/Fibonacci.md b/vendor/respect/validation/docs/Fibonacci.md
new file mode 100644
index 0000000000000000000000000000000000000000..fe8c5235b775e98fda3c81e43f1736e7e18dc30f
--- /dev/null
+++ b/vendor/respect/validation/docs/Fibonacci.md
@@ -0,0 +1,17 @@
+# Fibonacci
+
+ - `v::fibonacci()`
+
+Validates whether the input follows the Fibonacci integer sequence.
+
+```php
+v::fibonacci()->validate(1); // true
+v::fibonacci()->validate('34'); // true
+v::fibonacci()->validate(6); // false
+```
+
+***
+See also:
+
+  * [PrimeNumber](PrimeNumber.md)
+  * [PerfectSquare](PerfectSquare.md)
\ No newline at end of file
diff --git a/vendor/respect/validation/docs/File.md b/vendor/respect/validation/docs/File.md
new file mode 100644
index 0000000000000000000000000000000000000000..8454d0258d2d1922fc5105c71f1e6ea3a3ab28fb
--- /dev/null
+++ b/vendor/respect/validation/docs/File.md
@@ -0,0 +1,30 @@
+# File
+
+- `v::file()`
+
+Validates files.
+
+```php
+v::file()->validate(__FILE__); // true
+v::file()->validate(__DIR__); // false
+```
+
+This validator will consider SplFileInfo instances, so you can do something like:
+
+```php
+v::file()->validate(new \SplFileInfo($file));
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/FilterVar.md b/vendor/respect/validation/docs/FilterVar.md
new file mode 100644
index 0000000000000000000000000000000000000000..a13d4fa091ffab6afb9a9df90b13d9adba374d64
--- /dev/null
+++ b/vendor/respect/validation/docs/FilterVar.md
@@ -0,0 +1,18 @@
+# FilterVar
+
+- `v::filterVar(int $filter)`
+- `v::filterVar(int $filter, mixed $options)`
+
+A wrapper for PHP's [filter_var()](http://php.net/filter_var) function.
+
+```php
+v::filterVar(FILTER_VALIDATE_EMAIL)->validate('bob@example.com'); // true
+v::filterVar(FILTER_VALIDATE_URL)->validate('http://example.com'); // true
+v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->validate('http://example.com'); // false
+v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->validate('http://example.com/path'); // true
+```
+
+***
+See also:
+
+  * [Callback](Callback.md)
diff --git a/vendor/respect/validation/docs/Finite.md b/vendor/respect/validation/docs/Finite.md
new file mode 100644
index 0000000000000000000000000000000000000000..42ef9f30d6d833305e0140c368d87694dd9b887c
--- /dev/null
+++ b/vendor/respect/validation/docs/Finite.md
@@ -0,0 +1,18 @@
+# Finite
+
+- `v::finite()`
+
+Validates if the input is a finite number.
+
+```php
+v::finite()->validate('10'); // true
+v::finite()->validate(10); // true
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Infinite](Infinite.md)
+  * [IntVal](IntVal.md)
+  * [Numeric](Numeric.md)
diff --git a/vendor/respect/validation/docs/FloatType.md b/vendor/respect/validation/docs/FloatType.md
new file mode 100644
index 0000000000000000000000000000000000000000..87efee83511a971477a7ec4ca2f84fc4ab81dbcc
--- /dev/null
+++ b/vendor/respect/validation/docs/FloatType.md
@@ -0,0 +1,25 @@
+# FloatType
+
+- `v::floatType()`
+
+Validates whether the type of a value is float.
+
+```php
+v::floatType()->validate(1.5); // true
+v::floatType()->validate('1.5'); // false
+v::floatType()->validate(0e5); // true
+```
+
+***
+See also:
+
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatVal](FloatVal.md)
+  * [IntType](IntType.md)
+  * [IntVal](IntVal.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/FloatVal.md b/vendor/respect/validation/docs/FloatVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..f73c2fc073094600820a00cba34c34ec6c378bd3
--- /dev/null
+++ b/vendor/respect/validation/docs/FloatVal.md
@@ -0,0 +1,17 @@
+# FloatVal
+
+- `v::floatVal()`
+
+Validates a floating point number.
+
+```php
+v::floatVal()->validate(1.5); // true
+v::floatVal()->validate('1e5'); // true
+```
+
+***
+See also:
+
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [IntVal](IntVal.md)
diff --git a/vendor/respect/validation/docs/Graph.md b/vendor/respect/validation/docs/Graph.md
new file mode 100644
index 0000000000000000000000000000000000000000..2c7503ad785414e4459968261f12b844a93db206
--- /dev/null
+++ b/vendor/respect/validation/docs/Graph.md
@@ -0,0 +1,15 @@
+# Graph
+
+- `v::graph()`
+- `v::graph(string $additionalChars)`
+
+Validates all characters that are graphically represented.
+
+```php
+v::graph()->validate('LKM@#$%4;'); // true
+```
+
+***
+See also:
+
+  * [Prnt](Prnt.md)
diff --git a/vendor/respect/validation/docs/HexRgbColor.md b/vendor/respect/validation/docs/HexRgbColor.md
new file mode 100644
index 0000000000000000000000000000000000000000..3e4a1e98d9e538d3f90f4aa2f25ab88e85bfaf8e
--- /dev/null
+++ b/vendor/respect/validation/docs/HexRgbColor.md
@@ -0,0 +1,16 @@
+# HexRgbColor
+
+- `v::hexRgbColor()`
+
+Validates a hex RGB color
+
+```php
+v::hexRgbColor()->validate('#FFFAAA'); // true
+v::hexRgbColor()->validate('123123'); // true
+v::hexRgbColor()->validate('FCD'); // true
+```
+
+***
+See also:
+
+  * [Vxdigit](Vxdigit.md)
diff --git a/vendor/respect/validation/docs/INSTALL.md b/vendor/respect/validation/docs/INSTALL.md
new file mode 100644
index 0000000000000000000000000000000000000000..9cf5efb04d0ebe5d4200890e6af78c7aa90f829d
--- /dev/null
+++ b/vendor/respect/validation/docs/INSTALL.md
@@ -0,0 +1,18 @@
+# Installation
+
+Package is available on [Packagist](http://packagist.org/packages/respect/validation),
+you can install it using [Composer](http://getcomposer.org).
+
+```shell
+composer require respect/validation
+```
+
+[PHP](https://php.net) 5.4+ or [HHVM](http://hhvm.com) 3.3+ are required.
+
+***
+See also:
+
+- [Contributing](../CONTRIBUTING.md)
+- [Feature Guide](README.md)
+- [License](../LICENSE.md)
+- [Validators](VALIDATORS.md)
diff --git a/vendor/respect/validation/docs/Identical.md b/vendor/respect/validation/docs/Identical.md
new file mode 100644
index 0000000000000000000000000000000000000000..0a280678abbaa25cb0749d159cf47b5b117d7793
--- /dev/null
+++ b/vendor/respect/validation/docs/Identical.md
@@ -0,0 +1,18 @@
+# Identical
+
+- `v::identical(mixed $value)`
+
+Validates if the input is identical to some value.
+
+```php
+v::identical(42)->validate(42); // true
+v::identical(42)->validate('42'); // false
+```
+
+Message template for this validator includes `{{compareTo}}`.
+
+***
+See also:
+
+  * [Contains](Contains.md)
+  * [Equals](Equals.md)
diff --git a/vendor/respect/validation/docs/IdentityCard.md b/vendor/respect/validation/docs/IdentityCard.md
new file mode 100644
index 0000000000000000000000000000000000000000..052eca1a28fd616d8538eae8d56d50cc2042a729
--- /dev/null
+++ b/vendor/respect/validation/docs/IdentityCard.md
@@ -0,0 +1,21 @@
+# IdentityCard
+
+- `v::identityCard(string $countryCode)`
+
+Validates Identity Card numbers according to the defined country.
+
+```php
+v::identityCard('PL')->validate('AYW036733'); // true
+v::identityCard('PL')->validate('APH505567'); // true
+v::identityCard('PL')->validate('APH 505567'); // false
+v::identityCard('PL')->validate('AYW036731'); // false
+```
+
+For now this rule only accepts Polish Identity Card numbers (Dowód Osobisty).
+
+***
+See also:
+
+  * [Bank](Bank.md)
+  * [Pesel](Pesel.md)
+  * [SubdivisionCode](SubdivisionCode.md)
diff --git a/vendor/respect/validation/docs/Image.md b/vendor/respect/validation/docs/Image.md
new file mode 100644
index 0000000000000000000000000000000000000000..5a84facf66d6e3f41314691b25d1fee0db21c383
--- /dev/null
+++ b/vendor/respect/validation/docs/Image.md
@@ -0,0 +1,32 @@
+# Image
+
+- `v::image()`
+- `v::image(finfo $fileInfo)`
+
+Validates if the file is a valid image by checking its MIME type.
+
+```php
+v::image()->validate('image.gif'); // true
+v::image()->validate('image.jpg'); // true
+v::image()->validate('image.png'); // true
+```
+
+All the validations above must return `false` if the input is not a valid file
+or of the MIME doesn't match with the file extension.
+
+This rule relies on [fileinfo](http://php.net/fileinfo) PHP extension.
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Imei.md b/vendor/respect/validation/docs/Imei.md
new file mode 100644
index 0000000000000000000000000000000000000000..96ed8e0a2a9fd0175165d0c7dd96bdee6ae8d76b
--- /dev/null
+++ b/vendor/respect/validation/docs/Imei.md
@@ -0,0 +1,20 @@
+# Imei
+
+- `v::imei()`
+
+Validates is the input is a valid [IMEI][].
+
+```php
+v::imei()->validate('35-209900-176148-1'); // true
+v::imei()->validate('490154203237518'); // true
+```
+
+***
+See also:
+
+  * [Bsn](Bsn.md)
+  * [Cnh](Cnh.md)
+  * [Cnpj](Cnpj.md)
+  * [Cpf](Cpf.md)
+
+[IMEI]: https://en.wikipedia.org/wiki/International_Mobile_Station_Equipment_Identity "International Mobile Station Equipment Identity"
diff --git a/vendor/respect/validation/docs/In.md b/vendor/respect/validation/docs/In.md
new file mode 100644
index 0000000000000000000000000000000000000000..a8aa698141b844e55c90845c8acdefca31f05ba1
--- /dev/null
+++ b/vendor/respect/validation/docs/In.md
@@ -0,0 +1,30 @@
+# In
+
+- `v::in(mixed $haystack)`
+- `v::in(mixed $haystack, boolean $identical = false)`
+
+Validates if the input is contained in a specific haystack.
+
+For strings:
+
+```php
+v::in('lorem ipsum')->validate('ipsum'); // true
+```
+
+For arrays:
+
+```php
+v::in(['lorem', 'ipsum'])->validate('lorem'); // true
+```
+
+A second parameter may be passed for identical comparison instead
+of equal comparison.
+
+Message template for this validator includes `{{haystack}}`.
+
+***
+See also:
+
+  * [StartsWith](StartsWith.md)
+  * [EndsWith](EndsWith.md)
+  * [Contains](Contains.md)
diff --git a/vendor/respect/validation/docs/Infinite.md b/vendor/respect/validation/docs/Infinite.md
new file mode 100644
index 0000000000000000000000000000000000000000..d29c666a4f11afd0ae697fca58c4c837705a72b1
--- /dev/null
+++ b/vendor/respect/validation/docs/Infinite.md
@@ -0,0 +1,17 @@
+# Infinite
+
+- `v::infinite()`
+
+Validates if the input is an infinite number.
+
+```php
+v::infinite()->validate(INF); // true
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Finite](Finite.md)
+  * [IntVal](IntVal.md)
+  * [Numeric](Numeric.md)
diff --git a/vendor/respect/validation/docs/Instance.md b/vendor/respect/validation/docs/Instance.md
new file mode 100644
index 0000000000000000000000000000000000000000..bbb45dd0c888a24183525f1d9e539c59bbd3c8cf
--- /dev/null
+++ b/vendor/respect/validation/docs/Instance.md
@@ -0,0 +1,17 @@
+# Instance
+
+- `v::instance(string $instanceName)`
+
+Validates if the input is an instance of the given class or interface.
+
+```php
+v::instance('DateTime')->validate(new DateTime); // true
+v::instance('Traversable')->validate(new ArrayObject); // true
+```
+
+Message template for this validator includes `{{instanceName}}`.
+
+***
+See also:
+
+  * [ObjectType](ObjectType.md)
diff --git a/vendor/respect/validation/docs/IntType.md b/vendor/respect/validation/docs/IntType.md
new file mode 100644
index 0000000000000000000000000000000000000000..d4313657fccba3df7b4c9c9a4fd95744a6d10950
--- /dev/null
+++ b/vendor/respect/validation/docs/IntType.md
@@ -0,0 +1,27 @@
+# IntType
+
+- `v::intType()`
+
+Validates whether the type of a value is integer.
+
+```php
+v::intType()->validate(42); // true
+v::intType()->validate('10'); // false
+```
+
+***
+See also:
+
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [Digit](Digit.md)
+  * [Finite](Finite.md)
+  * [FloatType](FloatType.md)
+  * [Infinite](Infinite.md)
+  * [IntVal](IntVal.md)
+  * [NullType](NullType.md)
+  * [Numeric](Numeric.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/IntVal.md b/vendor/respect/validation/docs/IntVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..18a04046192e8e3e6642d635d394946f16ec078f
--- /dev/null
+++ b/vendor/respect/validation/docs/IntVal.md
@@ -0,0 +1,18 @@
+# IntVal
+
+- `v::intVal()`
+
+Validates if the input is an integer.
+
+```php
+v::intVal()->validate('10'); // true
+v::intVal()->validate(10); // true
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Finite](Finite.md)
+  * [Infinite](Infinite.md)
+  * [Numeric](Numeric.md)
diff --git a/vendor/respect/validation/docs/Ip.md b/vendor/respect/validation/docs/Ip.md
new file mode 100644
index 0000000000000000000000000000000000000000..927dbc7ef618932495bd9e39f38e735675d27d43
--- /dev/null
+++ b/vendor/respect/validation/docs/Ip.md
@@ -0,0 +1,24 @@
+# Ip
+
+- `v::ip()`
+- `v::ip(mixed $options)`
+
+Validates IP Addresses. This validator uses the native filter_var()
+PHP function.
+
+```php
+v::ip()->validate('192.168.0.1');
+```
+
+You can pass a parameter with filter_var flags for IP.
+
+```php
+v::ip(FILTER_FLAG_NO_PRIV_RANGE)->validate('127.0.0.1'); // false
+```
+
+***
+See also:
+
+  * [Domain](Domain.md)
+  * [MacAddress](MacAddress.md)
+  * [Tld](Tld.md)
diff --git a/vendor/respect/validation/docs/Iterable.md b/vendor/respect/validation/docs/Iterable.md
new file mode 100644
index 0000000000000000000000000000000000000000..b64abe28899857ddec73717780d5e5acc4a4560c
--- /dev/null
+++ b/vendor/respect/validation/docs/Iterable.md
@@ -0,0 +1,5 @@
+# Iterable
+
+- `v::iterable()`
+
+**Deprecated**: Use [IterableType](IterableType.md) instead.
diff --git a/vendor/respect/validation/docs/IterableType.md b/vendor/respect/validation/docs/IterableType.md
new file mode 100644
index 0000000000000000000000000000000000000000..a246af271f9cba26a1b0dd538f1eb637e6056e14
--- /dev/null
+++ b/vendor/respect/validation/docs/IterableType.md
@@ -0,0 +1,20 @@
+# IterableType
+
+- `v::iterableType()`
+
+Validates if the input is iterable, in other words, if you're able to iterate
+over it with [foreach](http://php.net/foreach) language construct.
+
+```php
+v::iterableType()->validate([]); // true
+v::iterableType()->validate(new ArrayObject()); // true
+v::iterableType()->validate(new stdClass()); // true
+v::iterableType()->validate('string'); // false
+```
+
+***
+See also:
+
+  * [ArrayVal](ArrayVal.md)
+  * [Countable](Countable.md)
+  * [Instance](Instance.md)
diff --git a/vendor/respect/validation/docs/Json.md b/vendor/respect/validation/docs/Json.md
new file mode 100644
index 0000000000000000000000000000000000000000..eb41367ceaf4ffe1b8060977dada30cad6981013
--- /dev/null
+++ b/vendor/respect/validation/docs/Json.md
@@ -0,0 +1,18 @@
+# Json
+
+- `v::json()`
+
+Validates if the given input is a valid JSON.
+
+```php
+v::json()->validate('{"foo":"bar"}'); // true
+```
+
+***
+See also:
+
+  * [Domain](Domain.md)
+  * [Email](Email.md)
+  * [FilterVar](FilterVar.md)
+  * [Phone](Phone.md)
+  * [VideoUrl](VideoUrl.md)
diff --git a/vendor/respect/validation/docs/Key.md b/vendor/respect/validation/docs/Key.md
new file mode 100644
index 0000000000000000000000000000000000000000..70a74c07a5a2836c4879799cddfbae89d377a23a
--- /dev/null
+++ b/vendor/respect/validation/docs/Key.md
@@ -0,0 +1,34 @@
+# Key
+
+- `v::key(string $name)`
+- `v::key(string $name, v $validator)`
+- `v::key(string $name, v $validator, boolean $mandatory = true)`
+
+Validates an array key.
+
+```php
+$dict = [
+    'foo' => 'bar'
+];
+
+v::key('foo')->validate($dict); // true
+```
+
+You can also validate the key value itself:
+
+```php
+v::key('foo', v::equals('bar'))->validate($dict); // true
+```
+
+Third parameter makes the key presence optional:
+
+```php
+v::key('lorem', v::stringType(), false)->validate($dict); // true
+```
+
+The name of this validator is automatically set to the key name.
+
+***
+See also:
+
+  * [Attribute](Attribute.md)
diff --git a/vendor/respect/validation/docs/KeyNested.md b/vendor/respect/validation/docs/KeyNested.md
new file mode 100644
index 0000000000000000000000000000000000000000..3129dde31c723082fab3332c9c0fa6a3ef81bd2e
--- /dev/null
+++ b/vendor/respect/validation/docs/KeyNested.md
@@ -0,0 +1,40 @@
+# KeyNested
+
+- `v::keyNested(string $name)`
+- `v::keyNested(string $name, v $validator)`
+- `v::keyNested(string $name, v $validator, boolean $mandatory = true)`
+
+Validates an array key or an object property using `.` to represent nested data.
+
+Validating keys from arrays or `ArrayAccess` instances:
+
+```php
+$array = [
+    'foo' => [
+        'bar' => 123,
+    ],
+];
+
+v::keyNested('foo.bar')->validate($array); // true
+```
+
+Validating object properties:
+
+```php
+$object = new stdClass();
+$object->foo = new stdClass();
+$object->foo->bar = 42;
+
+v::keyNested('foo.bar')->validate($object); // true
+```
+
+This rule was inspired by [Yii2 ArrayHelper][].
+
+***
+See also:
+
+  * [Attribute](Attribute.md)
+  * [Key](Key.md)
+
+
+[Yii2 ArrayHelper]: https://github.com/yiisoft/yii2/blob/68c30c1/framework/helpers/BaseArrayHelper.php "Yii2 ArrayHelper"
diff --git a/vendor/respect/validation/docs/KeySet.md b/vendor/respect/validation/docs/KeySet.md
new file mode 100644
index 0000000000000000000000000000000000000000..faf40818aafbd384335127681e039e5c744ce1dc
--- /dev/null
+++ b/vendor/respect/validation/docs/KeySet.md
@@ -0,0 +1,51 @@
+# KeySet
+
+- `v::keySet(Key $rule...)`
+
+Validates a keys in a defined structure.
+
+```php
+$dict = ['foo' => 42];
+
+v::keySet(
+    v::key('foo', v::intVal())
+)->validate($dict); // true
+```
+
+Extra keys are not allowed:
+```php
+$dict = ['foo' => 42, 'bar' => 'String'];
+
+v::keySet(
+    v::key('foo', v::intVal())
+)->validate($dict); // false
+```
+
+Missing required keys are not allowed:
+```php
+$dict = ['foo' => 42, 'bar' => 'String'];
+
+v::keySet(
+    v::key('foo', v::intVal()),
+    v::key('bar', v::stringType()),
+    v::key('baz', v::boolType())
+)->validate($dict); // false
+```
+
+Missing non-required keys are allowed:
+```php
+$dict = ['foo' => 42, 'bar' => 'String'];
+
+v::keySet(
+    v::key('foo', v::intVal()),
+    v::key('bar', v::stringType()),
+    v::key('baz', v::boolType(), false)
+)->validate($dict); // true
+```
+
+The keys' order is not considered in the validation.
+
+***
+See also:
+
+  * [Key](Key.md)
diff --git a/vendor/respect/validation/docs/KeyValue.md b/vendor/respect/validation/docs/KeyValue.md
new file mode 100644
index 0000000000000000000000000000000000000000..98ee9db8731581b6fbda57e80f05742a5e4b4b0c
--- /dev/null
+++ b/vendor/respect/validation/docs/KeyValue.md
@@ -0,0 +1,62 @@
+# KeyValue
+
+- `keyValue(string $comparedKey, string $ruleName, string $baseKey)`
+
+Performs validation of `$comparedKey` using the rule named on `$ruleName` with
+`$baseKey` as base.
+
+Sometimes, when validating arrays, the validation of a key value depends on
+another key value and that may cause some ugly code since you need the input
+before the validation, making some checking manually:
+
+```php
+v::key('password')->check($_POST);
+v::key('password_confirmation', v::equals($_POST['password']))->check($_POST);
+```
+
+The problem with the above code is because you do not know if `password` is a
+valid key, so you must check it manually before performing the validation on
+`password_confirmation`.
+
+The `keyValue()` rule makes this job easier by creating a rule named on
+`$ruleName` passing `$baseKey` as the first argument of this rule, see an example:
+
+```php
+v::keyValue('password_confirmation', 'equals', 'password')->validate($_POST);
+```
+
+The above code will result on `true` if _`$_POST['password_confirmation']` is
+[equals](Equals.md) to `$_POST['password']`_, it's the same of:
+
+See another example:
+
+```php
+v::keyValue('state', 'subdivisionCode', 'country')->validate($_POST);
+```
+
+The above code will result on `true` if _`$_POST['state']` is a
+[subdivision code](SubdivisionCode.md) of `$_POST['country']`_:
+
+This rule will invalidate the input if `$comparedKey` or `$baseKey` don't exist,
+or if the rule named on `$ruleName` could not be created (or don't exist).
+
+When using `assert()` or `check()` methods and the rule do not pass, it overwrites
+all values in the validation exceptions with `$baseKey` and `$comparedKey`.
+
+```php
+v::keyValue('password_confirmation', 'equals', 'password')->check($input);
+```
+
+The above code may generate the message:
+
+```
+password_confirmation must be equals "password"
+```
+
+***
+See also:
+
+  * [Key](Key.md)
+  * [KeyNested](KeyNested.md)
+  * [KeySet](KeySet.md)
+
diff --git a/vendor/respect/validation/docs/LanguageCode.md b/vendor/respect/validation/docs/LanguageCode.md
new file mode 100644
index 0000000000000000000000000000000000000000..a990f315a9a6f8d8b5261bfeab954fa5890a1bed
--- /dev/null
+++ b/vendor/respect/validation/docs/LanguageCode.md
@@ -0,0 +1,20 @@
+# LanguageCode
+
+- `v::languageCode()`
+
+Validates a language code based on ISO 639:
+
+```php
+v::languageCode()->validate('pt'); // true
+v::languageCode()->validate('en'); // true
+v::languageCode()->validate('it'); // true
+v::languageCode('alpha-3')->validate('ita'); // true
+v::languageCode('alpha-3')->validate('eng'); // true
+```
+
+You can choose between alpha-2 and alpha-3, alpha-2 is set by default.
+
+***
+See also:
+
+  * [CountryCode](CountryCode.md)
\ No newline at end of file
diff --git a/vendor/respect/validation/docs/LeapDate.md b/vendor/respect/validation/docs/LeapDate.md
new file mode 100644
index 0000000000000000000000000000000000000000..aa0e7581f7ab4207e3f863dcd14a6c800cd5bd14
--- /dev/null
+++ b/vendor/respect/validation/docs/LeapDate.md
@@ -0,0 +1,18 @@
+# LeapDate
+
+- `v::leapDate(string $format)`
+
+Validates if a date is leap.
+
+```php
+v::leapDate('Y-m-d')->validate('1988-02-29'); // true
+```
+
+This validator accepts DateTime instances as well. The $format
+parameter is mandatory.
+
+***
+See also:
+
+  * [Date](Date.md)
+  * [LeapYear](LeapYear.md)
diff --git a/vendor/respect/validation/docs/LeapYear.md b/vendor/respect/validation/docs/LeapYear.md
new file mode 100644
index 0000000000000000000000000000000000000000..db208993164f717ab648968850f78013a8794f74
--- /dev/null
+++ b/vendor/respect/validation/docs/LeapYear.md
@@ -0,0 +1,17 @@
+# LeapYear
+
+- `v::leapYear()`
+
+Validates if a year is leap.
+
+```php
+v::leapYear()->validate('1988'); // true
+```
+
+This validator accepts DateTime instances as well.
+
+***
+See also:
+
+  * [Date](Date.md)
+  * [LeapDate](LeapDate.md)
diff --git a/vendor/respect/validation/docs/Length.md b/vendor/respect/validation/docs/Length.md
new file mode 100644
index 0000000000000000000000000000000000000000..2fbf519536b85d41e705750ef6d05b57d0d59645
--- /dev/null
+++ b/vendor/respect/validation/docs/Length.md
@@ -0,0 +1,44 @@
+# Length
+
+- `v::length(int $min, int $max)`
+- `v::length(int $min, null)`
+- `v::length(null, int $max)`
+- `v::length(int $min, int $max, boolean $inclusive = true)`
+
+Validates lengths. Most simple example:
+
+```php
+v::stringType()->length(1, 5)->validate('abc'); // true
+```
+
+You can also validate only minimum length:
+
+```php
+v::stringType()->length(5, null)->validate('abcdef'); // true
+```
+
+Only maximum length:
+
+```php
+v::stringType()->length(null, 5)->validate('abc'); // true
+```
+
+The type as the first validator in a chain is a good practice,
+since length accepts many types:
+
+```php
+v::arrayVal()->length(1, 5)->validate(['foo', 'bar']); // true
+```
+
+A third parameter may be passed to validate the passed values inclusive:
+
+```php
+v::stringType()->length(1, 5, true)->validate('a'); // true
+```
+
+Message template for this validator includes `{{minValue}}` and `{{maxValue}}`.
+
+***
+See also:
+
+  * [Between](Between.md)
diff --git a/vendor/respect/validation/docs/Lowercase.md b/vendor/respect/validation/docs/Lowercase.md
new file mode 100644
index 0000000000000000000000000000000000000000..a79f82b76fdb91a36d71b1ceffa09daa00ea1b07
--- /dev/null
+++ b/vendor/respect/validation/docs/Lowercase.md
@@ -0,0 +1,14 @@
+# Lowercase
+
+- `v::lowercase()`
+
+Validates if string characters are lowercase in the input:
+
+```php
+v::stringType()->lowercase()->validate('xkcd'); // true
+```
+
+***
+See also:
+
+  * [Uppercase](Uppercase.md)
diff --git a/vendor/respect/validation/docs/MacAddress.md b/vendor/respect/validation/docs/MacAddress.md
new file mode 100644
index 0000000000000000000000000000000000000000..92f427af302b90114e4c6705be4687b1c87a3c29
--- /dev/null
+++ b/vendor/respect/validation/docs/MacAddress.md
@@ -0,0 +1,17 @@
+# MacAddress
+
+- `v::macAddress()`
+
+Validates a Mac Address.
+
+```php
+v::macAddress()->validate('00:11:22:33:44:55'); // true
+v::macAddress()->validate('af-AA-22-33-44-55'); // true
+```
+
+***
+See also:
+
+  * [Domain](Domain.md)
+  * [Ip](Ip.md)
+  * [Tld](Tld.md)
diff --git a/vendor/respect/validation/docs/Max.md b/vendor/respect/validation/docs/Max.md
new file mode 100644
index 0000000000000000000000000000000000000000..1c199b9497ad9067e2241117fbc8893543443996
--- /dev/null
+++ b/vendor/respect/validation/docs/Max.md
@@ -0,0 +1,36 @@
+# Max
+
+- `v::max(mixed $maxValue)`
+- `v::max(mixed $maxValue, boolean $inclusive = true)`
+
+Validates if the input doesn't exceed the maximum value.
+
+```php
+v::intVal()->max(15)->validate(20); // false
+v::intVal()->max(20)->validate(20); // false
+v::intVal()->max(20, true)->validate(20); // true
+```
+
+Also accepts dates:
+
+```php
+v::date()->max('2012-01-01')->validate('2010-01-01'); // true
+```
+
+Also date intervals:
+
+```php
+// Same of minimum age validation
+v::date()->max('-18 years')->validate('1988-09-09'); // true
+```
+
+`true` may be passed as a parameter to indicate that inclusive
+values must be used.
+
+Message template for this validator includes `{{maxValue}}`.
+
+***
+See also:
+
+  * [Min](Min.md)
+  * [Between](Between.md)
diff --git a/vendor/respect/validation/docs/Mimetype.md b/vendor/respect/validation/docs/Mimetype.md
new file mode 100644
index 0000000000000000000000000000000000000000..a2af05e8c74aec337944d3a1566a5a050ba822b4
--- /dev/null
+++ b/vendor/respect/validation/docs/Mimetype.md
@@ -0,0 +1,25 @@
+# Mimetype
+
+- `v::mimetype(string $mimetype)`
+
+Validates if the file mimetype matches the expected one:
+
+```php
+v::mimetype('image/png')->validate('image.png'); // true
+```
+
+This rule is case-sensitive and requires [fileinfo](http://php.net/fileinfo) PHP extension.
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Min.md b/vendor/respect/validation/docs/Min.md
new file mode 100644
index 0000000000000000000000000000000000000000..460154f25f8435fe489caff1681dd0c1ee49ce37
--- /dev/null
+++ b/vendor/respect/validation/docs/Min.md
@@ -0,0 +1,29 @@
+# Min
+
+- `v::min(mixed $minValue)`
+- `v::min(mixed $minValue, boolean $inclusive = true)`
+
+Validates if the input is greater than the minimum value.
+
+```php
+v::intVal()->min(15)->validate(5); // false
+v::intVal()->min(5)->validate(5); // false
+v::intVal()->min(5, true)->validate(5); // true
+```
+
+Also accepts dates:
+
+```php
+v::date()->min('2012-01-01')->validate('2015-01-01'); // true
+```
+
+`true` may be passed as a parameter to indicate that inclusive
+values must be used.
+
+Message template for this validator includes `{{minValue}}`.
+
+***
+See also:
+
+  * [Max](Max.md)
+  * [Between](Between.md)
diff --git a/vendor/respect/validation/docs/MinimumAge.md b/vendor/respect/validation/docs/MinimumAge.md
new file mode 100644
index 0000000000000000000000000000000000000000..33b457ae0b0ad2d3b34288a56569dee05e6e6188
--- /dev/null
+++ b/vendor/respect/validation/docs/MinimumAge.md
@@ -0,0 +1,23 @@
+# MinimumAge
+
+This is going to be deprecated, please use [Age](Age.md) instead.
+
+- `v::minimumAge(int $age)`
+- `v::minimumAge(int $age, string $format)`
+
+Validates a minimum age for a given date.
+
+```php
+v::minimumAge(18)->validate('1987-01-01'); // true
+v::minimumAge(18, 'd/m/Y')->validate('01/01/1987'); // true
+```
+
+Using `date()` before is a best-practice.
+
+Message template for this validator includes `{{age}}`.
+
+***
+See also:
+
+  * [Age](Age.md)
+  * [Date](Date.md)
diff --git a/vendor/respect/validation/docs/Multiple.md b/vendor/respect/validation/docs/Multiple.md
new file mode 100644
index 0000000000000000000000000000000000000000..b6d8c7ff02ce91038d3b57c4abff84308cacc737
--- /dev/null
+++ b/vendor/respect/validation/docs/Multiple.md
@@ -0,0 +1,14 @@
+# Multiple
+
+- `v::multiple(int $multipleOf)`
+
+Validates if the input is a multiple of the given parameter
+
+```php
+v::intVal()->multiple(3)->validate(9); // true
+```
+
+***
+See also:
+
+  * [PrimeNumber](PrimeNumber.md)
diff --git a/vendor/respect/validation/docs/Negative.md b/vendor/respect/validation/docs/Negative.md
new file mode 100644
index 0000000000000000000000000000000000000000..efecb52018b0763c49d61deec12b3f45b1bbec7c
--- /dev/null
+++ b/vendor/respect/validation/docs/Negative.md
@@ -0,0 +1,14 @@
+# Negative
+
+- `v::negative()`
+
+Validates if a number is lower than zero
+
+```php
+v::numeric()->negative()->validate(-15); // true
+```
+
+***
+See also:
+
+  * [Positive](Positive.md)
diff --git a/vendor/respect/validation/docs/NfeAccessKey.md b/vendor/respect/validation/docs/NfeAccessKey.md
new file mode 100644
index 0000000000000000000000000000000000000000..2f9188f1b0ce52d960b4ef30f58dd17b203c6d61
--- /dev/null
+++ b/vendor/respect/validation/docs/NfeAccessKey.md
@@ -0,0 +1,16 @@
+# NfeAccessKey
+
+- `v::nfeAccessKey(string $accessKey)`
+
+Validates the access key of the Brazilian electronic invoice (NFe).
+
+```php
+v::nfeAccessKey()->validate('31841136830118868211870485416765268625116906'); // true
+```
+
+***
+See also:
+
+  * [Cnh](Cnh.md)
+  * [Cnpj](Cnpj.md)
+  * [Cpf](Cpf.md)
diff --git a/vendor/respect/validation/docs/No.md b/vendor/respect/validation/docs/No.md
new file mode 100644
index 0000000000000000000000000000000000000000..e50b4c72becd343ad8682869488b9522d8fd456f
--- /dev/null
+++ b/vendor/respect/validation/docs/No.md
@@ -0,0 +1,24 @@
+# No
+
+- `v::no()`
+- `v::no(boolean $locale)`
+
+Validates if value is considered as "No".
+
+```php
+v::no()->validate('N'); // true
+v::no()->validate('Nay'); // true
+v::no()->validate('Nix'); // true
+v::no()->validate('No'); // true
+v::no()->validate('Nope'); // true
+v::no()->validate('Not'); // true
+```
+
+This rule is case insensitive.
+
+If `$locale` is TRUE, uses the value of [nl_langinfo()](http://php.net/nl_langinfo) with `NOEXPR` constant.
+
+***
+See also:
+
+  * [Yes](Yes.md)
diff --git a/vendor/respect/validation/docs/NoWhitespace.md b/vendor/respect/validation/docs/NoWhitespace.md
new file mode 100644
index 0000000000000000000000000000000000000000..052cfcdee028d66c24fe55bb1b6bce6ee64e7a27
--- /dev/null
+++ b/vendor/respect/validation/docs/NoWhitespace.md
@@ -0,0 +1,21 @@
+# NoWhitespace
+
+- `v::noWhitespace()`
+
+Validates if a string contains no whitespace (spaces, tabs and line breaks);
+
+```php
+v::noWhitespace()->validate('foo bar');  //false
+v::noWhitespace()->validate("foo\nbar"); // false
+```
+
+This is most useful when chaining with other validators such as `v::alnum()`
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
+  * [NotBlank](NotBlank.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NotOptional](NotOptional.md)
diff --git a/vendor/respect/validation/docs/NoneOf.md b/vendor/respect/validation/docs/NoneOf.md
new file mode 100644
index 0000000000000000000000000000000000000000..44e91537e8754135bf7f3a0400e0d5259d036188
--- /dev/null
+++ b/vendor/respect/validation/docs/NoneOf.md
@@ -0,0 +1,21 @@
+# NoneOf
+
+- `v::noneOf(v $v1, v $v2, v $v3...)`
+
+Validates if NONE of the given validators validate:
+
+```php
+v::noneOf(
+    v::intVal(),
+    v::floatVal()
+)->validate('foo'); // true
+```
+
+In the sample above, 'foo' isn't a integer nor a float, so noneOf returns true.
+
+***
+See also:
+
+  * [Not](Not.md)
+  * [AllOf](AllOf.md)
+  * [OneOf](OneOf.md)
diff --git a/vendor/respect/validation/docs/Not.md b/vendor/respect/validation/docs/Not.md
new file mode 100644
index 0000000000000000000000000000000000000000..31f575bca1748ce768a9dbc54e4b9ed4d7d7e4c3
--- /dev/null
+++ b/vendor/respect/validation/docs/Not.md
@@ -0,0 +1,24 @@
+# Not
+
+- `v::not(v $negatedValidator)`
+
+Negates any rule.
+
+```php
+v::not(v::ip())->validate('foo'); // true
+```
+
+In the sample above, validator returns true because 'foo' isn't an IP Address.
+
+You can negate complex, grouped or chained validators as well:
+
+```php
+v::not(v::intVal()->positive())->validate(-1.5); // true
+```
+
+Each other validation has custom messages for negated rules.
+
+***
+See also:
+
+  * [NoneOf](NoneOf.md)
diff --git a/vendor/respect/validation/docs/NotBlank.md b/vendor/respect/validation/docs/NotBlank.md
new file mode 100644
index 0000000000000000000000000000000000000000..35a5ef2de273e29918c98c4a743603b026ffd3ca
--- /dev/null
+++ b/vendor/respect/validation/docs/NotBlank.md
@@ -0,0 +1,34 @@
+# NotBlank
+
+- `v::notBlank()`
+
+Validates if the given input is not a blank value (`null`, zeros, empty strings
+or empty arrays, recursively).
+
+```php
+v::notBlank()->validate(null); // false
+v::notBlank()->validate(''); // false
+v::notBlank()->validate([]); // false
+v::notBlank()->validate(' '); // false
+v::notBlank()->validate(0); // false
+v::notBlank()->validate('0'); // false
+v::notBlank()->validate(0); // false
+v::notBlank()->validate('0.0'); // false
+v::notBlank()->validate(false); // false
+v::notBlank()->validate(['']); // false
+v::notBlank()->validate([' ']); // false
+v::notBlank()->validate([0]); // false
+v::notBlank()->validate(['0']); // false
+v::notBlank()->validate([false]); // false
+v::notBlank()->validate([[''], [0]]); // false
+v::notBlank()->validate(new stdClass()); // false
+```
+
+It's similar to [NotEmpty](NotEmpty.md) but it's way more strict.
+
+***
+See also:
+
+  * [NoWhitespace](NoWhitespace.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NullType](NullType.md)
diff --git a/vendor/respect/validation/docs/NotEmpty.md b/vendor/respect/validation/docs/NotEmpty.md
new file mode 100644
index 0000000000000000000000000000000000000000..ab888f6a641664ad296b7de9cb616c4421500f08
--- /dev/null
+++ b/vendor/respect/validation/docs/NotEmpty.md
@@ -0,0 +1,42 @@
+# NotEmpty
+
+- `v::notEmpty()`
+
+Validates if the given input is not empty or in other words is input mandatory and
+required. This function also takes whitespace into account, use `noWhitespace()`
+if no spaces or linebreaks and other whitespace anywhere in the input is desired.
+
+```php
+v::stringType()->notEmpty()->validate(''); // false
+```
+
+Null values are empty:
+
+```php
+v::notEmpty()->validate(null); // false
+```
+
+Numbers:
+
+```php
+v::intVal()->notEmpty()->validate(0); // false
+```
+
+Empty arrays:
+
+```php
+v::arrayVal()->notEmpty()->validate([]); // false
+```
+
+Whitespace:
+
+```php
+v::stringType()->notEmpty()->validate('        ');  //false
+v::stringType()->notEmpty()->validate("\t \n \r");  //false
+```
+
+***
+See also:
+
+  * [NoWhitespace](NoWhitespace.md)
+  * [NullType](NullType.md)
diff --git a/vendor/respect/validation/docs/NotOptional.md b/vendor/respect/validation/docs/NotOptional.md
new file mode 100644
index 0000000000000000000000000000000000000000..487e7f1ef253ff82ead7b3f150f7c07a3163209b
--- /dev/null
+++ b/vendor/respect/validation/docs/NotOptional.md
@@ -0,0 +1,39 @@
+# NotOptional
+
+- `v::notOptional()`
+
+Validates if the given input is not optional. By _optional_ we consider `null`
+or an empty string (`''`).
+
+```php
+v::notOptional()->validate(''); // false
+v::notOptional()->validate(null); // false
+```
+
+Other values:
+
+```php
+v::notOptional()->validate([]); // true
+v::notOptional()->validate(' '); // true
+v::notOptional()->validate(0); // true
+v::notOptional()->validate('0'); // true
+v::notOptional()->validate(0); // true
+v::notOptional()->validate('0.0'); // true
+v::notOptional()->validate(false); // true
+v::notOptional()->validate(['']); // true
+v::notOptional()->validate([' ']); // true
+v::notOptional()->validate([0]); // true
+v::notOptional()->validate(['0']); // true
+v::notOptional()->validate([false]); // true
+v::notOptional()->validate([[''), [0]]); // true
+v::notOptional()->validate(new stdClass()); // true
+```
+
+***
+See also:
+
+  * [NoWhitespace](NoWhitespace.md)
+  * [NotBlank](NotBlank.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NullType](NullType.md)
+  * [Optional](Optional.md)
diff --git a/vendor/respect/validation/docs/NullType.md b/vendor/respect/validation/docs/NullType.md
new file mode 100644
index 0000000000000000000000000000000000000000..5b39feb6c2d0eb36a964fc982d2fcd58aa73cea8
--- /dev/null
+++ b/vendor/respect/validation/docs/NullType.md
@@ -0,0 +1,25 @@
+# NullType
+
+- `v::nullType()`
+
+Validates if the input is null.
+
+```php
+v::nullType()->validate(null); // true
+```
+
+***
+See also:
+
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [NotBlank](NotBlank.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NotOptional](NotOptional.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Numeric.md b/vendor/respect/validation/docs/Numeric.md
new file mode 100644
index 0000000000000000000000000000000000000000..d8121fb61c9ae621e4ebe74b45b80853e5c95721
--- /dev/null
+++ b/vendor/respect/validation/docs/Numeric.md
@@ -0,0 +1,18 @@
+# Numeric
+
+- `v::numeric()`
+
+Validates on any numeric value.
+
+```php
+v::numeric()->validate(-12); // true
+v::numeric()->validate('135.0'); // true
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Finite](Finite.md)
+  * [Infinite](Infinite.md)
+  * [IntVal](IntVal.md)
diff --git a/vendor/respect/validation/docs/ObjectType.md b/vendor/respect/validation/docs/ObjectType.md
new file mode 100644
index 0000000000000000000000000000000000000000..39212603155048570ca891161b495f1f8f41792c
--- /dev/null
+++ b/vendor/respect/validation/docs/ObjectType.md
@@ -0,0 +1,24 @@
+# ObjectType
+
+- `v::objectType()`
+
+Validates if the input is an object.
+
+```php
+v::objectType()->validate(new stdClass); // true
+```
+
+***
+See also:
+
+  * [Attribute](Attribute.md)
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [Instance](Instance.md)
+  * [IntType](IntType.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Odd.md b/vendor/respect/validation/docs/Odd.md
new file mode 100644
index 0000000000000000000000000000000000000000..b1a8d05fc978f94cd5e074288b5988969c161868
--- /dev/null
+++ b/vendor/respect/validation/docs/Odd.md
@@ -0,0 +1,17 @@
+# Odd
+
+- `v::odd()`
+
+Validates an odd number.
+
+```php
+v::intVal()->odd()->validate(3); // true
+```
+
+Using `int()` before `odd()` is a best practice.
+
+***
+See also:
+
+  * [Even](Even.md)
+  * [Multiple](Multiple.md)
diff --git a/vendor/respect/validation/docs/OneOf.md b/vendor/respect/validation/docs/OneOf.md
new file mode 100644
index 0000000000000000000000000000000000000000..e16be50df043ad94aa622584da26a71746077ee0
--- /dev/null
+++ b/vendor/respect/validation/docs/OneOf.md
@@ -0,0 +1,25 @@
+# OneOf
+
+- `v::oneOf(v $v1, v $v2, v $v3...)`
+
+This is a group validator that acts as an OR operator.
+
+```php
+v::oneOf(
+    v::intVal(),
+    v::floatVal()
+)->validate(15.5); // true
+```
+
+In the sample above, `v::intVal()` doesn't validates, but
+`v::floatVal()` validates, so oneOf returns true.
+
+`v::oneOf` returns true if at least one inner validator
+passes.
+
+***
+See also:
+
+  * [AllOf](AllOf.md)
+  * [NoneOf](NoneOf.md)
+  * [When](When.md)
diff --git a/vendor/respect/validation/docs/Optional.md b/vendor/respect/validation/docs/Optional.md
new file mode 100644
index 0000000000000000000000000000000000000000..1a4aa5ec091f9731c70ae017489abc01c6424de1
--- /dev/null
+++ b/vendor/respect/validation/docs/Optional.md
@@ -0,0 +1,21 @@
+# Optional
+
+- `v::optional(v $rule)`
+
+Validates if the given input is optional or not. By _optional_ we consider `null`
+or an empty string (`''`).
+
+```php
+v::optional(v::alpha())->validate(''); // true
+v::optional(v::digit())->validate(null); // true
+```
+
+
+***
+See also:
+
+  * [NoWhitespace](NoWhitespace.md)
+  * [NotBlank](NotBlank.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NotOptional](NotOptional.md)
+  * [NullType](NullType.md)
diff --git a/vendor/respect/validation/docs/PerfectSquare.md b/vendor/respect/validation/docs/PerfectSquare.md
new file mode 100644
index 0000000000000000000000000000000000000000..3a344b27c9125bd28f0ac6afc1fa8b3d485d372b
--- /dev/null
+++ b/vendor/respect/validation/docs/PerfectSquare.md
@@ -0,0 +1,16 @@
+# PerfectSquare
+
+- `v::perfectSquare()`
+
+Validates a perfect square.
+
+```php
+v::perfectSquare()->validate(25); // true (5*5)
+v::perfectSquare()->validate(9); // true (3*3)
+```
+
+***
+See also:
+
+  * [Factor](Factor.md)
+  * [PrimeNumber](PrimeNumber.md)
diff --git a/vendor/respect/validation/docs/Pesel.md b/vendor/respect/validation/docs/Pesel.md
new file mode 100644
index 0000000000000000000000000000000000000000..275ff7f8d3117304f091e08f9b3424aff30cbf65
--- /dev/null
+++ b/vendor/respect/validation/docs/Pesel.md
@@ -0,0 +1,12 @@
+# Pesel
+
+- `v::pesel()`
+
+Validates PESEL (Polish human identification number).
+
+```php
+v::pesel()->validate('21120209256'); // true
+v::pesel()->validate('97072704800'); // true
+v::pesel()->validate('97072704801'); // false
+v::pesel()->validate('PESEL123456'); // false
+```
diff --git a/vendor/respect/validation/docs/Phone.md b/vendor/respect/validation/docs/Phone.md
new file mode 100644
index 0000000000000000000000000000000000000000..ac3cba9b9582c7192467e65376d4c0e7dd8b0899
--- /dev/null
+++ b/vendor/respect/validation/docs/Phone.md
@@ -0,0 +1,22 @@
+# Phone
+
+- `v::phone()`
+
+Validates a valid 7, 10, 11 digit phone number (North America, Europe and most
+Asian and Middle East countries), supporting country and area codes (in dot,
+space or dashed notations) such as:
+
+    (555)555-5555
+    555 555 5555
+    +5(555)555.5555
+    33(1)22 22 22 22
+    +33(1)22 22 22 22
+    +33(020)7777 7777
+    03-6106666
+
+***
+See also:
+
+  * [Email](Email.md)
+  * [Url](Url.md)
+  * [VideoUrl](VideoUrl.md)
diff --git a/vendor/respect/validation/docs/PhpLabel.md b/vendor/respect/validation/docs/PhpLabel.md
new file mode 100644
index 0000000000000000000000000000000000000000..4295267d72fb63767b02985ce2fd2f4479226e43
--- /dev/null
+++ b/vendor/respect/validation/docs/PhpLabel.md
@@ -0,0 +1,24 @@
+# PhpLabel
+
+- `v::phpLabel()`
+
+Validates if a value is considered a valid PHP Label, 
+so that it can be used as a *variable*, *function* or *class* name, for example.
+
+Reference:
+http://php.net/manual/en/language.variables.basics.php
+
+```php
+v::phpLabel()->validate('person'); //true
+v::phpLabel()->validate('foo'); //true
+v::phpLabel()->validate('4ccess'); //false
+```
+
+***
+See also:
+
+  * [Regex](Regex.md)
+  * [ResourceType](ResourceType.md)
+  * [Slug](Slug.md)
+  * [Charset](Charset.md)
+  
\ No newline at end of file
diff --git a/vendor/respect/validation/docs/Positive.md b/vendor/respect/validation/docs/Positive.md
new file mode 100644
index 0000000000000000000000000000000000000000..ecf75d9f00fd536907b1e56462fda4f184920501
--- /dev/null
+++ b/vendor/respect/validation/docs/Positive.md
@@ -0,0 +1,14 @@
+# Positive
+
+- `v::positive()`
+
+Validates if a number is higher than zero
+
+```php
+v::numeric()->positive()->validate(-15); // false
+```
+
+***
+See also:
+
+  * [Negative](Negative.md)
diff --git a/vendor/respect/validation/docs/PostalCode.md b/vendor/respect/validation/docs/PostalCode.md
new file mode 100644
index 0000000000000000000000000000000000000000..c18ec96ede6a146bddb14f0c964cb95b278a4670
--- /dev/null
+++ b/vendor/respect/validation/docs/PostalCode.md
@@ -0,0 +1,22 @@
+# PostalCode
+
+- `v::postalCode(string $countryCode)`
+
+Validates a postal code according to the given country code.
+
+```php
+v::postalCode('BR')->validate('02179000'); // true
+v::postalCode('BR')->validate('02179-000'); // true
+v::postalCode('US')->validate('02179-000'); // false
+v::postalCode('US')->validate('55372'); // true
+v::postalCode('PL')->validate('99-300'); // true
+```
+
+Message template for this validator includes `{{countryCode}}`.
+
+Extracted from [GeoNames](http://www.geonames.org/).
+
+***
+See also:
+
+  * [CountryCode](CountryCode.md)
diff --git a/vendor/respect/validation/docs/PrimeNumber.md b/vendor/respect/validation/docs/PrimeNumber.md
new file mode 100644
index 0000000000000000000000000000000000000000..dee58eabd4c93b89b4e351fd856d9608beeddfa6
--- /dev/null
+++ b/vendor/respect/validation/docs/PrimeNumber.md
@@ -0,0 +1,16 @@
+# PrimeNumber
+
+- `v::primeNumber()`
+
+Validates a prime number
+
+```php
+v::primeNumber()->validate(7); // true
+```
+
+***
+See also:
+
+  * [Factor](Factor.md)
+  * [PerfectSquare](PerfectSquare.md)
+  * [PrimeNumber](PrimeNumber.md)
diff --git a/vendor/respect/validation/docs/Prnt.md b/vendor/respect/validation/docs/Prnt.md
new file mode 100644
index 0000000000000000000000000000000000000000..29dc6d76397b0d52e1cb0b8a269d4f4395952913
--- /dev/null
+++ b/vendor/respect/validation/docs/Prnt.md
@@ -0,0 +1,15 @@
+# Prnt
+
+- `v::prnt()`
+- `v::prnt(string $additionalChars)`
+
+Similar to `v::graph` but accepts whitespace.
+
+```php
+v::prnt()->validate('LMKA0$% _123'); // true
+```
+
+***
+See also:
+
+  * [Graph](Graph.md)
diff --git a/vendor/respect/validation/docs/Punct.md b/vendor/respect/validation/docs/Punct.md
new file mode 100644
index 0000000000000000000000000000000000000000..d49411aa90978c85ffe136eb0afdf574dc985fd5
--- /dev/null
+++ b/vendor/respect/validation/docs/Punct.md
@@ -0,0 +1,17 @@
+# Punct
+
+- `v::punct()`
+- `v::punct(string $additionalChars)`
+
+Accepts only punctuation characters:
+
+```php
+v::punct()->validate('&,.;[]'); // true
+```
+
+***
+See also:
+
+  * [Cntrl](Cntrl.md)
+  * [Graph](Graph.md)
+  * [Prnt](Prnt.md)
diff --git a/vendor/respect/validation/docs/README.md b/vendor/respect/validation/docs/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..abd573aaff56a3aae4a2660f92ac9c3f62c8ac88
--- /dev/null
+++ b/vendor/respect/validation/docs/README.md
@@ -0,0 +1,310 @@
+# Feature Guide
+
+## Namespace import
+
+Respect\Validation is namespaced, but you can make your life easier by importing
+a single class into your context:
+
+```php
+use Respect\Validation\Validator as v;
+```
+
+## Simple validation
+
+The Hello World validator is something like this:
+
+```php
+$number = 123;
+v::numeric()->validate($number); // true
+```
+
+## Chained validation
+
+It is possible to use validators in a chain. Sample below validates a string
+containing numbers and letters, no whitespace and length between 1 and 15.
+
+```php
+$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
+$usernameValidator->validate('alganet'); // true
+```
+
+## Validating object attributes
+
+Given this simple object:
+
+```php
+$user = new stdClass;
+$user->name = 'Alexandre';
+$user->birthdate = '1987-07-01';
+```
+
+Is possible to validate its attributes in a single chain:
+
+```php
+$userValidator = v::attribute('name', v::stringType()->length(1,32))
+                  ->attribute('birthdate', v::date()->age(18));
+
+$userValidator->validate($user); // true
+```
+
+Validating array keys is also possible using `v::key()`
+
+Note that we used `v::stringType()` and `v::date()` in the beginning of the validator.
+Although is not mandatory, it is a good practice to use the type of the
+validated object as the first node in the chain.
+
+## Input optional
+
+On oldest versions of Respect\Validation all validators treat input as optional
+and accept an empty string input as valid. Even though a useful feature that
+caused a lot of troubles for our team and neither was an obvious behavior. Also
+there was some people who likes to accept `null` as optional value, not only an
+empty string.
+
+For that reason all rules are mandatory now but if you want to treat a value as
+optional you can use `v::optional()` rule:
+
+```php
+v::alpha()->validate(''); // false input required
+v::alpha()->validate(null); // false input required
+
+v::optional(v::alpha())->validate(''); // true
+v::optional(v::alpha())->validate(null); // true
+```
+
+By _optional_ we consider `null` or an empty string (`''`).
+
+See more on [Optional](Optional.md).
+
+## Negating rules
+
+You can use the `v::not()` to negate any rule:
+
+```php
+v::not(v::intVal())->validate(10); // false, input must not be integer
+```
+
+## Validator reuse
+
+Once created, you can reuse your validator anywhere. Remember `$usernameValidator`?
+
+```php
+$usernameValidator->validate('respect');            //true
+$usernameValidator->validate('alexandre gaigalas'); // false
+$usernameValidator->validate('#$%');                //false
+```
+
+## Exception types
+
+* `Respect\Validation\Exceptions\ExceptionInterface`:
+    * All exceptions implement this interface;
+* `Respect\Validation\Exceptions\ValidationException`:
+    * Implements the `Respect\Validation\Exceptions\ExceptionInterface` interface
+    * Thrown when the `check()` fails
+    * All validation exceptions extend this class
+    * Available methods:
+        * `getMainMessage()`;
+        * `setMode($mode)`;
+        * `setName($name)`;
+        * `setParam($name, $value)`;
+        * `setTemplate($template)`;
+        * more...
+* `Respect\Validation\Exceptions\NestedValidationException`:
+    * Extends the `Respect\Validation\Exceptions\ValidationException` class
+    * Usually thrown when the `assert()` fails
+    * Available methods:
+        * `findMessages()`;
+        * `getFullMessage()`;
+        * `getMessages()`;
+        * more...
+
+## Informative exceptions
+
+When something goes wrong, Validation can tell you exactly what's going on. For this,
+we use the `assert()` method instead of `validate()`:
+
+```php
+use Respect\Validation\Exceptions\NestedValidationException;
+
+try {
+    $usernameValidator->assert('really messed up screen#name');
+} catch(NestedValidationException $exception) {
+   echo $exception->getFullMessage();
+}
+```
+
+The printed message is exactly this, as a nested Markdown list:
+
+```no-highlight
+- All of the required rules must pass for "really messed up screen#name"
+  - "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
+  - "really messed up screen#name" must not contain whitespace
+  - "really messed up screen#name" must have a length between 1 and 15
+```
+
+## Getting all messages as an array
+
+The Markdown list is fine, but unusable on a HTML form or something more custom.
+For that you can use `getMessages()`.
+
+It will return all messages from the rules that did not pass the validation.
+
+```php
+try {
+    $usernameValidator->assert('really messed up screen#name');
+} catch(NestedValidationException $exception) {
+    print_r($exception->getMessages());
+}
+```
+
+The code above may display something like:
+
+```no-highlight
+Array
+(
+    [0] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
+    [1] => "really messed up screen#name" must not contain whitespace
+    [2] => "really messed up screen#name" must have a length between 1 and 15
+)
+```
+
+## Getting messages as an array by name
+
+If you want to get specific message by name you can use `findMessages()` passing
+the names of the rules you want:
+
+```php
+try {
+    $usernameValidator->assert('really messed up screen#name');
+} catch(NestedValidationException $exception) {
+    print_r($exception->findMessages(['alnum', 'noWhitespace']));
+}
+```
+
+The `findMessages()` returns an array with messages from the requested validators,
+like this:
+
+```no-highlight
+Array
+(
+    [alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
+    [noWhitespace] => "really messed up screen#name" must not contain whitespace
+)
+```
+
+## Custom messages
+
+Getting messages as an array is fine, but sometimes you need to customize them in order
+to present them to the user. This is possible using the `findMessages()` method as well:
+
+```php
+$errors = $exception->findMessages([
+    'alnum' => '{{name}} must contain only letters and digits',
+    'length' => '{{name}} must not have more than 15 chars',
+    'noWhitespace' => '{{name}} cannot contain spaces'
+]);
+```
+
+For all messages, the `{{name}}` variable is available for templates. If you
+do not define a name it uses the input to replace this placeholder.
+
+## Message localization
+
+You're also able to translate your message to another language with Validation.
+The only thing one must do is to define the param `translator` as a callable that
+will handle the translation:
+
+```php
+$exception->setParam('translator', 'gettext');
+```
+
+The example above uses `gettext()` but you can use any other callable value, like
+`[$translator, 'trans']` or `you_custom_function()`.
+
+After that, if you call `getMainMessage()` or `getFullMessage()` (for nested),
+the message will be translated.
+
+Note that `getMessage()` will keep the original message.
+
+## Custom rules
+
+You also can use your own rules:
+
+```php
+namespace My\Validation\Rules;
+
+use Respect\Validation\Rules\AbstractRule;
+
+class MyRule extends AbstractRule
+{
+    public function validate($input)
+    {
+        // Do something here with the $input and return a boolean value
+    }
+}
+```
+
+If you do want Validation to execute you rule (or rules) in the chain, you must
+use `v::with()` passing your rule's namespace as an argument:
+
+```php
+v::with('My\\Validation\\Rules\\');
+v::myRule(); // Try to load "My\Validation\Rules\MyRule" if any
+```
+
+By default `with()` appends the given prefix, but you can change this behavior
+in order to overwrite default rules:
+
+```php
+v::with('My\\Validation\\Rules', true);
+v::alnum(); // Try to use "My\Validation\Rules\Alnum" if any
+```
+
+## Validator name
+
+On `v::attribute()` and `v::key()`, `{{name}}` is the attribute/key name. For others,
+is the same as the input. You can customize a validator name using:
+
+```php
+v::date('Y-m-d')->between('1980-02-02', 'now')->setName('Member Since');
+```
+
+## Zend/Symfony validators
+
+It is also possible to reuse validators from other frameworks if they are installed:
+
+```php
+$hostnameValidator = v::zend('Hostname')->assert('google.com');
+$timeValidator     = v::sf('Time')->assert('22:00:01');
+```
+
+## Validation methods
+
+We've seen `validate()` that returns true or false and `assert()` that throws a complete
+validation report. There is also a `check()` method that returns an Exception
+only with the first error found:
+
+```php
+use Respect\Validation\Exceptions\ValidationException;
+
+try {
+    $usernameValidator->check('really messed up screen#name');
+} catch(ValidationException $exception) {
+    echo $exception->getMainMessage();
+}
+```
+
+Message:
+
+```no-highlight
+"really messed up screen#name" must contain only letters (a-z) and digits (0-9)
+```
+
+***
+See also:
+
+- [Contributing](../CONTRIBUTING.md)
+- [Installation](INSTALL.md)
+- [License](../LICENSE.md)
+- [Validators](VALIDATORS.md)
+- [Changelog](../CHANGELOG.md)
diff --git a/vendor/respect/validation/docs/Readable.md b/vendor/respect/validation/docs/Readable.md
new file mode 100644
index 0000000000000000000000000000000000000000..00a074eb9142aa4700965e2bf593d6b3cbd67e3d
--- /dev/null
+++ b/vendor/respect/validation/docs/Readable.md
@@ -0,0 +1,23 @@
+# Readable
+
+- `v::readable()`
+
+Validates if the given data is a file exists and is readable.
+
+```php
+v::readable()->validate('/path/of/a/readable/file'); // true
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Regex.md b/vendor/respect/validation/docs/Regex.md
new file mode 100644
index 0000000000000000000000000000000000000000..ed0d2517345e6fcb37c9ad8e68a3d83d98b815ab
--- /dev/null
+++ b/vendor/respect/validation/docs/Regex.md
@@ -0,0 +1,21 @@
+# Regex
+
+- `v::regex(string $regex)`
+
+Evaluates a regex on the input and validates if matches
+
+```php
+v::regex('/[a-z]/')->validate('a'); // true
+```
+
+Message template for this validator includes `{{regex}}`
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
+  * [Contains](Contains.md)
+  * [Digit](Digit.md)
+  * [EndsWith](EndsWith.md)
+  * [StartsWith](StartsWith.md)
diff --git a/vendor/respect/validation/docs/ResourceType.md b/vendor/respect/validation/docs/ResourceType.md
new file mode 100644
index 0000000000000000000000000000000000000000..c21a2f1d89b7a85c966d8eefdd07e3abe4d4e565
--- /dev/null
+++ b/vendor/respect/validation/docs/ResourceType.md
@@ -0,0 +1,21 @@
+# ResourceType
+
+- `v::resourceType()`
+
+Validates if the input is a resource.
+
+```php
+v::resourceType()->validate(fopen('/path/to/file.txt', 'w')); // true
+```
+
+***
+See also:
+
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Roman.md b/vendor/respect/validation/docs/Roman.md
new file mode 100644
index 0000000000000000000000000000000000000000..b619930e1bf61ec67b70c246aa1aaa23bbfafb00
--- /dev/null
+++ b/vendor/respect/validation/docs/Roman.md
@@ -0,0 +1,16 @@
+# Roman
+
+- `v::roman()`
+
+Validates roman numbers
+
+```php
+v::roman()->validate('IV'); // true
+```
+
+***
+See also:
+
+  * [In](In.md)
+  * [Regex](Regex.md)
+  * [Uppercase](Uppercase.md)
diff --git a/vendor/respect/validation/docs/ScalarVal.md b/vendor/respect/validation/docs/ScalarVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..366657854d77bda4e2df7eac79e9787b4c392fc1
--- /dev/null
+++ b/vendor/respect/validation/docs/ScalarVal.md
@@ -0,0 +1,15 @@
+# ScalarVal
+
+- `v::scalarVal()`
+
+Validates if the input is a scalar value.
+
+```php
+v::scalarVal()->validate([]); // false
+v::scalarVal()->validate(135.0); // true
+```
+
+***
+See also:
+
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Sf.md b/vendor/respect/validation/docs/Sf.md
new file mode 100644
index 0000000000000000000000000000000000000000..a7988a8b98d4027c45045556046a7d7169bc4a0b
--- /dev/null
+++ b/vendor/respect/validation/docs/Sf.md
@@ -0,0 +1,19 @@
+# Sf
+
+- `v::sf(string $validator)`
+
+Use Symfony2 validators inside Respect\Validation flow. Messages
+are preserved.
+
+```php
+v::sf('Time')->validate('15:00:00');
+```
+
+
+You must add `"symfony/validator": "~2.6"` to your `require` property on composer.json file.
+
+
+***
+See also:
+
+  * [Zend](Zend.md)
diff --git a/vendor/respect/validation/docs/Size.md b/vendor/respect/validation/docs/Size.md
new file mode 100644
index 0000000000000000000000000000000000000000..13f5aee4e96aec1c383ef7bed1c78a471aa33f6f
--- /dev/null
+++ b/vendor/respect/validation/docs/Size.md
@@ -0,0 +1,48 @@
+# Size
+
+- `v::size(string $minSize)`
+- `v::size(string $minSize, string $maxSize)`
+- `v::size(null, string $maxSize)`
+
+Validates file sizes:
+
+```php
+v::size('1KB')->validate($filename); // Must have at least 1KB size
+v::size('1MB', '2MB')->validate($filename); // Must have the size between 1MB and 2MB
+v::size(null, '1GB')->validate($filename); // Must not be greater than 1GB
+```
+
+Sizes are not case-sensitive and the accepted values are:
+
+- B
+- KB
+- MB
+- GB
+- TB
+- PB
+- EB
+- ZB
+- YB
+
+This validator will consider `SplFileInfo` instances, like:
+
+```php
+$fileInfo = new SplFileInfo($filename);
+v::size('1.5mb')->validate($fileInfo); // Will return true or false
+```
+
+Message template for this validator includes `{{minSize}}` and `{{maxSize}}`.
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Slug.md b/vendor/respect/validation/docs/Slug.md
new file mode 100644
index 0000000000000000000000000000000000000000..599bbbaac904fdef72ddcf7fc753511aa67fc8a7
--- /dev/null
+++ b/vendor/respect/validation/docs/Slug.md
@@ -0,0 +1,17 @@
+# Slug
+
+- `v::slug()`
+
+Validates slug-like strings:
+
+```php
+v::slug()->validate('my-wordpress-title'); // true
+v::slug()->validate('my-wordpress--title'); // false
+v::slug()->validate('my-wordpress-title-'); // false
+```
+
+***
+See also:
+
+  * [Url](Url.md)
+  * [VideoUrl](VideoUrl.md)
diff --git a/vendor/respect/validation/docs/Space.md b/vendor/respect/validation/docs/Space.md
new file mode 100644
index 0000000000000000000000000000000000000000..a0faec57133569ef6457237c0eacd2f9e6782db0
--- /dev/null
+++ b/vendor/respect/validation/docs/Space.md
@@ -0,0 +1,15 @@
+# Space
+
+- `v::space()`
+- `v::space(string $additionalChars)`
+
+Accepts only whitespace:
+
+```php
+v::space()->validate('    '); // true
+```
+
+***
+See also:
+
+  * [Cntrl](Cntrl.md)
diff --git a/vendor/respect/validation/docs/StartsWith.md b/vendor/respect/validation/docs/StartsWith.md
new file mode 100644
index 0000000000000000000000000000000000000000..842655d94b25b1460254e12d1d4618032cf77d5c
--- /dev/null
+++ b/vendor/respect/validation/docs/StartsWith.md
@@ -0,0 +1,31 @@
+# StartsWith
+
+- `v::startsWith(mixed $value)`
+- `v::startsWith(mixed $value, boolean $identical = false)`
+
+This validator is similar to `v::contains()`, but validates
+only if the value is at the beginning of the input.
+
+For strings:
+
+```php
+v::startsWith('lorem')->validate('lorem ipsum'); // true
+```
+
+For arrays:
+
+```php
+v::startsWith('lorem')->validate(['lorem', 'ipsum']); // true
+```
+
+`true` may be passed as a parameter to indicate identical comparison
+instead of equal.
+
+Message template for this validator includes `{{startValue}}`.
+
+***
+See also:
+
+  * [EndsWith](EndsWith.md)
+  * [Contains](Contains.md)
+  * [In](In.md)
diff --git a/vendor/respect/validation/docs/StringType.md b/vendor/respect/validation/docs/StringType.md
new file mode 100644
index 0000000000000000000000000000000000000000..624c3df8cfbe16b0774d69203d9d5d32a5c12f03
--- /dev/null
+++ b/vendor/respect/validation/docs/StringType.md
@@ -0,0 +1,22 @@
+# StringType
+
+- `v::stringType()`
+
+Validates a string.
+
+```php
+v::stringType()->validate('hi'); // true
+```
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [FloatType](FloatType.md)
+  * [IntType](IntType.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/SubdivisionCode.md b/vendor/respect/validation/docs/SubdivisionCode.md
new file mode 100644
index 0000000000000000000000000000000000000000..3cb031922eff171dcac07b05827f9420049fa83c
--- /dev/null
+++ b/vendor/respect/validation/docs/SubdivisionCode.md
@@ -0,0 +1,284 @@
+# SubdivisionCode
+
+- `v::subdivisionCode(string $countryCode)`
+
+Validates subdivision country codes according to [ISO 3166-2][].
+
+The `$countryCode` must be a country in [ISO 3166-1 alpha-2][] format.
+
+```php
+v::subdivisionCode('BR')->validate('SP'); // true
+v::subdivisionCode('US')->validate('CA'); // true
+```
+
+This rule is case sensitive.
+
+## Available country codes
+
+- `AD`: Andorra
+- `AE`: United Arab Emirates
+- `AF`: Afghanistan
+- `AG`: Antigua and Barbuda
+- `AI`: Anguilla
+- `AL`: Albania
+- `AM`: Armenia
+- `AN`: AN.html
+- `AO`: Angola
+- `AQ`: Antarctica
+- `AR`: Argentina
+- `AS`: American Samoa
+- `AT`: Austria
+- `AU`: Australia
+- `AW`: Aruba
+- `AX`: Ã…land
+- `AZ`: Azerbaijan
+- `BA`: Bosnia and Herzegovina
+- `BB`: Barbados
+- `BD`: Bangladesh
+- `BE`: Belgium
+- `BF`: Burkina Faso
+- `BG`: Bulgaria
+- `BH`: Bahrain
+- `BI`: Burundi
+- `BJ`: Benin
+- `BL`: Saint Barthélemy
+- `BM`: Bermuda
+- `BN`: Brunei
+- `BO`: Bolivia
+- `BQ`: Bonaire
+- `BR`: Brazil
+- `BS`: Bahamas
+- `BT`: Bhutan
+- `BV`: Bouvet Island
+- `BW`: Botswana
+- `BY`: Belarus
+- `BZ`: Belize
+- `CA`: Canada
+- `CC`: Cocos [Keeling] Islands
+- `CD`: Democratic Republic of the Congo
+- `CF`: Central African Republic
+- `CG`: Republic of the Congo
+- `CH`: Switzerland
+- `CI`: Ivory Coast
+- `CK`: Cook Islands
+- `CL`: Chile
+- `CM`: Cameroon
+- `CN`: China
+- `CO`: Colombia
+- `CR`: Costa Rica
+- `CS`: CS.html
+- `CU`: Cuba
+- `CV`: Cape Verde
+- `CW`: Curacao
+- `CX`: Christmas Island
+- `CY`: Cyprus
+- `CZ`: Czech Republic
+- `DE`: Germany
+- `DJ`: Djibouti
+- `DK`: Denmark
+- `DM`: Dominica
+- `DO`: Dominican Republic
+- `DZ`: Algeria
+- `EC`: Ecuador
+- `EE`: Estonia
+- `EG`: Egypt
+- `EH`: Western Sahara
+- `ER`: Eritrea
+- `ES`: Spain
+- `ET`: Ethiopia
+- `FI`: Finland
+- `FJ`: Fiji
+- `FK`: Falkland Islands
+- `FM`: Micronesia
+- `FO`: Faroe Islands
+- `FR`: France
+- `GA`: Gabon
+- `GB`: United Kingdom
+- `GD`: Grenada
+- `GE`: Georgia
+- `GF`: French Guiana
+- `GG`: Guernsey
+- `GH`: Ghana
+- `GI`: Gibraltar
+- `GL`: Greenland
+- `GM`: Gambia
+- `GN`: Guinea
+- `GP`: Guadeloupe
+- `GQ`: Equatorial Guinea
+- `GR`: Greece
+- `GS`: South Georgia and the South Sandwich Islands
+- `GT`: Guatemala
+- `GU`: Guam
+- `GW`: Guinea-Bissau
+- `GY`: Guyana
+- `HK`: Hong Kong
+- `HM`: Heard Island and McDonald Islands
+- `HN`: Honduras
+- `HR`: Croatia
+- `HT`: Haiti
+- `HU`: Hungary
+- `ID`: Indonesia
+- `IE`: Ireland
+- `IL`: Israel
+- `IM`: Isle of Man
+- `IN`: India
+- `IO`: British Indian Ocean Territory
+- `IQ`: Iraq
+- `IR`: Iran
+- `IS`: Iceland
+- `IT`: Italy
+- `JE`: Jersey
+- `JM`: Jamaica
+- `JO`: Jordan
+- `JP`: Japan
+- `KE`: Kenya
+- `KG`: Kyrgyzstan
+- `KH`: Cambodia
+- `KI`: Kiribati
+- `KM`: Comoros
+- `KN`: Saint Kitts and Nevis
+- `KP`: North Korea
+- `KR`: South Korea
+- `KW`: Kuwait
+- `KY`: Cayman Islands
+- `KZ`: Kazakhstan
+- `LA`: Laos
+- `LB`: Lebanon
+- `LC`: Saint Lucia
+- `LI`: Liechtenstein
+- `LK`: Sri Lanka
+- `LR`: Liberia
+- `LS`: Lesotho
+- `LT`: Lithuania
+- `LU`: Luxembourg
+- `LV`: Latvia
+- `LY`: Libya
+- `MA`: Morocco
+- `MC`: Monaco
+- `MD`: Moldova
+- `ME`: Montenegro
+- `MF`: Saint Martin
+- `MG`: Madagascar
+- `MH`: Marshall Islands
+- `MK`: Macedonia
+- `ML`: Mali
+- `MM`: Myanmar [Burma]
+- `MN`: Mongolia
+- `MO`: Macao
+- `MP`: Northern Mariana Islands
+- `MQ`: Martinique
+- `MR`: Mauritania
+- `MS`: Montserrat
+- `MT`: Malta
+- `MU`: Mauritius
+- `MV`: Maldives
+- `MW`: Malawi
+- `MX`: Mexico
+- `MY`: Malaysia
+- `MZ`: Mozambique
+- `NA`: Namibia
+- `NC`: New Caledonia
+- `NE`: Niger
+- `NF`: Norfolk Island
+- `NG`: Nigeria
+- `NI`: Nicaragua
+- `NL`: Netherlands
+- `NO`: Norway
+- `NP`: Nepal
+- `NR`: Nauru
+- `NU`: Niue
+- `NZ`: New Zealand
+- `OM`: Oman
+- `PA`: Panama
+- `PE`: Peru
+- `PF`: French Polynesia
+- `PG`: Papua New Guinea
+- `PH`: Philippines
+- `PK`: Pakistan
+- `PL`: Poland
+- `PM`: Saint Pierre and Miquelon
+- `PN`: Pitcairn Islands
+- `PR`: Puerto Rico
+- `PS`: Palestine
+- `PT`: Portugal
+- `PW`: Palau
+- `PY`: Paraguay
+- `QA`: Qatar
+- `RE`: Réunion
+- `RO`: Romania
+- `RS`: Serbia
+- `RU`: Russia
+- `RW`: Rwanda
+- `SA`: Saudi Arabia
+- `SB`: Solomon Islands
+- `SC`: Seychelles
+- `SD`: Sudan
+- `SE`: Sweden
+- `SG`: Singapore
+- `SH`: Saint Helena
+- `SI`: Slovenia
+- `SJ`: Svalbard and Jan Mayen
+- `SK`: Slovakia
+- `SL`: Sierra Leone
+- `SM`: San Marino
+- `SN`: Senegal
+- `SO`: Somalia
+- `SR`: Suriname
+- `SS`: South Sudan
+- `ST`: São Tomé and Príncipe
+- `SV`: El Salvador
+- `SX`: Sint Maarten
+- `SY`: Syria
+- `SZ`: Swaziland
+- `TC`: Turks and Caicos Islands
+- `TD`: Chad
+- `TF`: French Southern Territories
+- `TG`: Togo
+- `TH`: Thailand
+- `TJ`: Tajikistan
+- `TK`: Tokelau
+- `TL`: East Timor
+- `TM`: Turkmenistan
+- `TN`: Tunisia
+- `TO`: Tonga
+- `TR`: Turkey
+- `TT`: Trinidad and Tobago
+- `TV`: Tuvalu
+- `TW`: Taiwan
+- `TZ`: Tanzania
+- `UA`: Ukraine
+- `UG`: Uganda
+- `UM`: U.S. Minor Outlying Islands
+- `US`: United States
+- `UY`: Uruguay
+- `UZ`: Uzbekistan
+- `VA`: Vatican City
+- `VC`: Saint Vincent and the Grenadines
+- `VE`: Venezuela
+- `VG`: British Virgin Islands
+- `VI`: U.S. Virgin Islands
+- `VN`: Vietnam
+- `VU`: Vanuatu
+- `WF`: Wallis and Futuna
+- `WS`: Samoa
+- `XK`: Kosovo
+- `YE`: Yemen
+- `YT`: Mayotte
+- `ZA`: South Africa
+- `ZM`: Zambia
+- `ZW`: Zimbabwe
+
+All data was extrated from [GeoNames][] which is licensed under a
+[Creative Commons Attribution 3.0 License][].
+
+***
+See also:
+
+  * [CountryCode](CountryCode.md)
+  * [Tld](Tld.md)
+
+
+[Creative Commons Attribution 3.0 License]: http://creativecommons.org/licenses/by/3.0 "Creative Commons Attribution 3.0 License"
+[GeoNames]: http://www.geonames.org "GetNames"
+[ISO 3166-1 alpha-2]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 "ISO 3166-1 alpha-2"
+[ISO 3166-2]: http://en.wikipedia.org/wiki/ISO_3166-2 "ISO 3166-2"
diff --git a/vendor/respect/validation/docs/SymbolicLink.md b/vendor/respect/validation/docs/SymbolicLink.md
new file mode 100644
index 0000000000000000000000000000000000000000..bc9019657bc68072e439020da43c0169169eab43
--- /dev/null
+++ b/vendor/respect/validation/docs/SymbolicLink.md
@@ -0,0 +1,23 @@
+# SymbolicLink
+
+- `v::symbolicLink()`
+
+Validates if the given data is a path of a valid symbolic link.
+
+```php
+v::symbolicLink()->validate('/path/of/valid/symbolic/link'); // true
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Tld.md b/vendor/respect/validation/docs/Tld.md
new file mode 100644
index 0000000000000000000000000000000000000000..db05452a196958e19b794707740c69487c99d5a2
--- /dev/null
+++ b/vendor/respect/validation/docs/Tld.md
@@ -0,0 +1,17 @@
+# Tld
+
+- `v::tld()`
+
+Validates a top-level domain
+
+```php
+v::tld()->validate('com'); // true
+v::tld()->validate('ly'); // true
+v::tld()->validate('org'); // true
+```
+
+***
+See also:
+
+ * [Domain](Domain.md)
+ * [CountryCode](CountryCode.md)
diff --git a/vendor/respect/validation/docs/TrueVal.md b/vendor/respect/validation/docs/TrueVal.md
new file mode 100644
index 0000000000000000000000000000000000000000..59869d200419e5db273de2f4fa7c6bb30847dbd7
--- /dev/null
+++ b/vendor/respect/validation/docs/TrueVal.md
@@ -0,0 +1,21 @@
+# TrueVal
+
+- `v::trueVal()`
+
+Validates if a value is considered as `true`.
+
+```php
+v::trueVal()->validate(true); // true
+v::trueVal()->validate(1); // true
+v::trueVal()->validate('1'); // true
+v::trueVal()->validate('true'); // true
+v::trueVal()->validate('on'); // true
+v::trueVal()->validate('yes'); // true
+v::trueVal()->validate('0.5'); // false
+v::trueVal()->validate('2'); // false
+```
+
+***
+See also:
+
+  * [FalseVal](FalseVal.md)
diff --git a/vendor/respect/validation/docs/Type.md b/vendor/respect/validation/docs/Type.md
new file mode 100644
index 0000000000000000000000000000000000000000..50f2abb9f9a75a2e1fa087a69b38274ad45d8631
--- /dev/null
+++ b/vendor/respect/validation/docs/Type.md
@@ -0,0 +1,31 @@
+# Type
+
+- `v::type(string $type)`
+
+Validates the type of input.
+
+```php
+v::type('bool')->validate(true); // true
+v::type('callable')->validate(function (){}); // true
+v::type('object')->validate(new stdClass()); // true
+```
+
+***
+See also:
+
+  * [ArrayVal](ArrayVal.md)
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [Finite](Finite.md)
+  * [FloatType](FloatType.md)
+  * [FloatVal](FloatVal.md)
+  * [Infinite](Infinite.md)
+  * [Instance](Instance.md)
+  * [IntType](IntType.md)
+  * [IntVal](IntVal.md)
+  * [NullType](NullType.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [ScalarVal](ScalarVal.md)
+  * [StringType](StringType.md)
+  * [Type](Type.md)
diff --git a/vendor/respect/validation/docs/Uploaded.md b/vendor/respect/validation/docs/Uploaded.md
new file mode 100644
index 0000000000000000000000000000000000000000..774f9bb8216835034c4fa9c02263dfe2c9f898f5
--- /dev/null
+++ b/vendor/respect/validation/docs/Uploaded.md
@@ -0,0 +1,23 @@
+# Uploaded
+
+- `v::uploaded()`
+
+Validates if the given data is a file that was uploaded via HTTP POST.
+
+```php
+v::uploaded()->validate('/path/of/an/uploaded/file'); // true
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Writable](Writable.md)
diff --git a/vendor/respect/validation/docs/Uppercase.md b/vendor/respect/validation/docs/Uppercase.md
new file mode 100644
index 0000000000000000000000000000000000000000..1dff7acf584a5ee43724526f6ff729879521ef2e
--- /dev/null
+++ b/vendor/respect/validation/docs/Uppercase.md
@@ -0,0 +1,14 @@
+# Uppercase
+
+- `v::uppercase()`
+
+Validates if string characters are uppercase in the input:
+
+```php
+v::stringType()->uppercase()->validate('W3C'); // true
+```
+
+***
+See also:
+
+  * [Lowercase](Lowercase.md)
diff --git a/vendor/respect/validation/docs/Url.md b/vendor/respect/validation/docs/Url.md
new file mode 100644
index 0000000000000000000000000000000000000000..5638cf55f4b364edceea324d80904c3f87ce3178
--- /dev/null
+++ b/vendor/respect/validation/docs/Url.md
@@ -0,0 +1,24 @@
+# Url
+
+- `v::url()`
+
+Validates if input is an URL:
+
+```php
+v::url()->validate('http://example.com'); // true
+v::url()->validate('https://www.youtube.com/watch?v=6FOUqQt3Kg0'); // true
+v::url()->validate('ldap://[::1]'); // true
+v::url()->validate('mailto:john.doe@example.com'); // true
+v::url()->validate('news:new.example.com'); // true
+```
+
+This rule uses [FilterVar](FilterVar.md)
+
+***
+See also:
+
+  * [Domain](Domain.md)
+  * [Email](Email.md)
+  * [FilterVar](FilterVar.md)
+  * [Phone](Phone.md)
+  * [VideoUrl](VideoUrl.md)
diff --git a/vendor/respect/validation/docs/VALIDATORS.md b/vendor/respect/validation/docs/VALIDATORS.md
new file mode 100644
index 0000000000000000000000000000000000000000..4804cbee39d14c11fbdd5325884fbd9399c06964
--- /dev/null
+++ b/vendor/respect/validation/docs/VALIDATORS.md
@@ -0,0 +1,338 @@
+# Validators
+
+## Types
+
+  * [ArrayVal](ArrayVal.md)
+  * [ArrayType](ArrayType.md)
+  * [BoolVal](BoolVal.md)
+  * [BoolType](BoolType.md)
+  * [CallableType](CallableType.md)
+  * [Countable](Countable.md)
+  * [Date](Date.md)
+  * [FalseVal](FalseVal.md)
+  * [FloatVal](FloatVal.md)
+  * [FloatType](FloatType.md)
+  * [Instance](Instance.md)
+  * [IntVal](IntVal.md)
+  * [IntType](IntType.md)
+  * [IterableType](IterableType.md)
+  * [NullType](NullType.md)
+  * [Numeric](Numeric.md)
+  * [ObjectType](ObjectType.md)
+  * [ResourceType](ResourceType.md)
+  * [ScalarVal](ScalarVal.md)
+  * [StringType](StringType.md)
+  * [TrueVal](TrueVal.md)
+  * [Type](Type.md)
+  * [Xdigit](Xdigit.md)
+
+## Generics
+
+  * [AlwaysInvalid](AlwaysInvalid.md)
+  * [AlwaysValid](AlwaysValid.md)
+  * [Call](Call.md)
+  * [Callback](Callback.md)
+  * [FilterVar](FilterVar.md)
+  * [Not](Not.md)
+  * [Optional](Optional.md)
+  * [Type](Type.md)
+  * [When](When.md)
+
+## Comparing Values
+
+  * [Age](Age.md)
+  * [Between](Between.md)
+  * [Equals](Equals.md)
+  * [Identical](Identical.md)
+  * [Max](Max.md)
+  * [Min](Min.md)
+
+## Numeric
+
+  * [Between](Between.md)
+  * [BoolType](BoolType.md)
+  * [Even](Even.md)
+  * [Factor](Factor.md)
+  * [Fibonacci](Fibonacci.md)
+  * [Finite](Finite.md)
+  * [FloatVal](FloatVal.md)
+  * [FloatType](FloatType.md)
+  * [Infinite](Infinite.md)
+  * [IntVal](IntVal.md)
+  * [IntType](IntType.md)
+  * [Multiple](Multiple.md)
+  * [Negative](Negative.md)
+  * [NotEmpty](NotEmpty.md)
+  * [Numeric](Numeric.md)
+  * [Odd](Odd.md)
+  * [PerfectSquare](PerfectSquare.md)
+  * [Positive](Positive.md)
+  * [PrimeNumber](PrimeNumber.md)
+  * [Roman](Roman.md)
+  * [Xdigit](Xdigit.md)
+
+## String
+
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
+  * [Between](Between.md)
+  * [Charset](Charset.md)
+  * [Cntrl](Cntrl.md)
+  * [Consonant](Consonant.md)
+  * [Contains](Contains.md)
+  * [Digit](Digit.md)
+  * [EndsWith](EndsWith.md)
+  * [Graph](Graph.md)
+  * [In](In.md)
+  * [Length](Length.md)
+  * [Lowercase](Lowercase.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NoWhitespace](NoWhitespace.md)
+  * [PhpLabel](PhpLabel.md)
+  * [Prnt](Prnt.md)
+  * [Punct](Punct.md)
+  * [Regex](Regex.md)
+  * [ResourceType](ResourceType.md)
+  * [Slug](Slug.md)
+  * [Space](Space.md)
+  * [StartsWith](StartsWith.md)
+  * [Uppercase](Uppercase.md)
+  * [Version](Version.md)
+  * [Vowel](Vowel.md)
+  * [Xdigit](Xdigit.md)
+
+## Arrays
+
+  * [ArrayVal](ArrayVal.md)
+  * [ArrayType](ArrayType.md)
+  * [Contains](Contains.md)
+  * [Each](Each.md)
+  * [EndsWith](EndsWith.md)
+  * [In](In.md)
+  * [Key](Key.md)
+  * [KeyNested](KeyNested.md)
+  * [KeySet](KeySet.md)
+  * [KeyValue](KeyValue.md)
+  * [Length](Length.md)
+  * [NotEmpty](NotEmpty.md)
+  * [StartsWith](StartsWith.md)
+
+## Objects
+
+  * [Attribute](Attribute.md)
+  * [Instance](Instance.md)
+  * [Length](Length.md)
+
+## Date and Time
+
+  * [Age](Age.md)
+  * [Between](Between.md)
+  * [Date](Date.md)
+  * [LeapDate](LeapDate.md)
+  * [LeapYear](LeapYear.md)
+  * [MinimumAge](MinimumAge.md)
+
+## Group Validators
+
+  * [AllOf](AllOf.md)
+  * [NoneOf](NoneOf.md)
+  * [OneOf](OneOf.md)
+
+## Regional
+
+  * [CountryCode](CountryCode.md)
+  * [CurrencyCode](CurrencyCode.md)
+  * [IdentityCard](IdentityCard.md)
+  * [LanguageCode](LanguageCode.md)
+  * [PostalCode](PostalCode.md)
+  * [SubdivisionCode](SubdivisionCode.md)
+  * [Tld](Tld.md)
+
+## Files
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Image](Image.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
+  * [Writable](Writable.md)
+
+## Banking
+
+  * [Bank](Bank.md)
+  * [BankAccount](BankAccount.md)
+  * [Bic](Bic.md)
+
+## Other
+
+  * [Bsn](Bsn.md)
+  * [Cnh](Cnh.md)
+  * [Cnpj](Cnpj.md)
+  * [Cpf](Cpf.md)
+  * [Domain](Domain.md)
+  * [Email](Email.md)
+  * [HexRgbColor](HexRgbColor.md)
+  * [Imei](Imei.md)
+  * [Ip](Ip.md)
+  * [Json](Json.md)
+  * [MacAddress](MacAddress.md)
+  * [NfeAccessKey](NfeAccessKey.md)
+  * [NotBlank](NotBlank.md)
+  * [NotOptional](NotOptional.md)
+  * [Pesel](Pesel.md)
+  * [Phone](Phone.md)
+  * [Sf](Sf.md)
+  * [Url](Url.md)
+  * [VideoUrl](VideoUrl.md)
+  * [Zend](Zend.md)
+
+## Yes/No
+
+  * [No](No.md)
+  * [Yes](Yes.md)
+
+## Alphabetically
+
+  * [Age](Age.md)
+  * [AllOf](AllOf.md)
+  * [Alnum](Alnum.md)
+  * [Alpha](Alpha.md)
+  * [AlwaysInvalid](AlwaysInvalid.md)
+  * [AlwaysValid](AlwaysValid.md)
+  * [ArrayVal](ArrayVal.md)
+  * [ArrayType](ArrayType.md)
+  * [Attribute](Attribute.md)
+  * [Bank](Bank.md)
+  * [BankAccount](BankAccount.md)
+  * [Between](Between.md)
+  * [Bic](Bic.md)
+  * [BoolType](BoolType.md)
+  * [Bsn](Bsn.md)
+  * [Call](Call.md)
+  * [CallableType](CallableType.md)
+  * [Callback](Callback.md)
+  * [Charset](Charset.md)
+  * [Cnh](Cnh.md)
+  * [Cnpj](Cnpj.md)
+  * [Cntrl](Cntrl.md)
+  * [Consonant](Consonant.md)
+  * [Contains](Contains.md)
+  * [Countable](Countable.md)
+  * [CountryCode](CountryCode.md)
+  * [Cpf](Cpf.md)
+  * [CreditCard](CreditCard.md)
+  * [Date](Date.md)
+  * [Digit](Digit.md)
+  * [Directory](Directory.md)
+  * [Domain](Domain.md)
+  * [Each](Each.md)
+  * [Email](Email.md)
+  * [EndsWith](EndsWith.md)
+  * [Equals](Equals.md)
+  * [Even](Even.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [Factor](Factor.md)
+  * [FalseVal](FalseVal.md)
+  * [Fibonacci](Fibonacci.md)
+  * [File](File.md)
+  * [FilterVar](FilterVar.md)
+  * [Finite](Finite.md)
+  * [FloatVal](FloatVal.md)
+  * [FloatType](FloatType.md)
+  * [Graph](Graph.md)
+  * [HexRgbColor](HexRgbColor.md)
+  * [Identical](Identical.md)
+  * [IdentityCard](IdentityCard.md)
+  * [Image](Image.md)
+  * [Imei](Imei.md)
+  * [In](In.md)
+  * [Infinite](Infinite.md)
+  * [Instance](Instance.md)
+  * [IntVal](IntVal.md)
+  * [IntType](IntType.md)
+  * [Ip](Ip.md)
+  * [IterableType](IterableType.md)
+  * [Json](Json.md)
+  * [Key](Key.md)
+  * [KeyNested](KeyNested.md)
+  * [KeySet](KeySet.md)
+  * [KeyValue](KeyValue.md)
+  * [LanguageCode](LanguageCode.md)
+  * [LeapDate](LeapDate.md)
+  * [LeapYear](LeapYear.md)
+  * [Length](Length.md)
+  * [Lowercase](Lowercase.md)
+  * [MacAddress](MacAddress.md)
+  * [Max](Max.md)
+  * [Mimetype](Mimetype.md)
+  * [Min](Min.md)
+  * [MinimumAge](MinimumAge.md)
+  * [Multiple](Multiple.md)
+  * [Negative](Negative.md)
+  * [NfeAccessKey](NfeAccessKey.md)
+  * [No](No.md)
+  * [NoWhitespace](NoWhitespace.md)
+  * [NoneOf](NoneOf.md)
+  * [Not](Not.md)
+  * [NotBlank](NotBlank.md)
+  * [NotEmpty](NotEmpty.md)
+  * [NotOptional](NotOptional.md)
+  * [NullType](NullType.md)
+  * [Numeric](Numeric.md)
+  * [ObjectType](ObjectType.md)
+  * [Odd](Odd.md)
+  * [OneOf](OneOf.md)
+  * [Optional](Optional.md)
+  * [PerfectSquare](PerfectSquare.md)
+  * [Pesel](Pesel.md)
+  * [Phone](Phone.md)
+  * [PhpLabel](PhpLabel.md)
+  * [Positive](Positive.md)
+  * [PostalCode](PostalCode.md)
+  * [PrimeNumber](PrimeNumber.md)
+  * [Prnt](Prnt.md)
+  * [Punct](Punct.md)
+  * [Readable](Readable.md)
+  * [Regex](Regex.md)
+  * [ResourceType](ResourceType.md)
+  * [Roman](Roman.md)
+  * [ScalarVal](ScalarVal.md)
+  * [Sf](Sf.md)
+  * [Size](Size.md)
+  * [Slug](Slug.md)
+  * [Space](Space.md)
+  * [StartsWith](StartsWith.md)
+  * [StringType](StringType.md)
+  * [SubdivisionCode](SubdivisionCode.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Tld](Tld.md)
+  * [TrueVal](TrueVal.md)
+  * [Type](Type.md)
+  * [Uploaded](Uploaded.md)
+  * [Uppercase](Uppercase.md)
+  * [Url](Url.md)
+  * [Version](Version.md)
+  * [VideoUrl](VideoUrl.md)
+  * [Vowel](Vowel.md)
+  * [When](When.md)
+  * [Writable](Writable.md)
+  * [Xdigit](Xdigit.md)
+  * [Yes](Yes.md)
+  * [Zend](Zend.md)
+
+***
+See also:
+
+- [Contributing](../CONTRIBUTING.md)
+- [Feature Guide](README.md)
+- [Installation](INSTALL.md)
+- [License](../LICENSE.md)
+- [Changelog](../CHANGELOG.md)
diff --git a/vendor/respect/validation/docs/Version.md b/vendor/respect/validation/docs/Version.md
new file mode 100644
index 0000000000000000000000000000000000000000..aad3ce8a3d02bc333d3bff0c11a9b359a67c66c7
--- /dev/null
+++ b/vendor/respect/validation/docs/Version.md
@@ -0,0 +1,16 @@
+# Version
+
+- `v::version()`
+
+Validates version numbers using Semantic Versioning.
+
+```php
+v::version()->validate('1.0.0');
+```
+
+***
+See also:
+
+  * [Equals](Equals.md)
+  * [Regex](Regex.md)
+  * [Roman](Roman.md)
diff --git a/vendor/respect/validation/docs/VideoUrl.md b/vendor/respect/validation/docs/VideoUrl.md
new file mode 100644
index 0000000000000000000000000000000000000000..1ef962793bdc6082f57ad70d42f059a06095ca5a
--- /dev/null
+++ b/vendor/respect/validation/docs/VideoUrl.md
@@ -0,0 +1,35 @@
+# VideoUrl
+
+- `v::videoUrl()`
+- `v::videoUrl(string $service)`
+
+Validates if the input is a video URL value:
+
+```php
+v::videoUrl()->validate('https://player.vimeo.com/video/71787467'); // true
+v::videoUrl()->validate('https://vimeo.com/71787467'); // true
+v::videoUrl()->validate('https://www.youtube.com/embed/netHLn9TScY'); // true
+v::videoUrl()->validate('https://www.youtube.com/watch?v=netHLn9TScY'); // true
+v::videoUrl()->validate('https://youtu.be/netHLn9TScY'); // true
+
+v::videoUrl('youtube')->validate('https://www.youtube.com/watch?v=netHLn9TScY'); // true
+v::videoUrl('vimeo')->validate('https://vimeo.com/71787467'); // true
+
+v::videoUrl()->validate('https://youtube.com'); // false
+v::videoUrl('youtube')->validate('https://vimeo.com/71787467'); // false
+```
+
+The services accepted are:
+
+- YouTube
+- Vimeo
+
+The `$service` value is not case-sensitive.
+
+Message template for this validator includes `{{service}}`.
+
+
+***
+See also:
+
+  * [Url](Url.md)
diff --git a/vendor/respect/validation/docs/Vowel.md b/vendor/respect/validation/docs/Vowel.md
new file mode 100644
index 0000000000000000000000000000000000000000..98d806f5d90b39658d61d9e69dec3d86b5330e2f
--- /dev/null
+++ b/vendor/respect/validation/docs/Vowel.md
@@ -0,0 +1,17 @@
+# Vowel
+
+- `v::vowel()`
+
+Similar to `v::alnum()`. Validates strings that contains only vowels:
+
+```php
+v::vowel()->validate('aei'); // true
+```
+
+***
+See also:
+
+  * [Alnum](Alnum.md)
+  * [Digit](Digit.md)
+  * [Alpha](Alpha.md)
+  * [Consonant](Consonant.md)
diff --git a/vendor/respect/validation/docs/When.md b/vendor/respect/validation/docs/When.md
new file mode 100644
index 0000000000000000000000000000000000000000..6254cb34d991733bd29c9b2281bad838f362a24e
--- /dev/null
+++ b/vendor/respect/validation/docs/When.md
@@ -0,0 +1,24 @@
+# When
+
+- `v::when(v $if, v $then, v $else)`
+- `v::when(v $if, v $then)`
+
+A ternary validator that accepts three parameters.
+
+When the `$if` validates, returns validation for `$then`.
+When the `$if` doesn't validate, returns validation for `$else`, if defined.
+
+```php
+v::when(v::intVal(), v::positive(), v::notEmpty())->validate($input);
+```
+
+In the sample above, if `$input` is an integer, then it must be positive.
+If `$input` is not an integer, then it must not me empty.
+When `$else` is not defined use [AlwaysInvalid](AlwaysInvalid.md)
+
+***
+See also:
+
+  * [AllOf](AllOf.md)
+  * [OneOf](OneOf.md)
+  * [NoneOf](NoneOf.md)
diff --git a/vendor/respect/validation/docs/Writable.md b/vendor/respect/validation/docs/Writable.md
new file mode 100644
index 0000000000000000000000000000000000000000..b7aa5e436534c6fee4bdf42b5fdafefc7494b08f
--- /dev/null
+++ b/vendor/respect/validation/docs/Writable.md
@@ -0,0 +1,23 @@
+# Writable
+
+- `v::writable()`
+
+Validates if the given input is writable file.
+
+```php
+v::writable()->validate('/path/of/a/writable/file'); // true
+```
+
+***
+See also:
+
+  * [Directory](Directory.md)
+  * [Executable](Executable.md)
+  * [Exists](Exists.md)
+  * [Extension](Extension.md)
+  * [File](File.md)
+  * [Mimetype](Mimetype.md)
+  * [Readable](Readable.md)
+  * [Size](Size.md)
+  * [SymbolicLink](SymbolicLink.md)
+  * [Uploaded](Uploaded.md)
diff --git a/vendor/respect/validation/docs/Xdigit.md b/vendor/respect/validation/docs/Xdigit.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e79d0fdfc6b52ac263f8748ce5dc03c778c9c81
--- /dev/null
+++ b/vendor/respect/validation/docs/Xdigit.md
@@ -0,0 +1,22 @@
+# Xdigit
+
+- `v::xdigit()`
+
+Accepts an hexadecimal number:
+
+```php
+v::xdigit()->validate('abc123'); // true
+```
+
+Notice, however, that it doesn't accept strings starting with 0x:
+
+```php
+v::xdigit()->validate('0x1f'); // false
+```
+
+***
+See also:
+
+  * [Digit](Digit.md)
+  * [Alnum](Alnum.md)
+  * [HexRgbColor](HexRgbColor.md)
diff --git a/vendor/respect/validation/docs/Yes.md b/vendor/respect/validation/docs/Yes.md
new file mode 100644
index 0000000000000000000000000000000000000000..9fef6d8f4d6b0e02e6b9dab619c39451b9f83db6
--- /dev/null
+++ b/vendor/respect/validation/docs/Yes.md
@@ -0,0 +1,23 @@
+# Yes
+
+- `v::yes()`
+- `v::yes(boolean $locale)`
+
+Validates if value is considered as "Yes".
+
+```php
+v::yes()->validate('Y'); // true
+v::yes()->validate('Yea'); // true
+v::yes()->validate('Yeah'); // true
+v::yes()->validate('Yep'); // true
+v::yes()->validate('Yes'); // true
+```
+
+This rule is case insensitive.
+
+If `$locale` is TRUE, uses the value of [nl_langinfo()](http://php.net/nl_langinfo) with `YESEXPR` constant.
+
+***
+See also:
+
+  * [No](No.md)
diff --git a/vendor/respect/validation/docs/Zend.md b/vendor/respect/validation/docs/Zend.md
new file mode 100644
index 0000000000000000000000000000000000000000..8ec0ae8ed7ff8daf197e3ef1b5e42ed594ca2b94
--- /dev/null
+++ b/vendor/respect/validation/docs/Zend.md
@@ -0,0 +1,17 @@
+# Zend
+
+- `v::zend(mixed $validator)`
+
+Use Zend validators inside Respect\Validation flow. Messages
+are preserved.
+
+```php
+v::zend('Hostname')->validate('google.com');
+```
+
+You must add `"zendframework/zend-validator": "~2.3"` to your `require` property on composer.json file.
+
+***
+See also:
+
+  * [Sf](Sf.md)