diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
index 67e5bc4..becf49e 100644
--- a/app/Exceptions/Handler.php
+++ b/app/Exceptions/Handler.php
@@ -6,7 +6,7 @@ use Exception;
 use Illuminate\Auth\Access\AuthorizationException;
 use Illuminate\Auth\AuthenticationException;
 use Illuminate\Database\Eloquent\ModelNotFoundException;
-use Illuminate\Http\Exception\HttpResponseException;
+use Illuminate\Http\Exceptions\HttpResponseException;
 use Illuminate\Session\TokenMismatchException;
 use Illuminate\Validation\ValidationException;
 use Symfony\Component\HttpKernel\Exception\HttpException;
diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php
index 66affea..291935b 100644
--- a/app/Http/Controllers/ActivityController.php
+++ b/app/Http/Controllers/ActivityController.php
@@ -24,6 +24,7 @@ class ActivityController extends Controller
      */
     public function __construct(ActivityRepository $activities)
     {
+        $this->middleware('auth');
         $this->middleware('permission:users.activity');
         $this->activities = $activities;
     }
diff --git a/app/Http/Controllers/Auth/SocialAuthController.php b/app/Http/Controllers/Auth/SocialAuthController.php
index ffe75e0..a71a898 100644
--- a/app/Http/Controllers/Auth/SocialAuthController.php
+++ b/app/Http/Controllers/Auth/SocialAuthController.php
@@ -188,7 +188,7 @@ class SocialAuthController extends Controller
      */
     private function handleMissingEmail($socialUser)
     {
-        Session::set('social.user', $socialUser);
+        Session::put('social.user', $socialUser);
 
         return redirect()->to('auth/twitter/email');
     }
@@ -201,6 +201,11 @@ class SocialAuthController extends Controller
      */
     private function loginAndRedirect($user)
     {
+        if ($user->isBanned()) {
+            return redirect()->to('login')
+                ->withErrors(trans('app.your_account_is_banned'));
+        }
+
         if (settings('2fa.enabled') && Authy::isEnabled($user)) {
             session()->put('auth.2fa.id', $user->id);
             return redirect()->route('auth.token');
diff --git a/app/Http/Controllers/InstallController.php b/app/Http/Controllers/InstallController.php
index 6205e9d..7e57338 100644
--- a/app/Http/Controllers/InstallController.php
+++ b/app/Http/Controllers/InstallController.php
@@ -70,7 +70,7 @@ class InstallController extends Controller
                 ->withErrors("Connection to your database cannot be established. Please provide correct database credentials.");
         }
 
-        Session::set('install.db_credentials', $dbCredentials);
+        Session::put('install.db_credentials', $dbCredentials);
 
         return view('install.installation');
     }
diff --git a/app/Http/Controllers/PermissionsController.php b/app/Http/Controllers/PermissionsController.php
index 1863fa3..f4c12de 100644
--- a/app/Http/Controllers/PermissionsController.php
+++ b/app/Http/Controllers/PermissionsController.php
@@ -33,6 +33,7 @@ class PermissionsController extends Controller
      */
     public function __construct(RoleRepository $roles, PermissionRepository $permissions)
     {
+        $this->middleware('auth');
         $this->middleware('permission:permissions.manage');
         $this->roles = $roles;
         $this->permissions = $permissions;
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index cd9d20c..b40b6b4 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -100,9 +100,16 @@ class ProfileController extends Controller
      */
     public function updateAvatar(Request $request, UserAvatarManager $avatarManager)
     {
-        $name = $avatarManager->uploadAndCropAvatar($this->theUser);
+        $this->validate($request, [
+            'avatar' => 'image'
+        ]);
 
-        return $this->handleAvatarUpdate($name);
+        if ($name = $avatarManager->uploadAndCropAvatar($this->theUser)) {
+            return $this->handleAvatarUpdate($name);
+        }
+
+        return redirect()->route('profile')
+            ->withErrors(trans('app.avatar_not_changed'));
     }
 
     /**
diff --git a/app/Http/Controllers/RolesController.php b/app/Http/Controllers/RolesController.php
index 1ecfd4c..2d5309e 100644
--- a/app/Http/Controllers/RolesController.php
+++ b/app/Http/Controllers/RolesController.php
@@ -31,6 +31,7 @@ class RolesController extends Controller
      */
     public function __construct(RoleRepository $roles)
     {
+        $this->middleware('auth');
         $this->middleware('permission:roles.manage');
         $this->roles = $roles;
     }
diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php
index 77352ea..25fca49 100644
--- a/app/Http/Controllers/SettingsController.php
+++ b/app/Http/Controllers/SettingsController.php
@@ -12,6 +12,11 @@ use Settings;
  */
 class SettingsController extends Controller
 {
+    public function __construct()
+    {
+        $this->middleware('auth');
+    }
+
     /**
      * Display general settings page.
      *
diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php
index caae686..90847b9 100644
--- a/app/Http/Controllers/UsersController.php
+++ b/app/Http/Controllers/UsersController.php
@@ -197,16 +197,21 @@ class UsersController extends Controller
      * @param UserAvatarManager $avatarManager
      * @return mixed
      */
-    public function updateAvatar(User $user, UserAvatarManager $avatarManager)
+    public function updateAvatar(User $user, UserAvatarManager $avatarManager, Request $request)
     {
-        $name = $avatarManager->uploadAndCropAvatar($user);
+        $this->validate($request, ['avatar' => 'image']);
 
-        $this->users->update($user->id, ['avatar' => $name]);
+        if ($name = $avatarManager->uploadAndCropAvatar($user)) {
+            $this->users->update($user->id, ['avatar' => $name]);
 
-        event(new UpdatedByAdmin($user));
+            event(new UpdatedByAdmin($user));
+
+            return redirect()->route('user.edit', $user->id)
+                ->withSuccess(trans('app.avatar_changed'));
+        }
 
         return redirect()->route('user.edit', $user->id)
-            ->withSuccess(trans('app.avatar_changed'));
+            ->withErrors(trans('app.avatar_not_changed'));
     }
 
     /**
diff --git a/app/Http/Middleware/SocialLogin.php b/app/Http/Middleware/SocialLogin.php
index 2089644..ec9be61 100644
--- a/app/Http/Middleware/SocialLogin.php
+++ b/app/Http/Middleware/SocialLogin.php
@@ -16,7 +16,7 @@ class SocialLogin
      */
     public function handle($request, Closure $next)
     {
-        $provider = $request->route()->getParameter('provider');
+        $provider = $request->route()->parameter('provider');
 
         if (! in_array($provider, config('auth.social.providers'))) {
             throw new NotFoundHttpException;
diff --git a/app/Listeners/RoleEventsSubscriber.php b/app/Listeners/RoleEventsSubscriber.php
index 730ac6c..fdcf618 100644
--- a/app/Listeners/RoleEventsSubscriber.php
+++ b/app/Listeners/RoleEventsSubscriber.php
@@ -2,18 +2,16 @@
 
 namespace Portal\Listeners;
 
-use Portal\Activity;
 use Portal\Events\Role\Created;
 use Portal\Events\Role\PermissionsUpdated;
 use Portal\Events\Role\Updated;
 use Portal\Events\Role\Deleted;
-use Portal\Events\User\UserEventContract;
 use Portal\Services\Logging\UserActivity\Logger;
 
 class RoleEventsSubscriber
 {
     /**
-     * @var UserActivityLogger
+     * @var Logger
      */
     private $logger;
 
diff --git a/app/Providers/HtmlServiceProvider.php b/app/Providers/HtmlServiceProvider.php
index 6f9a049..eafadbc 100644
--- a/app/Providers/HtmlServiceProvider.php
+++ b/app/Providers/HtmlServiceProvider.php
@@ -25,10 +25,10 @@ class HtmlServiceProvider extends BaseHtmlServiceProvider
         $this->app->singleton('form', function($app) {
 
             if (env('FORCE_SSL')) {
-                $app['url']->forceSchema('https');
+                $app['url']->forceScheme('https');
             }
 
-            $form = new FormBuilder($app['html'], $app['url'], $app['view'], $app['session.store']->getToken());
+            $form = new FormBuilder($app['html'], $app['url'], $app['view'], $app['session.store']->token());
 
             return $form->setSessionStore($app['session.store']);
         });
diff --git a/app/Repositories/Session/DbSession.php b/app/Repositories/Session/DbSession.php
index be1a74d..c5d93cd 100644
--- a/app/Repositories/Session/DbSession.php
+++ b/app/Repositories/Session/DbSession.php
@@ -2,6 +2,7 @@
 
 namespace Portal\Repositories\Session;
 
+use Carbon\Carbon;
 use Portal\Repositories\User\UserRepository;
 use DB;
 
@@ -26,8 +27,11 @@ class DbSession implements SessionRepository
      */
     public function getUserSessions($userId)
     {
+        $validTimestamp = Carbon::now()->subMinutes(config('session.lifetime'))->timestamp;
+
         return DB::table('sessions')
             ->where('user_id', $userId)
+            ->where('last_activity', '>=', $validTimestamp)
             ->get(['id', 'ip_address', 'user_agent', 'last_activity'])
             ->all();
     }
diff --git a/app/Repositories/User/EloquentUser.php b/app/Repositories/User/EloquentUser.php
index 405f89b..bb0ba23 100644
--- a/app/Repositories/User/EloquentUser.php
+++ b/app/Repositories/User/EloquentUser.php
@@ -117,7 +117,7 @@ class EloquentUser implements UserRepository
      */
     public function update($id, array $data)
     {
-        if (array_get($data, 'country_id') == 0) {
+        if (! array_get($data, 'country_id')) {
             $data['country_id'] = null;
         }
 
diff --git a/app/Services/Auth/TwoFactor/Authenticatable.php b/app/Services/Auth/TwoFactor/Authenticatable.php
index d5d55af..8254942 100644
--- a/app/Services/Auth/TwoFactor/Authenticatable.php
+++ b/app/Services/Auth/TwoFactor/Authenticatable.php
@@ -2,12 +2,8 @@
 
 namespace Portal\Services\Auth\TwoFactor;
 
-use Illuminate\Auth\Authenticatable as BaseAuthenticatable;
-
 trait Authenticatable
 {
-    use BaseAuthenticatable;
-
     /**
      * Get the e-mail address used for two-factor authentication.
      *
diff --git a/app/Services/Upload/UserAvatarManager.php b/app/Services/Upload/UserAvatarManager.php
index 5b8c3d0..f4be86a 100644
--- a/app/Services/Upload/UserAvatarManager.php
+++ b/app/Services/Upload/UserAvatarManager.php
@@ -49,7 +49,14 @@ class UserAvatarManager
     {
         list($name, $avatarImage) = $this->uploadFile($user);
 
-        $this->cropAndResizeImage($avatarImage);
+        try {
+            $this->cropAndResizeImage($avatarImage);
+            $this->deleteAvatarIfUploaded($user);
+        } catch (\Exception $e) {
+            logger("Cannot upload avatar. " . $e->getMessage());
+            $this->fs->delete($this->getDestinationDirectory() . "/" . $name);
+            return null;
+        }
 
         return $name;
     }
@@ -86,8 +93,6 @@ class UserAvatarManager
      */
     private function uploadFile(User $user)
     {
-        $this->deleteAvatarIfUploaded($user);
-
         $name = $this->generateAvatarName();
         $uploadedFile = $this->getUploadedFileFromRequest();
 
diff --git a/app/User.php b/app/User.php
index 119b963..9182065 100644
--- a/app/User.php
+++ b/app/User.php
@@ -2,7 +2,6 @@
 
 namespace Portal;
 
-use Illuminate\Notifications\Messages\MailMessage;
 use Illuminate\Notifications\Notifiable;
 use Portal\Presenters\UserPresenter;
 use Portal\Services\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatable;
diff --git a/composer.json b/composer.json
index c992694..b23e820 100644
--- a/composer.json
+++ b/composer.json
@@ -3,14 +3,21 @@
     "description": "Advanced PHP Login and User Management",
     "keywords": ["advanced", "secure", "login", "user management", "authentication", "authorization", "register"],
     "type": "project",
+    "repositories": [
+        {
+            "type": "vcs",
+            "url": "https://github.com/reganjohnson/laravel-jsvalidation"
+        }
+    ],
     "require": {
         "php": ">=5.6.4",
-        "laravel/framework": "5.3.*",
-        "proengsoft/laravel-jsvalidation": "~1.1",
-        "laravel/socialite": "^2.0",
+        "laravel/framework": "5.4.*",
+        "proengsoft/laravel-jsvalidation": "^1.6.0-dev",
+        "laravel/socialite": "^3.0",
         "laracasts/presenter": "^0.2.1",
         "laravelcollective/html": "^5.1",
         "webpatser/laravel-countries": "^1.4",
+        "paragonie/random_compat": "~1.4",
         "intervention/image": "^2.3",
         "zizaco/entrust": "^1.5",
         "anlutro/l4-settings": "^0.4.6",
@@ -21,10 +28,10 @@
         "symfony/dom-crawler": "~3.0",
         "fzaninotto/faker": "~1.4",
         "mockery/mockery": "0.9.*",
-        "phpunit/phpunit": "~4.0",
-        "phpspec/phpspec": "~2.1",
+        "phpunit/phpunit": "~5.7",
         "barryvdh/laravel-ide-helper": "2.2.*",
-        "barryvdh/laravel-debugbar": "2.2.*"
+        "barryvdh/laravel-debugbar": "2.3.*",
+        "laravel/browser-kit-testing": "^1.0"
     },
     "autoload": {
         "classmap": [
@@ -38,12 +45,9 @@
         ]
     },
     "autoload-dev": {
-        "classmap": [
-            "tests/TestCase.php",
-            "tests/MailTrap.php",
-            "tests/functional/FunctionalTestCase.php",
-            "tests/functional/Listeners/BaseListenerTestCase.php"
-        ]
+        "psr-4": {
+            "Tests\\": "tests/"
+        }
     },
     "scripts": {
         "post-install-cmd": [
@@ -63,5 +67,8 @@
     },
     "config": {
         "preferred-install": "dist"
-    }
+    },
+
+    "minimum-stability": "dev",
+    "prefer-stable": true
 }
diff --git a/composer.lock b/composer.lock
index dc77a3d..c742bdf 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,26 +4,27 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "c9e5b5819a5594df2f942814fbfb8884",
-    "content-hash": "8774a5d96e28f0e8e4ef9f5da9b71b18",
+    "hash": "28886666e80391696ff98779af51ef5b",
+    "content-hash": "6b90a830cb70d373e1526a81415ffb8a",
     "packages": [
         {
             "name": "anhskohbo/no-captcha",
-            "version": "2.1.2",
+            "version": "2.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/anhskohbo/no-captcha.git",
-                "reference": "07fd1583feae651c4db3652719f2d46fa23c4fd4"
+                "reference": "4f729a21999f496db9580fc4625a0f837ef53adc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/anhskohbo/no-captcha/zipball/07fd1583feae651c4db3652719f2d46fa23c4fd4",
-                "reference": "07fd1583feae651c4db3652719f2d46fa23c4fd4",
+                "url": "https://api.github.com/repos/anhskohbo/no-captcha/zipball/4f729a21999f496db9580fc4625a0f837ef53adc",
+                "reference": "4f729a21999f496db9580fc4625a0f837ef53adc",
                 "shasum": ""
             },
             "require": {
-                "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*",
-                "php": ">=5.4.0"
+                "guzzlehttp/guzzle": "^6.2",
+                "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
+                "php": ">=5.5.5"
             },
             "type": "library",
             "autoload": {
@@ -50,7 +51,7 @@
                 "no-captcha",
                 "recaptcha"
             ],
-            "time": "2016-08-24 16:35:03"
+            "time": "2017-01-30 19:35:26"
         },
         {
             "name": "anlutro/l4-settings",
@@ -99,93 +100,6 @@
             "time": "2016-08-24 14:06:54"
         },
         {
-            "name": "classpreloader/classpreloader",
-            "version": "3.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/ClassPreloader/ClassPreloader.git",
-                "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
-                "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
-                "shasum": ""
-            },
-            "require": {
-                "nikic/php-parser": "^1.0|^2.0",
-                "php": ">=5.5.9"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.8|^5.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.0-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "ClassPreloader\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Michael Dowling",
-                    "email": "mtdowling@gmail.com"
-                },
-                {
-                    "name": "Graham Campbell",
-                    "email": "graham@alt-three.com"
-                }
-            ],
-            "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
-            "keywords": [
-                "autoload",
-                "class",
-                "preload"
-            ],
-            "time": "2015-11-09 22:51:51"
-        },
-        {
-            "name": "dnoegel/php-xdg-base-dir",
-            "version": "0.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
-                "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a",
-                "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.2"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "@stable"
-            },
-            "type": "project",
-            "autoload": {
-                "psr-4": {
-                    "XdgBaseDir\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "description": "implementation of xdg base directory specification for php",
-            "time": "2014-10-24 07:27:01"
-        },
-        {
             "name": "doctrine/inflector",
             "version": "v1.1.0",
             "source": {
@@ -253,17 +167,59 @@
             "time": "2015-11-06 14:35:42"
         },
         {
+            "name": "erusev/parsedown",
+            "version": "1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/erusev/parsedown.git",
+                "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/erusev/parsedown/zipball/20ff8bbb57205368b4b42d094642a3e52dac85fb",
+                "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Parsedown": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Emanuil Rusev",
+                    "email": "hello@erusev.com",
+                    "homepage": "http://erusev.com"
+                }
+            ],
+            "description": "Parser for Markdown.",
+            "homepage": "http://parsedown.org",
+            "keywords": [
+                "markdown",
+                "parser"
+            ],
+            "time": "2016-11-02 15:56:58"
+        },
+        {
             "name": "guzzlehttp/guzzle",
-            "version": "6.2.1",
+            "version": "6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/guzzle.git",
-                "reference": "3f808fba627f2c5b69e2501217bf31af349c1427"
+                "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427",
-                "reference": "3f808fba627f2c5b69e2501217bf31af349c1427",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ebf29dee597f02f09f4d5bbecc68230ea9b08f60",
+                "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60",
                 "shasum": ""
             },
             "require": {
@@ -312,32 +268,32 @@
                 "rest",
                 "web service"
             ],
-            "time": "2016-07-15 17:22:37"
+            "time": "2016-10-08 15:01:37"
         },
         {
             "name": "guzzlehttp/promises",
-            "version": "1.2.0",
+            "version": "v1.3.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/promises.git",
-                "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579"
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579",
-                "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.5.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.0"
+                "phpunit/phpunit": "^4.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0-dev"
+                    "dev-master": "1.4-dev"
                 }
             },
             "autoload": {
@@ -363,7 +319,7 @@
             "keywords": [
                 "promise"
             ],
-            "time": "2016-05-18 16:56:05"
+            "time": "2016-12-20 10:07:11"
         },
         {
             "name": "guzzlehttp/psr7",
@@ -425,16 +381,16 @@
         },
         {
             "name": "intervention/image",
-            "version": "2.3.8",
+            "version": "2.3.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Intervention/image.git",
-                "reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c"
+                "reference": "e8881fd99b9804b29e02d6d1c2c15ee459335cf1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Intervention/image/zipball/4064a980324f6c3bfa2bd981dfb247afa705ec3c",
-                "reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c",
+                "url": "https://api.github.com/repos/Intervention/image/zipball/e8881fd99b9804b29e02d6d1c2c15ee459335cf1",
+                "reference": "e8881fd99b9804b29e02d6d1c2c15ee459335cf1",
                 "shasum": ""
             },
             "require": {
@@ -483,152 +439,7 @@
                 "thumbnail",
                 "watermark"
             ],
-            "time": "2016-09-01 17:04:03"
-        },
-        {
-            "name": "jakub-onderka/php-console-color",
-            "version": "0.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/JakubOnderka/PHP-Console-Color.git",
-                "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1",
-                "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.2"
-            },
-            "require-dev": {
-                "jakub-onderka/php-code-style": "1.0",
-                "jakub-onderka/php-parallel-lint": "0.*",
-                "jakub-onderka/php-var-dump-check": "0.*",
-                "phpunit/phpunit": "3.7.*",
-                "squizlabs/php_codesniffer": "1.*"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "JakubOnderka\\PhpConsoleColor": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-2-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Jakub Onderka",
-                    "email": "jakub.onderka@gmail.com",
-                    "homepage": "http://www.acci.cz"
-                }
-            ],
-            "time": "2014-04-08 15:00:19"
-        },
-        {
-            "name": "jakub-onderka/php-console-highlighter",
-            "version": "v0.3.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git",
-                "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5",
-                "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5",
-                "shasum": ""
-            },
-            "require": {
-                "jakub-onderka/php-console-color": "~0.1",
-                "php": ">=5.3.0"
-            },
-            "require-dev": {
-                "jakub-onderka/php-code-style": "~1.0",
-                "jakub-onderka/php-parallel-lint": "~0.5",
-                "jakub-onderka/php-var-dump-check": "~0.1",
-                "phpunit/phpunit": "~4.0",
-                "squizlabs/php_codesniffer": "~1.5"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "JakubOnderka\\PhpConsoleHighlighter": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Jakub Onderka",
-                    "email": "acci@acci.cz",
-                    "homepage": "http://www.acci.cz/"
-                }
-            ],
-            "time": "2015-04-20 18:58:01"
-        },
-        {
-            "name": "jeremeamia/SuperClosure",
-            "version": "2.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/jeremeamia/super_closure.git",
-                "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/29a88be2a4846d27c1613aed0c9071dfad7b5938",
-                "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938",
-                "shasum": ""
-            },
-            "require": {
-                "nikic/php-parser": "^1.2|^2.0",
-                "php": ">=5.4",
-                "symfony/polyfill-php56": "^1.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.0|^5.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.2-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "SuperClosure\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Jeremy Lindblom",
-                    "email": "jeremeamia@gmail.com",
-                    "homepage": "https://github.com/jeremeamia",
-                    "role": "Developer"
-                }
-            ],
-            "description": "Serialize Closure objects, including their context and binding",
-            "homepage": "https://github.com/jeremeamia/super_closure",
-            "keywords": [
-                "closure",
-                "function",
-                "lambda",
-                "parser",
-                "serializable",
-                "serialize",
-                "tokenizer"
-            ],
-            "time": "2015-12-05 17:17:57"
+            "time": "2017-02-04 10:37:19"
         },
         {
             "name": "laracasts/presenter",
@@ -678,42 +489,40 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v5.3.9",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "f6fbb481672f8dc4bc6882d5d654bbfa3588c8ec"
+                "reference": "9cee8db07cfac13a3a49d17388c9ced4c52e17ac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/f6fbb481672f8dc4bc6882d5d654bbfa3588c8ec",
-                "reference": "f6fbb481672f8dc4bc6882d5d654bbfa3588c8ec",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/9cee8db07cfac13a3a49d17388c9ced4c52e17ac",
+                "reference": "9cee8db07cfac13a3a49d17388c9ced4c52e17ac",
                 "shasum": ""
             },
             "require": {
-                "classpreloader/classpreloader": "~3.0",
                 "doctrine/inflector": "~1.0",
+                "erusev/parsedown": "~1.6",
                 "ext-mbstring": "*",
                 "ext-openssl": "*",
-                "jeremeamia/superclosure": "~2.2",
                 "league/flysystem": "~1.0",
                 "monolog/monolog": "~1.11",
                 "mtdowling/cron-expression": "~1.0",
                 "nesbot/carbon": "~1.20",
                 "paragonie/random_compat": "~1.4|~2.0",
                 "php": ">=5.6.4",
-                "psy/psysh": "0.7.*",
                 "ramsey/uuid": "~3.0",
-                "swiftmailer/swiftmailer": "~5.1",
-                "symfony/console": "3.1.*",
-                "symfony/debug": "3.1.*",
-                "symfony/finder": "3.1.*",
-                "symfony/http-foundation": "3.1.*",
-                "symfony/http-kernel": "3.1.*",
-                "symfony/process": "3.1.*",
-                "symfony/routing": "3.1.*",
-                "symfony/translation": "3.1.*",
-                "symfony/var-dumper": "3.1.*",
+                "swiftmailer/swiftmailer": "~5.4",
+                "symfony/console": "~3.2",
+                "symfony/debug": "~3.2",
+                "symfony/finder": "~3.2",
+                "symfony/http-foundation": "~3.2",
+                "symfony/http-kernel": "~3.2",
+                "symfony/process": "~3.2",
+                "symfony/routing": "~3.2",
+                "symfony/var-dumper": "~3.2",
+                "tijsverkoyen/css-to-inline-styles": "~2.2",
                 "vlucas/phpdotenv": "~2.2"
             },
             "replace": {
@@ -735,6 +544,7 @@
                 "illuminate/http": "self.version",
                 "illuminate/log": "self.version",
                 "illuminate/mail": "self.version",
+                "illuminate/notifications": "self.version",
                 "illuminate/pagination": "self.version",
                 "illuminate/pipeline": "self.version",
                 "illuminate/queue": "self.version",
@@ -749,31 +559,34 @@
             },
             "require-dev": {
                 "aws/aws-sdk-php": "~3.0",
+                "doctrine/dbal": "~2.5",
                 "mockery/mockery": "~0.9.4",
                 "pda/pheanstalk": "~3.0",
-                "phpunit/phpunit": "~5.4",
+                "phpunit/phpunit": "~5.7",
                 "predis/predis": "~1.0",
-                "symfony/css-selector": "3.1.*",
-                "symfony/dom-crawler": "3.1.*"
+                "symfony/css-selector": "~3.2",
+                "symfony/dom-crawler": "~3.2"
             },
             "suggest": {
                 "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).",
-                "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
+                "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).",
                 "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
-                "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).",
+                "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).",
+                "laravel/tinker": "Required to use the tinker console command (~1.0).",
                 "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
                 "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
+                "nexmo/client": "Required to use the Nexmo transport (~1.0).",
                 "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
                 "predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
                 "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).",
-                "symfony/css-selector": "Required to use some of the crawler integration testing tools (3.1.*).",
-                "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (3.1.*).",
+                "symfony/css-selector": "Required to use some of the crawler integration testing tools (~3.2).",
+                "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~3.2).",
                 "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)."
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.3-dev"
+                    "dev-master": "5.4-dev"
                 }
             },
             "autoload": {
@@ -801,27 +614,27 @@
                 "framework",
                 "laravel"
             ],
-            "time": "2016-09-12 14:08:29"
+            "time": "2017-02-10 19:40:54"
         },
         {
             "name": "laravel/socialite",
-            "version": "v2.0.18",
+            "version": "v3.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/socialite.git",
-                "reference": "76ee5397fcdea5a062361392abca4eb397e519a3"
+                "reference": "01588748beef55ad5dd4f172d235548d3a6be79a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/socialite/zipball/76ee5397fcdea5a062361392abca4eb397e519a3",
-                "reference": "76ee5397fcdea5a062361392abca4eb397e519a3",
+                "url": "https://api.github.com/repos/laravel/socialite/zipball/01588748beef55ad5dd4f172d235548d3a6be79a",
+                "reference": "01588748beef55ad5dd4f172d235548d3a6be79a",
                 "shasum": ""
             },
             "require": {
-                "guzzlehttp/guzzle": "~5.0|~6.0",
-                "illuminate/contracts": "~5.0",
-                "illuminate/http": "~5.0",
-                "illuminate/support": "~5.0",
+                "guzzlehttp/guzzle": "~6.0",
+                "illuminate/contracts": "~5.4",
+                "illuminate/http": "~5.4",
+                "illuminate/support": "~5.4",
                 "league/oauth1-client": "~1.0",
                 "php": ">=5.4.0"
             },
@@ -855,32 +668,32 @@
                 "laravel",
                 "oauth"
             ],
-            "time": "2016-06-22 12:40:16"
+            "time": "2017-02-01 13:43:56"
         },
         {
             "name": "laravelcollective/html",
-            "version": "v5.3.0",
+            "version": "v5.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/LaravelCollective/html.git",
-                "reference": "961ce141c16c6b085128f209496c26efd3e681ca"
+                "reference": "7570f25d58a00fd6909c0563808590f9cdb14d47"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/LaravelCollective/html/zipball/961ce141c16c6b085128f209496c26efd3e681ca",
-                "reference": "961ce141c16c6b085128f209496c26efd3e681ca",
+                "url": "https://api.github.com/repos/LaravelCollective/html/zipball/7570f25d58a00fd6909c0563808590f9cdb14d47",
+                "reference": "7570f25d58a00fd6909c0563808590f9cdb14d47",
                 "shasum": ""
             },
             "require": {
-                "illuminate/http": "5.3.*",
-                "illuminate/routing": "5.3.*",
-                "illuminate/session": "5.3.*",
-                "illuminate/support": "5.3.*",
-                "illuminate/view": "5.3.*",
+                "illuminate/http": "5.4.*",
+                "illuminate/routing": "5.4.*",
+                "illuminate/session": "5.4.*",
+                "illuminate/support": "5.4.*",
+                "illuminate/view": "5.4.*",
                 "php": ">=5.6.4"
             },
             "require-dev": {
-                "illuminate/database": "5.3.*",
+                "illuminate/database": "5.4.*",
                 "mockery/mockery": "~0.9.4",
                 "phpunit/phpunit": "~5.4"
             },
@@ -909,24 +722,24 @@
             ],
             "description": "HTML and Form Builders for the Laravel Framework",
             "homepage": "http://laravelcollective.com",
-            "time": "2016-08-27 23:52:43"
+            "time": "2017-01-26 19:27:05"
         },
         {
             "name": "league/flysystem",
-            "version": "1.0.27",
+            "version": "1.0.35",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9"
+                "reference": "dda7f3ab94158a002d9846a97dc18ebfb7acc062"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
-                "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/dda7f3ab94158a002d9846a97dc18ebfb7acc062",
+                "reference": "dda7f3ab94158a002d9846a97dc18ebfb7acc062",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.4.0"
+                "php": ">=5.5.9"
             },
             "conflict": {
                 "league/flysystem-sftp": "<1.0.6"
@@ -992,7 +805,7 @@
                 "sftp",
                 "storage"
             ],
-            "time": "2016-08-10 08:55:11"
+            "time": "2017-02-09 11:33:58"
         },
         {
             "name": "league/oauth1-client",
@@ -1059,16 +872,16 @@
         },
         {
             "name": "monolog/monolog",
-            "version": "1.21.0",
+            "version": "1.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952"
+                "reference": "bad29cb8d18ab0315e6c477751418a82c850d558"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f42fbdfd53e306bda545845e4dbfd3e72edb4952",
-                "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558",
+                "reference": "bad29cb8d18ab0315e6c477751418a82c850d558",
                 "shasum": ""
             },
             "require": {
@@ -1079,7 +892,7 @@
                 "psr/log-implementation": "1.0.0"
             },
             "require-dev": {
-                "aws/aws-sdk-php": "^2.4.9",
+                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
                 "doctrine/couchdb": "~1.0@dev",
                 "graylog2/gelf-php": "~1.0",
                 "jakub-onderka/php-parallel-lint": "0.9",
@@ -1133,20 +946,20 @@
                 "logging",
                 "psr-3"
             ],
-            "time": "2016-07-29 03:23:52"
+            "time": "2016-11-26 00:15:39"
         },
         {
             "name": "mtdowling/cron-expression",
-            "version": "v1.1.0",
+            "version": "v1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mtdowling/cron-expression.git",
-                "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5"
+                "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
-                "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
+                "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad",
+                "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad",
                 "shasum": ""
             },
             "require": {
@@ -1157,8 +970,8 @@
             },
             "type": "library",
             "autoload": {
-                "psr-0": {
-                    "Cron": "src/"
+                "psr-4": {
+                    "Cron\\": "src/Cron/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1177,30 +990,36 @@
                 "cron",
                 "schedule"
             ],
-            "time": "2016-01-26 21:23:30"
+            "time": "2017-01-23 04:29:33"
         },
         {
             "name": "nesbot/carbon",
-            "version": "1.21.0",
+            "version": "1.22.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7"
+                "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
-                "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
+                "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.0",
-                "symfony/translation": "~2.6|~3.0"
+                "symfony/translation": "~2.6 || ~3.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.0|~5.0"
+                "friendsofphp/php-cs-fixer": "~2",
+                "phpunit/phpunit": "~4.0 || ~5.0"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.23-dev"
+                }
+            },
             "autoload": {
                 "psr-4": {
                     "Carbon\\": "src/Carbon/"
@@ -1224,71 +1043,20 @@
                 "datetime",
                 "time"
             ],
-            "time": "2015-11-04 20:07:17"
-        },
-        {
-            "name": "nikic/php-parser",
-            "version": "v2.1.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4dd659edadffdc2143e4753df655d866dbfeedf0",
-                "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0",
-                "shasum": ""
-            },
-            "require": {
-                "ext-tokenizer": "*",
-                "php": ">=5.4"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.0"
-            },
-            "bin": [
-                "bin/php-parse"
-            ],
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.1-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "PhpParser\\": "lib/PhpParser"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Nikita Popov"
-                }
-            ],
-            "description": "A PHP parser written in PHP",
-            "keywords": [
-                "parser",
-                "php"
-            ],
-            "time": "2016-09-16 12:04:44"
+            "time": "2017-01-16 07:55:07"
         },
         {
             "name": "paragonie/random_compat",
-            "version": "v2.0.2",
+            "version": "v1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/paragonie/random_compat.git",
-                "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
+                "reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
-                "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
+                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
+                "reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
                 "shasum": ""
             },
             "require": {
@@ -1323,33 +1091,34 @@
                 "pseudorandom",
                 "random"
             ],
-            "time": "2016-04-03 06:00:07"
+            "time": "2016-03-18 20:34:03"
         },
         {
             "name": "proengsoft/laravel-jsvalidation",
-            "version": "v1.3.1",
+            "version": "v1.6.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/proengsoft/laravel-jsvalidation.git",
-                "reference": "d659e05837a705b55c8bfe1e54eee0b93c7ccf11"
+                "url": "https://github.com/reganjohnson/laravel-jsvalidation.git",
+                "reference": "e93419ce53132f8d3d8ffaf32600a68a25e54ae8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/proengsoft/laravel-jsvalidation/zipball/d659e05837a705b55c8bfe1e54eee0b93c7ccf11",
-                "reference": "d659e05837a705b55c8bfe1e54eee0b93c7ccf11",
+                "url": "https://api.github.com/repos/reganjohnson/laravel-jsvalidation/zipball/e93419ce53132f8d3d8ffaf32600a68a25e54ae8",
+                "reference": "e93419ce53132f8d3d8ffaf32600a68a25e54ae8",
                 "shasum": ""
             },
             "require": {
-                "illuminate/config": "~5.0",
-                "illuminate/contracts": "~5.0",
-                "illuminate/http": "~5.0",
-                "illuminate/support": "~5.0",
-                "illuminate/validation": "~5.0",
-                "illuminate/view": "~5.0",
+                "illuminate/config": "~5.4",
+                "illuminate/contracts": "~5.4",
+                "illuminate/http": "~5.4",
+                "illuminate/support": "~5.4",
+                "illuminate/translation": "~5.4",
+                "illuminate/validation": "~5.4",
+                "illuminate/view": "~5.4",
                 "php": ">=5.4.0"
             },
             "require-dev": {
-                "mockery/mockery": "0.9.*",
+                "mockery/mockery": "~0.9",
                 "phpunit/phpunit": "~4.0"
             },
             "type": "library",
@@ -1359,7 +1128,6 @@
                     "Proengsoft\\JsValidation\\Tests\\": "tests"
                 }
             },
-            "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
@@ -1367,8 +1135,7 @@
                 {
                     "name": "Albert Moreno",
                     "email": "albert@memorylimit.net",
-                    "homepage": "http://memorylimit.net",
-                    "role": "DevOps"
+                    "homepage": "https://github.com/torrentalle"
                 }
             ],
             "description": "Validate forms transparently with Javascript reusing your Laravel Validation Rules, Messages, and FormRequest",
@@ -1382,7 +1149,10 @@
                 "validation",
                 "validator"
             ],
-            "time": "2016-01-04 00:23:38"
+            "support": {
+                "source": "https://github.com/reganjohnson/laravel-jsvalidation/tree/v1.6.0"
+            },
+            "time": "2017-01-31 13:50:57"
         },
         {
             "name": "psr/http-message",
@@ -1436,22 +1206,30 @@
         },
         {
             "name": "psr/log",
-            "version": "1.0.0",
+            "version": "1.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+                "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
-                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+                "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
                 "shasum": ""
             },
+            "require": {
+                "php": ">=5.3.0"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
             "autoload": {
-                "psr-0": {
-                    "Psr\\Log\\": ""
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1465,102 +1243,31 @@
                 }
             ],
             "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
             "keywords": [
                 "log",
                 "psr",
                 "psr-3"
             ],
-            "time": "2012-12-21 11:40:51"
+            "time": "2016-10-10 12:19:37"
         },
         {
-            "name": "psy/psysh",
-            "version": "v0.7.2",
+            "name": "ramsey/uuid",
+            "version": "3.5.2",
             "source": {
                 "type": "git",
-                "url": "https://github.com/bobthecow/psysh.git",
-                "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280"
+                "url": "https://github.com/ramsey/uuid.git",
+                "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280",
-                "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/5677cfe02397dd6b58c861870dfaa5d9007d3954",
+                "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954",
                 "shasum": ""
             },
             "require": {
-                "dnoegel/php-xdg-base-dir": "0.1",
-                "jakub-onderka/php-console-highlighter": "0.3.*",
-                "nikic/php-parser": "^1.2.1|~2.0",
-                "php": ">=5.3.9",
-                "symfony/console": "~2.3.10|^2.4.2|~3.0",
-                "symfony/var-dumper": "~2.7|~3.0"
-            },
-            "require-dev": {
-                "fabpot/php-cs-fixer": "~1.5",
-                "phpunit/phpunit": "~3.7|~4.0|~5.0",
-                "squizlabs/php_codesniffer": "~2.0",
-                "symfony/finder": "~2.1|~3.0"
-            },
-            "suggest": {
-                "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
-                "ext-pdo-sqlite": "The doc command requires SQLite to work.",
-                "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
-                "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history."
-            },
-            "bin": [
-                "bin/psysh"
-            ],
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-develop": "0.8.x-dev"
-                }
-            },
-            "autoload": {
-                "files": [
-                    "src/Psy/functions.php"
-                ],
-                "psr-4": {
-                    "Psy\\": "src/Psy/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Justin Hileman",
-                    "email": "justin@justinhileman.info",
-                    "homepage": "http://justinhileman.com"
-                }
-            ],
-            "description": "An interactive shell for modern PHP.",
-            "homepage": "http://psysh.org",
-            "keywords": [
-                "REPL",
-                "console",
-                "interactive",
-                "shell"
-            ],
-            "time": "2016-03-09 05:03:14"
-        },
-        {
-            "name": "ramsey/uuid",
-            "version": "3.5.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/ramsey/uuid.git",
-                "reference": "a6d15c8618ea3951fd54d34e326b68d3d0bc0786"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/a6d15c8618ea3951fd54d34e326b68d3d0bc0786",
-                "reference": "a6d15c8618ea3951fd54d34e326b68d3d0bc0786",
-                "shasum": ""
-            },
-            "require": {
-                "paragonie/random_compat": "^1.0|^2.0",
-                "php": ">=5.4"
+                "paragonie/random_compat": "^1.0|^2.0",
+                "php": ">=5.4"
             },
             "replace": {
                 "rhumsaa/uuid": "self.version"
@@ -1568,11 +1275,13 @@
             "require-dev": {
                 "apigen/apigen": "^4.1",
                 "codeception/aspect-mock": "1.0.0",
+                "doctrine/annotations": "~1.2.0",
                 "goaop/framework": "1.0.0-alpha.2",
                 "ircmaxell/random-lib": "^1.1",
                 "jakub-onderka/php-parallel-lint": "^0.9.0",
                 "mockery/mockery": "^0.9.4",
                 "moontoast/math": "^1.1",
+                "php-mock/php-mock-phpunit": "^0.3|^1.1",
                 "phpunit/phpunit": "^4.7|>=5.0 <5.4",
                 "satooshi/php-coveralls": "^0.6.1",
                 "squizlabs/php_codesniffer": "^2.3"
@@ -1622,27 +1331,28 @@
                 "identifier",
                 "uuid"
             ],
-            "time": "2016-08-02 18:39:32"
+            "time": "2016-11-22 19:21:44"
         },
         {
             "name": "swiftmailer/swiftmailer",
-            "version": "v5.4.3",
+            "version": "v5.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/swiftmailer/swiftmailer.git",
-                "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
+                "reference": "cd142238a339459b10da3d8234220963f392540c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
-                "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c",
+                "reference": "cd142238a339459b10da3d8234220963f392540c",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "require-dev": {
-                "mockery/mockery": "~0.9.1"
+                "mockery/mockery": "~0.9.1",
+                "symfony/phpunit-bridge": "~3.2"
             },
             "type": "library",
             "extra": {
@@ -1675,40 +1385,43 @@
                 "mail",
                 "mailer"
             ],
-            "time": "2016-07-08 11:51:25"
+            "time": "2016-12-29 10:02:40"
         },
         {
             "name": "symfony/console",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563"
+                "reference": "7a8405a9fc175f87fed8a3c40856b0d866d61936"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/8ea494c34f0f772c3954b5fbe00bffc5a435e563",
-                "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563",
+                "url": "https://api.github.com/repos/symfony/console/zipball/7a8405a9fc175f87fed8a3c40856b0d866d61936",
+                "reference": "7a8405a9fc175f87fed8a3c40856b0d866d61936",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.5.9",
+                "symfony/debug": "~2.8|~3.0",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "require-dev": {
                 "psr/log": "~1.0",
                 "symfony/event-dispatcher": "~2.8|~3.0",
+                "symfony/filesystem": "~2.8|~3.0",
                 "symfony/process": "~2.8|~3.0"
             },
             "suggest": {
                 "psr/log": "For using the console logger",
                 "symfony/event-dispatcher": "",
+                "symfony/filesystem": "",
                 "symfony/process": ""
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1735,20 +1448,73 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-19 06:48:39"
+            "time": "2017-02-06 12:04:21"
+        },
+        {
+            "name": "symfony/css-selector",
+            "version": "v3.2.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/css-selector.git",
+                "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
+                "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.9"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\CssSelector\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jean-François Simon",
+                    "email": "jeanfrancois.simon@sensiolabs.com"
+                },
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony CssSelector Component",
+            "homepage": "https://symfony.com",
+            "time": "2017-01-02 20:32:22"
         },
         {
             "name": "symfony/debug",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "34f6ac18c2974ca5fce68adf419ee7d15def6f11"
+                "reference": "b4d9818f127c60ce21ed62c395da7df868dc8477"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/34f6ac18c2974ca5fce68adf419ee7d15def6f11",
-                "reference": "34f6ac18c2974ca5fce68adf419ee7d15def6f11",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/b4d9818f127c60ce21ed62c395da7df868dc8477",
+                "reference": "b4d9818f127c60ce21ed62c395da7df868dc8477",
                 "shasum": ""
             },
             "require": {
@@ -1765,7 +1531,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1792,20 +1558,20 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-23 13:39:15"
+            "time": "2017-01-28 02:37:08"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5"
+                "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
-                "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6",
+                "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6",
                 "shasum": ""
             },
             "require": {
@@ -1825,7 +1591,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1852,20 +1618,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-19 10:45:57"
+            "time": "2017-01-02 20:32:22"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577"
+                "reference": "8c71141cae8e2957946b403cc71a67213c0380d6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577",
-                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6",
+                "reference": "8c71141cae8e2957946b403cc71a67213c0380d6",
                 "shasum": ""
             },
             "require": {
@@ -1874,7 +1640,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1901,20 +1667,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-26 12:04:02"
+            "time": "2017-01-02 20:32:22"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "63592e00fd90632b57ee50220a1ddb29b6bf3bb4"
+                "reference": "e192b04de44aa1ed0e39d6793f7e06f5e0b672a0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/63592e00fd90632b57ee50220a1ddb29b6bf3bb4",
-                "reference": "63592e00fd90632b57ee50220a1ddb29b6bf3bb4",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e192b04de44aa1ed0e39d6793f7e06f5e0b672a0",
+                "reference": "e192b04de44aa1ed0e39d6793f7e06f5e0b672a0",
                 "shasum": ""
             },
             "require": {
@@ -1927,7 +1693,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1954,20 +1720,20 @@
             ],
             "description": "Symfony HttpFoundation Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-22 12:11:19"
+            "time": "2017-02-02 13:47:35"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "aeda215d6b01f119508c090d2a09ebb5b0bc61f3"
+                "reference": "96443239baf674b143604fb87cb27cb01672ab77"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aeda215d6b01f119508c090d2a09ebb5b0bc61f3",
-                "reference": "aeda215d6b01f119508c090d2a09ebb5b0bc61f3",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/96443239baf674b143604fb87cb27cb01672ab77",
+                "reference": "96443239baf674b143604fb87cb27cb01672ab77",
                 "shasum": ""
             },
             "require": {
@@ -1975,7 +1741,7 @@
                 "psr/log": "~1.0",
                 "symfony/debug": "~2.8|~3.0",
                 "symfony/event-dispatcher": "~2.8|~3.0",
-                "symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2"
+                "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2"
             },
             "conflict": {
                 "symfony/config": "<2.8"
@@ -1995,7 +1761,7 @@
                 "symfony/stopwatch": "~2.8|~3.0",
                 "symfony/templating": "~2.8|~3.0",
                 "symfony/translation": "~2.8|~3.0",
-                "symfony/var-dumper": "~2.8|~3.0"
+                "symfony/var-dumper": "~3.2"
             },
             "suggest": {
                 "symfony/browser-kit": "",
@@ -2009,7 +1775,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2036,20 +1802,20 @@
             ],
             "description": "Symfony HttpKernel Component",
             "homepage": "https://symfony.com",
-            "time": "2016-09-03 15:28:24"
+            "time": "2017-02-06 13:15:19"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.2.0",
+            "version": "v1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "dff51f72b0706335131b00a7f49606168c582594"
+                "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
-                "reference": "dff51f72b0706335131b00a7f49606168c582594",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
+                "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
                 "shasum": ""
             },
             "require": {
@@ -2061,7 +1827,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
@@ -2095,128 +1861,20 @@
                 "portable",
                 "shim"
             ],
-            "time": "2016-05-18 14:26:46"
-        },
-        {
-            "name": "symfony/polyfill-php56",
-            "version": "v1.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php56.git",
-                "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/3edf57a8fbf9a927533344cef65ad7e1cf31030a",
-                "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3",
-                "symfony/polyfill-util": "~1.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.2-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Php56\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2016-05-18 14:26:46"
-        },
-        {
-            "name": "symfony/polyfill-util",
-            "version": "v1.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-util.git",
-                "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/ef830ce3d218e622b221d6bfad42c751d974bf99",
-                "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.2-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Util\\": ""
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony utilities for portability of PHP codes",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compat",
-                "compatibility",
-                "polyfill",
-                "shim"
-            ],
-            "time": "2016-05-18 14:26:46"
+            "time": "2016-11-14 01:06:16"
         },
         {
             "name": "symfony/process",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "e64e93041c80e77197ace5ab9385dedb5a143697"
+                "reference": "32646a7cf53f3956c76dcb5c82555224ae321858"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/e64e93041c80e77197ace5ab9385dedb5a143697",
-                "reference": "e64e93041c80e77197ace5ab9385dedb5a143697",
+                "url": "https://api.github.com/repos/symfony/process/zipball/32646a7cf53f3956c76dcb5c82555224ae321858",
+                "reference": "32646a7cf53f3956c76dcb5c82555224ae321858",
                 "shasum": ""
             },
             "require": {
@@ -2225,7 +1883,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2252,20 +1910,20 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-16 14:58:24"
+            "time": "2017-02-03 12:11:38"
         },
         {
             "name": "symfony/routing",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "8edf62498a1a4c57ba317664a4b698339c10cdf6"
+                "reference": "af464432c177dbcdbb32295113b7627500331f2d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/8edf62498a1a4c57ba317664a4b698339c10cdf6",
-                "reference": "8edf62498a1a4c57ba317664a4b698339c10cdf6",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/af464432c177dbcdbb32295113b7627500331f2d",
+                "reference": "af464432c177dbcdbb32295113b7627500331f2d",
                 "shasum": ""
             },
             "require": {
@@ -2294,7 +1952,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2327,20 +1985,20 @@
                 "uri",
                 "url"
             ],
-            "time": "2016-08-16 14:58:24"
+            "time": "2017-01-28 02:37:08"
         },
         {
             "name": "symfony/translation",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "a35edc277513c9bc0f063ca174c36b346f974528"
+                "reference": "ca032cc56976d88b85e7386b17020bc6dc95dbc5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/a35edc277513c9bc0f063ca174c36b346f974528",
-                "reference": "a35edc277513c9bc0f063ca174c36b346f974528",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/ca032cc56976d88b85e7386b17020bc6dc95dbc5",
+                "reference": "ca032cc56976d88b85e7386b17020bc6dc95dbc5",
                 "shasum": ""
             },
             "require": {
@@ -2364,7 +2022,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2391,20 +2049,20 @@
             ],
             "description": "Symfony Translation Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-05 08:37:39"
+            "time": "2017-01-21 17:06:35"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "62ee73706c421654a4c840028954510277f7dfc8"
+                "reference": "5bb4435a03a4f05c211f4a9a8ee2756965924511"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/62ee73706c421654a4c840028954510277f7dfc8",
-                "reference": "62ee73706c421654a4c840028954510277f7dfc8",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/5bb4435a03a4f05c211f4a9a8ee2756965924511",
+                "reference": "5bb4435a03a4f05c211f4a9a8ee2756965924511",
                 "shasum": ""
             },
             "require": {
@@ -2420,7 +2078,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2454,7 +2112,54 @@
                 "debug",
                 "dump"
             ],
-            "time": "2016-08-31 09:05:42"
+            "time": "2017-01-24 12:58:58"
+        },
+        {
+            "name": "tijsverkoyen/css-to-inline-styles",
+            "version": "2.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
+                "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b",
+                "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.5 || ^7",
+                "symfony/css-selector": "^2.7|~3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.8|5.1.*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "TijsVerkoyen\\CssToInlineStyles\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Tijs Verkoyen",
+                    "email": "css_to_inline_styles@verkoyen.eu",
+                    "role": "Developer"
+                }
+            ],
+            "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.",
+            "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
+            "time": "2016-09-20 12:50:39"
         },
         {
             "name": "vlucas/phpdotenv",
@@ -2508,22 +2213,22 @@
         },
         {
             "name": "webpatser/laravel-countries",
-            "version": "1.4.3",
+            "version": "1.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webpatser/laravel-countries.git",
-                "reference": "3142b86c71908a8e63dec07bc8fe48abff9902dd"
+                "reference": "bb5d5116d796a038bfb45f083998b25506d9a595"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/3142b86c71908a8e63dec07bc8fe48abff9902dd",
-                "reference": "3142b86c71908a8e63dec07bc8fe48abff9902dd",
+                "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/bb5d5116d796a038bfb45f083998b25506d9a595",
+                "reference": "bb5d5116d796a038bfb45f083998b25506d9a595",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.0"
             },
-            "type": "laravel-library",
+            "type": "library",
             "autoload": {
                 "psr-0": {
                     "Webpatser\\Countries": "src/"
@@ -2556,7 +2261,7 @@
                 "iso_3166_3",
                 "laravel"
             ],
-            "time": "2015-06-10 07:52:21"
+            "time": "2017-01-25 20:26:35"
         },
         {
             "name": "zizaco/entrust",
@@ -2630,28 +2335,28 @@
     "packages-dev": [
         {
             "name": "barryvdh/laravel-debugbar",
-            "version": "V2.2.3",
+            "version": "v2.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-debugbar.git",
-                "reference": "ecd1ce5c4a827e2f6a8fb41bcf67713beb1c1cbd"
+                "reference": "24e4f0261e352d3fd86d0447791b56ae49398674"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/ecd1ce5c4a827e2f6a8fb41bcf67713beb1c1cbd",
-                "reference": "ecd1ce5c4a827e2f6a8fb41bcf67713beb1c1cbd",
+                "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/24e4f0261e352d3fd86d0447791b56ae49398674",
+                "reference": "24e4f0261e352d3fd86d0447791b56ae49398674",
                 "shasum": ""
             },
             "require": {
-                "illuminate/support": "5.1.*|5.2.*|5.3.*",
-                "maximebf/debugbar": "~1.11.0|~1.12.0",
+                "illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*",
+                "maximebf/debugbar": "~1.13.0",
                 "php": ">=5.5.9",
                 "symfony/finder": "~2.7|~3.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.2-dev"
+                    "dev-master": "2.3-dev"
                 }
             },
             "autoload": {
@@ -2680,27 +2385,27 @@
                 "profiler",
                 "webprofiler"
             ],
-            "time": "2016-07-29 15:00:36"
+            "time": "2017-01-19 08:19:49"
         },
         {
             "name": "barryvdh/laravel-ide-helper",
-            "version": "v2.2.1",
+            "version": "v2.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-ide-helper.git",
-                "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463"
+                "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/28af7cd19ca41cc0c63dd1de2b46c2b84d31c463",
-                "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463",
+                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/a7fc2ec489aada6062d3a63ddc915004a21e38af",
+                "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af",
                 "shasum": ""
             },
             "require": {
                 "barryvdh/reflection-docblock": "^2.0.4",
-                "illuminate/console": "^5.0,<5.4",
-                "illuminate/filesystem": "^5.0,<5.4",
-                "illuminate/support": "^5.0,<5.4",
+                "illuminate/console": "^5.0,<5.5",
+                "illuminate/filesystem": "^5.0,<5.5",
+                "illuminate/support": "^5.0,<5.5",
                 "php": ">=5.4.0",
                 "symfony/class-loader": "^2.3|^3.0"
             },
@@ -2746,7 +2451,7 @@
                 "phpstorm",
                 "sublime"
             ],
-            "time": "2016-07-04 11:52:48"
+            "time": "2017-01-05 21:20:42"
         },
         {
             "name": "barryvdh/reflection-docblock",
@@ -2945,17 +2650,64 @@
             "time": "2015-05-11 14:41:42"
         },
         {
+            "name": "laravel/browser-kit-testing",
+            "version": "v1.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/browser-kit-testing.git",
+                "reference": "0adfb725147815bff5516d157577f375a6e66ebd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/browser-kit-testing/zipball/0adfb725147815bff5516d157577f375a6e66ebd",
+                "reference": "0adfb725147815bff5516d157577f375a6e66ebd",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.9",
+                "symfony/css-selector": "~3.1",
+                "symfony/dom-crawler": "~3.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\BrowserKitTesting\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "Provides backwards compatibility for BrowserKit testing in Laravel 5.4.",
+            "keywords": [
+                "laravel",
+                "testing"
+            ],
+            "time": "2017-02-08 22:32:37"
+        },
+        {
             "name": "maximebf/debugbar",
-            "version": "v1.12.0",
+            "version": "1.13.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/maximebf/php-debugbar.git",
-                "reference": "e634fbd32cd6bc3fa0e8c972b52d4bf49bab3988"
+                "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/e634fbd32cd6bc3fa0e8c972b52d4bf49bab3988",
-                "reference": "e634fbd32cd6bc3fa0e8c972b52d4bf49bab3988",
+                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/afee79a236348e39a44cb837106b7c5b4897ac2a",
+                "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a",
                 "shasum": ""
             },
             "require": {
@@ -2974,7 +2726,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.12-dev"
+                    "dev-master": "1.13-dev"
                 }
             },
             "autoload": {
@@ -3003,20 +2755,20 @@
                 "debug",
                 "debugbar"
             ],
-            "time": "2016-05-15 13:11:34"
+            "time": "2017-01-05 08:46:19"
         },
         {
             "name": "mockery/mockery",
-            "version": "0.9.5",
+            "version": "0.9.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/padraic/mockery.git",
-                "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2"
+                "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2",
-                "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2",
+                "url": "https://api.github.com/repos/padraic/mockery/zipball/1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855",
+                "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855",
                 "shasum": ""
             },
             "require": {
@@ -3068,19 +2820,61 @@
                 "test double",
                 "testing"
             ],
-            "time": "2016-05-22 21:52:33"
+            "time": "2017-02-09 13:29:38"
         },
         {
-            "name": "phpdocumentor/reflection-common",
-            "version": "1.0",
+            "name": "myclabs/deep-copy",
+            "version": "1.6.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+                "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "doctrine/collections": "1.*",
+                "phpunit/phpunit": "~4.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "homepage": "https://github.com/myclabs/DeepCopy",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "time": "2017-01-26 22:05:40"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
                 "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
                 "shasum": ""
             },
@@ -3126,16 +2920,16 @@
         },
         {
             "name": "phpdocumentor/reflection-docblock",
-            "version": "3.1.0",
+            "version": "3.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
+                "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
-                "reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
+                "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
                 "shasum": ""
             },
             "require": {
@@ -3167,20 +2961,20 @@
                 }
             ],
             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
-            "time": "2016-06-10 09:48:41"
+            "time": "2016-09-30 07:12:33"
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "0.2",
+            "version": "0.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
+                "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
-                "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
+                "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
                 "shasum": ""
             },
             "require": {
@@ -3214,132 +3008,20 @@
                     "email": "me@mikevanriel.com"
                 }
             ],
-            "time": "2016-06-10 07:14:17"
-        },
-        {
-            "name": "phpspec/php-diff",
-            "version": "v1.0.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpspec/php-diff.git",
-                "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a",
-                "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a",
-                "shasum": ""
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "Diff": "lib/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Chris Boulton",
-                    "homepage": "http://github.com/chrisboulton",
-                    "role": "Original developer"
-                }
-            ],
-            "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
-            "time": "2013-11-01 13:02:21"
-        },
-        {
-            "name": "phpspec/phpspec",
-            "version": "2.5.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpspec/phpspec.git",
-                "reference": "7e7e104de01b5052195cefefcd0b29f1add4c116"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/phpspec/zipball/7e7e104de01b5052195cefefcd0b29f1add4c116",
-                "reference": "7e7e104de01b5052195cefefcd0b29f1add4c116",
-                "shasum": ""
-            },
-            "require": {
-                "doctrine/instantiator": "^1.0.1",
-                "ext-tokenizer": "*",
-                "php": ">=5.3.3",
-                "phpspec/php-diff": "~1.0.0",
-                "phpspec/prophecy": "~1.4",
-                "sebastian/exporter": "~1.0",
-                "symfony/console": "~2.3|~3.0",
-                "symfony/event-dispatcher": "~2.1|~3.0",
-                "symfony/finder": "~2.1|~3.0",
-                "symfony/process": "^2.6|~3.0",
-                "symfony/yaml": "~2.1|~3.0"
-            },
-            "require-dev": {
-                "behat/behat": "^3.0.11",
-                "ciaranmcnulty/versionbasedtestskipper": "^0.2.1",
-                "phpunit/phpunit": "~4.4",
-                "symfony/filesystem": "~2.1|~3.0"
-            },
-            "suggest": {
-                "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
-            },
-            "bin": [
-                "bin/phpspec"
-            ],
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.5.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-0": {
-                    "PhpSpec": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
-                },
-                {
-                    "name": "Marcello Duarte",
-                    "homepage": "http://marcelloduarte.net/"
-                }
-            ],
-            "description": "Specification-oriented BDD framework for PHP 5.3+",
-            "homepage": "http://phpspec.net/",
-            "keywords": [
-                "BDD",
-                "SpecBDD",
-                "TDD",
-                "spec",
-                "specification",
-                "testing",
-                "tests"
-            ],
-            "time": "2016-09-04 11:59:15"
+            "time": "2016-11-25 06:54:22"
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.6.1",
+            "version": "v1.6.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "58a8137754bc24b25740d4281399a4a3596058e0"
+                "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
-                "reference": "58a8137754bc24b25740d4281399a4a3596058e0",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
+                "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
                 "shasum": ""
             },
             "require": {
@@ -3347,10 +3029,11 @@
                 "php": "^5.3|^7.0",
                 "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
                 "sebastian/comparator": "^1.1",
-                "sebastian/recursion-context": "^1.0"
+                "sebastian/recursion-context": "^1.0|^2.0"
             },
             "require-dev": {
-                "phpspec/phpspec": "^2.0"
+                "phpspec/phpspec": "^2.0",
+                "phpunit/phpunit": "^4.8 || ^5.6.5"
             },
             "type": "library",
             "extra": {
@@ -3388,43 +3071,44 @@
                 "spy",
                 "stub"
             ],
-            "time": "2016-06-07 08:13:47"
+            "time": "2016-11-21 14:58:47"
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.2.4",
+            "version": "4.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
+                "reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
-                "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c19cfc7cbb0e9338d8c469c7eedecc2a428b0971",
+                "reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3",
+                "php": "^5.6 || ^7.0",
                 "phpunit/php-file-iterator": "~1.3",
                 "phpunit/php-text-template": "~1.2",
-                "phpunit/php-token-stream": "~1.3",
-                "sebastian/environment": "^1.3.2",
-                "sebastian/version": "~1.0"
+                "phpunit/php-token-stream": "^1.4.2",
+                "sebastian/code-unit-reverse-lookup": "~1.0",
+                "sebastian/environment": "^1.3.2 || ^2.0",
+                "sebastian/version": "~1.0|~2.0"
             },
             "require-dev": {
                 "ext-xdebug": ">=2.1.4",
-                "phpunit/phpunit": "~4"
+                "phpunit/phpunit": "^5.4"
             },
             "suggest": {
                 "ext-dom": "*",
-                "ext-xdebug": ">=2.2.1",
+                "ext-xdebug": ">=2.4.0",
                 "ext-xmlwriter": "*"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.2.x-dev"
+                    "dev-master": "4.0.x-dev"
                 }
             },
             "autoload": {
@@ -3450,20 +3134,20 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2015-10-06 15:47:00"
+            "time": "2017-01-20 15:06:43"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.4.1",
+            "version": "1.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
+                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
-                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
                 "shasum": ""
             },
             "require": {
@@ -3497,7 +3181,7 @@
                 "filesystem",
                 "iterator"
             ],
-            "time": "2015-06-21 13:08:43"
+            "time": "2016-10-03 07:40:28"
         },
         {
             "name": "phpunit/php-text-template",
@@ -3586,16 +3270,16 @@
         },
         {
             "name": "phpunit/php-token-stream",
-            "version": "1.4.8",
+            "version": "1.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
+                "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
-                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
+                "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
                 "shasum": ""
             },
             "require": {
@@ -3631,44 +3315,54 @@
             "keywords": [
                 "tokenizer"
             ],
-            "time": "2015-09-15 10:49:45"
+            "time": "2016-11-15 14:06:22"
         },
         {
             "name": "phpunit/phpunit",
-            "version": "4.8.27",
+            "version": "5.7.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90"
+                "reference": "60ebeed87a35ea46fd7f7d8029df2d6f013ebb34"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90",
-                "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60ebeed87a35ea46fd7f7d8029df2d6f013ebb34",
+                "reference": "60ebeed87a35ea46fd7f7d8029df2d6f013ebb34",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-json": "*",
-                "ext-pcre": "*",
-                "ext-reflection": "*",
-                "ext-spl": "*",
-                "php": ">=5.3.3",
-                "phpspec/prophecy": "^1.3.1",
-                "phpunit/php-code-coverage": "~2.1",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "myclabs/deep-copy": "~1.3",
+                "php": "^5.6 || ^7.0",
+                "phpspec/prophecy": "^1.6.2",
+                "phpunit/php-code-coverage": "^4.0.4",
                 "phpunit/php-file-iterator": "~1.4",
                 "phpunit/php-text-template": "~1.2",
                 "phpunit/php-timer": "^1.0.6",
-                "phpunit/phpunit-mock-objects": "~2.3",
-                "sebastian/comparator": "~1.1",
+                "phpunit/phpunit-mock-objects": "^3.2",
+                "sebastian/comparator": "^1.2.4",
                 "sebastian/diff": "~1.2",
-                "sebastian/environment": "~1.3",
-                "sebastian/exporter": "~1.2",
-                "sebastian/global-state": "~1.0",
-                "sebastian/version": "~1.0",
+                "sebastian/environment": "^1.3.4 || ^2.0",
+                "sebastian/exporter": "~2.0",
+                "sebastian/global-state": "^1.1",
+                "sebastian/object-enumerator": "~2.0",
+                "sebastian/resource-operations": "~1.0",
+                "sebastian/version": "~1.0|~2.0",
                 "symfony/yaml": "~2.1|~3.0"
             },
+            "conflict": {
+                "phpdocumentor/reflection-docblock": "3.0.2"
+            },
+            "require-dev": {
+                "ext-pdo": "*"
+            },
             "suggest": {
+                "ext-xdebug": "*",
                 "phpunit/php-invoker": "~1.1"
             },
             "bin": [
@@ -3677,7 +3371,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.8.x-dev"
+                    "dev-master": "5.7.x-dev"
                 }
             },
             "autoload": {
@@ -3703,30 +3397,33 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2016-07-21 06:48:14"
+            "time": "2017-02-10 09:05:10"
         },
         {
             "name": "phpunit/phpunit-mock-objects",
-            "version": "2.3.8",
+            "version": "3.4.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
-                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
+                "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
-                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
+                "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
-                "php": ">=5.3.3",
-                "phpunit/php-text-template": "~1.2",
-                "sebastian/exporter": "~1.2"
+                "php": "^5.6 || ^7.0",
+                "phpunit/php-text-template": "^1.2",
+                "sebastian/exporter": "^1.2 || ^2.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<5.4.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.4"
+                "phpunit/phpunit": "^5.4"
             },
             "suggest": {
                 "ext-soap": "*"
@@ -3734,7 +3431,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.3.x-dev"
+                    "dev-master": "3.2.x-dev"
                 }
             },
             "autoload": {
@@ -3759,26 +3456,71 @@
                 "mock",
                 "xunit"
             ],
-            "time": "2015-10-02 06:51:40"
+            "time": "2016-12-08 20:27:08"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
+                "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "time": "2016-02-13 06:45:14"
         },
         {
             "name": "sebastian/comparator",
-            "version": "1.2.0",
+            "version": "1.2.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
+                "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
-                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+                "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3",
                 "sebastian/diff": "~1.2",
-                "sebastian/exporter": "~1.2"
+                "sebastian/exporter": "~1.2 || ~2.0"
             },
             "require-dev": {
                 "phpunit/phpunit": "~4.4"
@@ -3823,7 +3565,7 @@
                 "compare",
                 "equality"
             ],
-            "time": "2015-07-26 15:48:44"
+            "time": "2017-01-29 09:50:25"
         },
         {
             "name": "sebastian/diff",
@@ -3879,28 +3621,28 @@
         },
         {
             "name": "sebastian/environment",
-            "version": "1.3.8",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
+                "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
-                "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+                "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.3.3 || ^7.0"
+                "php": "^5.6 || ^7.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^4.8 || ^5.0"
+                "phpunit/phpunit": "^5.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
@@ -3925,25 +3667,25 @@
                 "environment",
                 "hhvm"
             ],
-            "time": "2016-08-18 05:49:44"
+            "time": "2016-11-26 07:53:53"
         },
         {
             "name": "sebastian/exporter",
-            "version": "1.2.2",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
+                "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
-                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+                "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3",
-                "sebastian/recursion-context": "~1.0"
+                "sebastian/recursion-context": "~2.0"
             },
             "require-dev": {
                 "ext-mbstring": "*",
@@ -3952,7 +3694,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
@@ -3992,7 +3734,7 @@
                 "export",
                 "exporter"
             ],
-            "time": "2016-06-17 09:04:28"
+            "time": "2016-11-19 08:54:04"
         },
         {
             "name": "sebastian/global-state",
@@ -4046,17 +3788,63 @@
             "time": "2015-10-12 03:26:01"
         },
         {
+            "name": "sebastian/object-enumerator",
+            "version": "2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
+                "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6",
+                "sebastian/recursion-context": "~2.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "time": "2016-11-19 07:35:10"
+        },
+        {
             "name": "sebastian/recursion-context",
-            "version": "1.0.2",
+            "version": "2.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/recursion-context.git",
-                "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+                "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
-                "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+                "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
                 "shasum": ""
             },
             "require": {
@@ -4068,7 +3856,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
@@ -4096,23 +3884,31 @@
             ],
             "description": "Provides functionality to recursively process PHP variables",
             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
-            "time": "2015-11-11 19:50:13"
+            "time": "2016-11-19 07:33:16"
         },
         {
-            "name": "sebastian/version",
-            "version": "1.0.6",
+            "name": "sebastian/resource-operations",
+            "version": "1.0.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
                 "shasum": ""
             },
+            "require": {
+                "php": ">=5.6.0"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
                     "src/"
@@ -4125,96 +3921,89 @@
             "authors": [
                 {
                     "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de",
-                    "role": "lead"
+                    "email": "sebastian@phpunit.de"
                 }
             ],
-            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
-            "homepage": "https://github.com/sebastianbergmann/version",
-            "time": "2015-06-21 13:59:46"
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "time": "2015-07-28 20:34:47"
         },
         {
-            "name": "symfony/class-loader",
-            "version": "v3.1.4",
+            "name": "sebastian/version",
+            "version": "2.0.1",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/class-loader.git",
-                "reference": "2d0ba77c46ecc96a6641009a98f72632216811ba"
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/class-loader/zipball/2d0ba77c46ecc96a6641009a98f72632216811ba",
-                "reference": "2d0ba77c46ecc96a6641009a98f72632216811ba",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.5.9"
-            },
-            "require-dev": {
-                "symfony/finder": "~2.8|~3.0",
-                "symfony/polyfill-apcu": "~1.1"
-            },
-            "suggest": {
-                "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
+                "php": ">=5.6"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Symfony\\Component\\ClassLoader\\": ""
-                },
-                "exclude-from-classmap": [
-                    "/Tests/"
+                "classmap": [
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "MIT"
+                "BSD-3-Clause"
             ],
             "authors": [
                 {
-                    "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
                 }
             ],
-            "description": "Symfony ClassLoader Component",
-            "homepage": "https://symfony.com",
-            "time": "2016-08-23 13:39:15"
+            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+            "homepage": "https://github.com/sebastianbergmann/version",
+            "time": "2016-10-03 07:35:21"
         },
         {
-            "name": "symfony/css-selector",
-            "version": "v3.1.4",
+            "name": "symfony/class-loader",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/css-selector.git",
-                "reference": "2851e1932d77ce727776154d659b232d061e816a"
+                "url": "https://github.com/symfony/class-loader.git",
+                "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/2851e1932d77ce727776154d659b232d061e816a",
-                "reference": "2851e1932d77ce727776154d659b232d061e816a",
+                "url": "https://api.github.com/repos/symfony/class-loader/zipball/2847d56f518ad5721bf85aa9174b3aa3fd12aa03",
+                "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.5.9"
             },
+            "require-dev": {
+                "symfony/finder": "~2.8|~3.0",
+                "symfony/polyfill-apcu": "~1.1"
+            },
+            "suggest": {
+                "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Component\\CssSelector\\": ""
+                    "Symfony\\Component\\ClassLoader\\": ""
                 },
                 "exclude-from-classmap": [
                     "/Tests/"
@@ -4226,10 +4015,6 @@
             ],
             "authors": [
                 {
-                    "name": "Jean-François Simon",
-                    "email": "jeanfrancois.simon@sensiolabs.com"
-                },
-                {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
                 },
@@ -4238,22 +4023,22 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony CssSelector Component",
+            "description": "Symfony ClassLoader Component",
             "homepage": "https://symfony.com",
-            "time": "2016-06-29 05:41:56"
+            "time": "2017-01-21 17:06:35"
         },
         {
             "name": "symfony/dom-crawler",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dom-crawler.git",
-                "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7"
+                "reference": "b814b41373fc4e535aff8c765abe39545216f391"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bb7395e8b1db3654de82b9f35d019958276de4d7",
-                "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b814b41373fc4e535aff8c765abe39545216f391",
+                "reference": "b814b41373fc4e535aff8c765abe39545216f391",
                 "shasum": ""
             },
             "require": {
@@ -4269,7 +4054,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -4296,29 +4081,35 @@
             ],
             "description": "Symfony DomCrawler Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-05 08:37:39"
+            "time": "2017-01-21 17:14:11"
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.1.4",
+            "version": "v3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d"
+                "reference": "e1718c6bf57e1efbb8793ada951584b2ab27775b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/f291ed25eb1435bddbe8a96caaef16469c2a092d",
-                "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/e1718c6bf57e1efbb8793ada951584b2ab27775b",
+                "reference": "e1718c6bf57e1efbb8793ada951584b2ab27775b",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.5.9"
             },
+            "require-dev": {
+                "symfony/console": "~2.8|~3.0"
+            },
+            "suggest": {
+                "symfony/console": "For validating YAML files using the lint command"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.1-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -4345,24 +4136,24 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2016-09-02 02:12:52"
+            "time": "2017-01-21 17:06:35"
         },
         {
             "name": "webmozart/assert",
-            "version": "1.1.0",
+            "version": "1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozart/assert.git",
-                "reference": "bb2d123231c095735130cc8f6d31385a44c7b308"
+                "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308",
-                "reference": "bb2d123231c095735130cc8f6d31385a44c7b308",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
+                "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.3.3|^7.0"
+                "php": "^5.3.3 || ^7.0"
             },
             "require-dev": {
                 "phpunit/phpunit": "^4.6",
@@ -4371,7 +4162,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
@@ -4395,16 +4186,18 @@
                 "check",
                 "validate"
             ],
-            "time": "2016-08-09 15:02:57"
+            "time": "2016-11-23 20:04:58"
         }
     ],
     "aliases": [],
-    "minimum-stability": "stable",
-    "stability-flags": [],
-    "prefer-stable": false,
+    "minimum-stability": "dev",
+    "stability-flags": {
+        "proengsoft/laravel-jsvalidation": 20
+    },
+    "prefer-stable": true,
     "prefer-lowest": false,
     "platform": {
-        "php": ">=5.5.9"
+        "php": ">=5.6.4"
     },
     "platform-dev": []
 }
diff --git a/config/app.php b/config/app.php
index 9371dc8..3fc7d2f 100644
--- a/config/app.php
+++ b/config/app.php
@@ -23,7 +23,7 @@ return [
     | Portal Version
     |--------------------------------------------------------------------------
     */
-    'version' => '1.2.0',
+    'version' => '1.3.0',
 
     /*
     |--------------------------------------------------------------------------
diff --git a/config/database.php b/config/database.php
index b4e0677..7922d30 100644
--- a/config/database.php
+++ b/config/database.php
@@ -4,19 +4,6 @@ return [
 
     /*
     |--------------------------------------------------------------------------
-    | PDO Fetch Style
-    |--------------------------------------------------------------------------
-    |
-    | By default, database results will be returned as instances of the PHP
-    | stdClass object; however, you may desire to retrieve records in an
-    | array format for simplicity. Here you can tweak the fetch style.
-    |
-    */
-
-    'fetch' => PDO::FETCH_CLASS,
-
-    /*
-    |--------------------------------------------------------------------------
     | Default Database Connection Name
     |--------------------------------------------------------------------------
     |
@@ -123,6 +110,8 @@ return [
 
     'redis' => [
 
+        'client' => 'predis',
+
         'cluster' => false,
 
         'default' => [
diff --git a/config/mail.php b/config/mail.php
index 8f8fdd4..1741262 100644
--- a/config/mail.php
+++ b/config/mail.php
@@ -121,4 +121,21 @@ return [
 
     'pretend' => false,
 
+    /*
+    |--------------------------------------------------------------------------
+    | Markdown Mail Settings
+    |--------------------------------------------------------------------------
+    |
+    | If you are using Markdown based email rendering, you may configure your
+    | theme and component paths here, allowing you to customize the design
+    | of the emails. Or, you may simply stick with the Laravel defaults!
+    |
+    */
+    'markdown' => [
+        'theme' => 'default',
+        'paths' => [
+            resource_path('views/vendor/mail'),
+        ],
+    ],
+
 ];
diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php
index 3cf545c..4498b48 100644
--- a/database/factories/ModelFactory.php
+++ b/database/factories/ModelFactory.php
@@ -39,7 +39,7 @@ $factory->define(Portal\Role::class, function (Faker\Generator $faker) {
     return [
         'name' => str_random(5),
         'display_name' => implode(" ", $faker->words(2)),
-        'description' => $faker->paragraph,
+        'description' => substr($faker->paragraph, 0, 255),
         'removable' => true,
     ];
 });
@@ -61,7 +61,7 @@ $factory->define(Activity::class, function (Faker\Generator $faker, array $attrs
 
     return [
         'user_id' => $userId,
-        'description' => $faker->paragraph,
+        'description' => substr($faker->paragraph, 0, 255),
         'ip_address' => $faker->ipv4,
         'user_agent' => $faker->userAgent
     ];
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644
index dc6f1eb..0000000
--- a/gulpfile.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var elixir = require('laravel-elixir');
-
-/*
- |--------------------------------------------------------------------------
- | Elixir Asset Management
- |--------------------------------------------------------------------------
- |
- | Elixir provides a clean, fluent API for defining some basic Gulp tasks
- | for your Laravel application. By default, we are compiling the Sass
- | file for our application, as well as publishing vendor resources.
- |
- */
-
-elixir(function(mix) {
-    mix.sass('app.scss');
-});
diff --git a/package.json b/package.json
index 8b7c633..6b58680 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,14 @@
 {
   "private": true,
   "devDependencies": {
-    "gulp": "^3.8.8"
+    "laravel-mix": "^0.7.2",
+    "bootstrap-sass": "^3.3.7",
+    "lodash": "^4.17.4"
   },
-  "dependencies": {
-    "laravel-elixir": "^3.0.0",
-    "bootstrap-sass": "^3.0.0"
+  "scripts": {
+    "dev": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+    "watch": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+    "hot": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
+    "production": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
   }
 }
diff --git a/phpunit.xml b/phpunit.xml
index 11fc619..62591a4 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -7,11 +7,14 @@
          convertNoticesToExceptions="true"
          convertWarningsToExceptions="true"
          processIsolation="false"
-         stopOnFailure="false"
-         syntaxCheck="false">
+         stopOnFailure="false">
     <testsuites>
-        <testsuite name="Advanced Security Test Suite">
-            <directory>./tests/</directory>
+        <testsuite name="Feature Tests">
+            <directory suffix="Test.php">./tests/Feature</directory>
+        </testsuite>
+
+        <testsuite name="Unit Tests">
+            <directory suffix="Test.php">./tests/Unit</directory>
         </testsuite>
     </testsuites>
     <filter>
diff --git a/resources/lang/en/app.php b/resources/lang/en/app.php
index 4bee34e..4127a63 100644
--- a/resources/lang/en/app.php
+++ b/resources/lang/en/app.php
@@ -335,5 +335,7 @@ return [
         'October' => 'October',
         'November' => 'November',
         'December' => 'December',
-    ]
+    ],
+
+    'avatar_not_changed' => 'Avatar image cannot be updated. Please try again.',
 ];
diff --git a/resources/lang/sr/app.php b/resources/lang/sr/app.php
index 482cacb..98a0cd8 100644
--- a/resources/lang/sr/app.php
+++ b/resources/lang/sr/app.php
@@ -324,5 +324,7 @@ return [
         'October' => 'Oktobar',
         'November' => 'Novembar',
         'December' => 'Decembar',
-    ]
+    ],
+
+    'avatar_not_changed' => 'Avatar ne može biti ažuriran. Molimo pokušajte ponovo.',
 ];
diff --git a/resources/views/user/profile.blade.php b/resources/views/user/profile.blade.php
index 6b3f428..9a1fdb5 100644
--- a/resources/views/user/profile.blade.php
+++ b/resources/views/user/profile.blade.php
@@ -71,7 +71,7 @@
     <div role="tabpanel" class="tab-pane" id="auth">
         <div class="row">
             <div class="col-md-8">
-                {!! Form::open(['route' => 'profile.update.login-details', 'method' => 'PUT', 'id' => 'socials-form']) !!}
+                {!! Form::open(['route' => 'profile.update.login-details', 'method' => 'PUT', 'id' => 'login-details-form']) !!}
                     @include('user.partials.auth')
                 {!! Form::close() !!}
             </div>
@@ -106,7 +106,7 @@
     {!! JsValidator::formRequest('Portal\Http\Requests\User\UpdateDetailsRequest', '#details-form') !!}
     {!! JsValidator::formRequest('Portal\Http\Requests\User\UpdateProfileLoginDetailsRequest', '#login-details-form') !!}
 
-    @if (config('auth.2fa.enabled'))
+    @if (settings('2fa.enabled'))
         {!! JsValidator::formRequest('Portal\Http\Requests\User\EnableTwoFactorRequest', '#two-factor-form') !!}
     @endif
 @stop
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index 22203c5..49513eb 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -59,274 +59,279 @@ Route::get('auth/{provider}/callback', 'Auth\SocialAuthController@handleProvider
 Route::get('auth/twitter/email', 'Auth\SocialAuthController@getTwitterEmail');
 Route::post('auth/twitter/email', 'Auth\SocialAuthController@postTwitterEmail');
 
-/**
- * Other
- */
+Route::group(['middleware' => 'auth'], function () {
 
-Route::get('/', [
-    'as' => 'dashboard',
-    'uses' => 'DashboardController@index'
-]);
+    /**
+     * Dashboard
+     */
 
-/**
- * User Profile
- */
+    Route::get('/', [
+        'as' => 'dashboard',
+        'uses' => 'DashboardController@index'
+    ]);
 
-Route::get('profile', [
-    'as' => 'profile',
-    'uses' => 'ProfileController@index'
-]);
+    /**
+     * User Profile
+     */
 
-Route::get('profile/activity', [
-    'as' => 'profile.activity',
-    'uses' => 'ProfileController@activity'
-]);
+    Route::get('profile', [
+        'as' => 'profile',
+        'uses' => 'ProfileController@index'
+    ]);
 
-Route::put('profile/details/update', [
-    'as' => 'profile.update.details',
-    'uses' => 'ProfileController@updateDetails'
-]);
+    Route::get('profile/activity', [
+        'as' => 'profile.activity',
+        'uses' => 'ProfileController@activity'
+    ]);
 
-Route::post('profile/avatar/update', [
-    'as' => 'profile.update.avatar',
-    'uses' => 'ProfileController@updateAvatar'
-]);
+    Route::put('profile/details/update', [
+        'as' => 'profile.update.details',
+        'uses' => 'ProfileController@updateDetails'
+    ]);
 
-Route::post('profile/avatar/update/external', [
-    'as' => 'profile.update.avatar-external',
-    'uses' => 'ProfileController@updateAvatarExternal'
-]);
+    Route::post('profile/avatar/update', [
+        'as' => 'profile.update.avatar',
+        'uses' => 'ProfileController@updateAvatar'
+    ]);
 
-Route::put('profile/login-details/update', [
-    'as' => 'profile.update.login-details',
-    'uses' => 'ProfileController@updateLoginDetails'
-]);
+    Route::post('profile/avatar/update/external', [
+        'as' => 'profile.update.avatar-external',
+        'uses' => 'ProfileController@updateAvatarExternal'
+    ]);
 
-Route::put('profile/social-networks/update', [
-    'as' => 'profile.update.social-networks',
-    'uses' => 'ProfileController@updateSocialNetworks'
-]);
+    Route::put('profile/login-details/update', [
+        'as' => 'profile.update.login-details',
+        'uses' => 'ProfileController@updateLoginDetails'
+    ]);
 
-Route::post('profile/two-factor/enable', [
-    'as' => 'profile.two-factor.enable',
-    'uses' => 'ProfileController@enableTwoFactorAuth'
-]);
+    Route::put('profile/social-networks/update', [
+        'as' => 'profile.update.social-networks',
+        'uses' => 'ProfileController@updateSocialNetworks'
+    ]);
 
-Route::post('profile/two-factor/disable', [
-    'as' => 'profile.two-factor.disable',
-    'uses' => 'ProfileController@disableTwoFactorAuth'
-]);
+    Route::post('profile/two-factor/enable', [
+        'as' => 'profile.two-factor.enable',
+        'uses' => 'ProfileController@enableTwoFactorAuth'
+    ]);
 
-Route::get('profile/sessions', [
-    'as' => 'profile.sessions',
-    'uses' => 'ProfileController@sessions'
-]);
+    Route::post('profile/two-factor/disable', [
+        'as' => 'profile.two-factor.disable',
+        'uses' => 'ProfileController@disableTwoFactorAuth'
+    ]);
 
-Route::delete('profile/sessions/{session}/invalidate', [
-    'as' => 'profile.sessions.invalidate',
-    'uses' => 'ProfileController@invalidateSession'
-]);
+    Route::get('profile/sessions', [
+        'as' => 'profile.sessions',
+        'uses' => 'ProfileController@sessions'
+    ]);
 
-/**
- * User Management
- */
-Route::get('user', [
-    'as' => 'user.list',
-    'uses' => 'UsersController@index'
-]);
+    Route::delete('profile/sessions/{session}/invalidate', [
+        'as' => 'profile.sessions.invalidate',
+        'uses' => 'ProfileController@invalidateSession'
+    ]);
 
-Route::get('user/create', [
-    'as' => 'user.create',
-    'uses' => 'UsersController@create'
-]);
+    /**
+     * User Management
+     */
+    Route::get('user', [
+        'as' => 'user.list',
+        'uses' => 'UsersController@index'
+    ]);
 
-Route::post('user/create', [
-    'as' => 'user.store',
-    'uses' => 'UsersController@store'
-]);
+    Route::get('user/create', [
+        'as' => 'user.create',
+        'uses' => 'UsersController@create'
+    ]);
 
-Route::get('user/{user}/show', [
-    'as' => 'user.show',
-    'uses' => 'UsersController@view'
-]);
+    Route::post('user/create', [
+        'as' => 'user.store',
+        'uses' => 'UsersController@store'
+    ]);
 
-Route::get('user/{user}/edit', [
-    'as' => 'user.edit',
-    'uses' => 'UsersController@edit'
-]);
+    Route::get('user/{user}/show', [
+        'as' => 'user.show',
+        'uses' => 'UsersController@view'
+    ]);
 
-Route::put('user/{user}/update/details', [
-    'as' => 'user.update.details',
-    'uses' => 'UsersController@updateDetails'
-]);
+    Route::get('user/{user}/edit', [
+        'as' => 'user.edit',
+        'uses' => 'UsersController@edit'
+    ]);
 
-Route::put('user/{user}/update/login-details', [
-    'as' => 'user.update.login-details',
-    'uses' => 'UsersController@updateLoginDetails'
-]);
+    Route::put('user/{user}/update/details', [
+        'as' => 'user.update.details',
+        'uses' => 'UsersController@updateDetails'
+    ]);
 
-Route::delete('user/{user}/delete', [
-    'as' => 'user.delete',
-    'uses' => 'UsersController@delete'
-]);
+    Route::put('user/{user}/update/login-details', [
+        'as' => 'user.update.login-details',
+        'uses' => 'UsersController@updateLoginDetails'
+    ]);
 
-Route::post('user/{user}/update/avatar', [
-    'as' => 'user.update.avatar',
-    'uses' => 'UsersController@updateAvatar'
-]);
+    Route::delete('user/{user}/delete', [
+        'as' => 'user.delete',
+        'uses' => 'UsersController@delete'
+    ]);
 
-Route::post('user/{user}/update/avatar/external', [
-    'as' => 'user.update.avatar.external',
-    'uses' => 'UsersController@updateAvatarExternal'
-]);
+    Route::post('user/{user}/update/avatar', [
+        'as' => 'user.update.avatar',
+        'uses' => 'UsersController@updateAvatar'
+    ]);
 
-Route::post('user/{user}/update/social-networks', [
-    'as' => 'user.update.socials',
-    'uses' => 'UsersController@updateSocialNetworks'
-]);
+    Route::post('user/{user}/update/avatar/external', [
+        'as' => 'user.update.avatar.external',
+        'uses' => 'UsersController@updateAvatarExternal'
+    ]);
 
-Route::get('user/{user}/sessions', [
-    'as' => 'user.sessions',
-    'uses' => 'UsersController@sessions'
-]);
+    Route::post('user/{user}/update/social-networks', [
+        'as' => 'user.update.socials',
+        'uses' => 'UsersController@updateSocialNetworks'
+    ]);
 
-Route::delete('user/{user}/sessions/{session}/invalidate', [
-    'as' => 'user.sessions.invalidate',
-    'uses' => 'UsersController@invalidateSession'
-]);
+    Route::get('user/{user}/sessions', [
+        'as' => 'user.sessions',
+        'uses' => 'UsersController@sessions'
+    ]);
 
-Route::post('user/{user}/two-factor/enable', [
-    'as' => 'user.two-factor.enable',
-    'uses' => 'UsersController@enableTwoFactorAuth'
-]);
+    Route::delete('user/{user}/sessions/{session}/invalidate', [
+        'as' => 'user.sessions.invalidate',
+        'uses' => 'UsersController@invalidateSession'
+    ]);
 
-Route::post('user/{user}/two-factor/disable', [
-    'as' => 'user.two-factor.disable',
-    'uses' => 'UsersController@disableTwoFactorAuth'
-]);
+    Route::post('user/{user}/two-factor/enable', [
+        'as' => 'user.two-factor.enable',
+        'uses' => 'UsersController@enableTwoFactorAuth'
+    ]);
 
-/**
- * Roles & Permissions
- */
+    Route::post('user/{user}/two-factor/disable', [
+        'as' => 'user.two-factor.disable',
+        'uses' => 'UsersController@disableTwoFactorAuth'
+    ]);
 
-Route::get('role', [
-    'as' => 'role.index',
-    'uses' => 'RolesController@index'
-]);
+    /**
+     * Roles & Permissions
+     */
 
-Route::get('role/create', [
-    'as' => 'role.create',
-    'uses' => 'RolesController@create'
-]);
+    Route::get('role', [
+        'as' => 'role.index',
+        'uses' => 'RolesController@index'
+    ]);
 
-Route::post('role/store', [
-    'as' => 'role.store',
-    'uses' => 'RolesController@store'
-]);
+    Route::get('role/create', [
+        'as' => 'role.create',
+        'uses' => 'RolesController@create'
+    ]);
 
-Route::get('role/{role}/edit', [
-    'as' => 'role.edit',
-    'uses' => 'RolesController@edit'
-]);
+    Route::post('role/store', [
+        'as' => 'role.store',
+        'uses' => 'RolesController@store'
+    ]);
 
-Route::put('role/{role}/update', [
-    'as' => 'role.update',
-    'uses' => 'RolesController@update'
-]);
+    Route::get('role/{role}/edit', [
+        'as' => 'role.edit',
+        'uses' => 'RolesController@edit'
+    ]);
 
-Route::delete('role/{role}/delete', [
-    'as' => 'role.delete',
-    'uses' => 'RolesController@delete'
-]);
+    Route::put('role/{role}/update', [
+        'as' => 'role.update',
+        'uses' => 'RolesController@update'
+    ]);
 
+    Route::delete('role/{role}/delete', [
+        'as' => 'role.delete',
+        'uses' => 'RolesController@delete'
+    ]);
 
-Route::post('permission/save', [
-    'as' => 'permission.save',
-    'uses' => 'PermissionsController@saveRolePermissions'
-]);
 
-Route::resource('permission', 'PermissionsController');
+    Route::post('permission/save', [
+        'as' => 'permission.save',
+        'uses' => 'PermissionsController@saveRolePermissions'
+    ]);
 
-/**
- * Settings
- */
+    Route::resource('permission', 'PermissionsController');
 
-Route::get('settings', [
-    'as' => 'settings.general',
-    'uses' => 'SettingsController@general',
-    'middleware' => 'permission:settings.general'
-]);
+    /**
+     * Settings
+     */
 
-Route::post('settings/general', [
-    'as' => 'settings.general.update',
-    'uses' => 'SettingsController@update',
-    'middleware' => 'permission:settings.general'
-]);
+    Route::get('settings', [
+        'as' => 'settings.general',
+        'uses' => 'SettingsController@general',
+        'middleware' => 'permission:settings.general'
+    ]);
 
-Route::get('settings/auth', [
-    'as' => 'settings.auth',
-    'uses' => 'SettingsController@auth',
-    'middleware' => 'permission:settings.auth'
-]);
+    Route::post('settings/general', [
+        'as' => 'settings.general.update',
+        'uses' => 'SettingsController@update',
+        'middleware' => 'permission:settings.general'
+    ]);
 
-Route::post('settings/auth', [
-    'as' => 'settings.auth.update',
-    'uses' => 'SettingsController@update',
-    'middleware' => 'permission:settings.auth'
-]);
+    Route::get('settings/auth', [
+        'as' => 'settings.auth',
+        'uses' => 'SettingsController@auth',
+        'middleware' => 'permission:settings.auth'
+    ]);
+
+    Route::post('settings/auth', [
+        'as' => 'settings.auth.update',
+        'uses' => 'SettingsController@update',
+        'middleware' => 'permission:settings.auth'
+    ]);
 
 // Only allow managing 2FA if AUTHY_KEY is defined inside .env file
-if (env('AUTHY_KEY')) {
-    Route::post('settings/auth/2fa/enable', [
-        'as' => 'settings.auth.2fa.enable',
-        'uses' => 'SettingsController@enableTwoFactor',
+    if (env('AUTHY_KEY')) {
+        Route::post('settings/auth/2fa/enable', [
+            'as' => 'settings.auth.2fa.enable',
+            'uses' => 'SettingsController@enableTwoFactor',
+            'middleware' => 'permission:settings.auth'
+        ]);
+
+        Route::post('settings/auth/2fa/disable', [
+            'as' => 'settings.auth.2fa.disable',
+            'uses' => 'SettingsController@disableTwoFactor',
+            'middleware' => 'permission:settings.auth'
+        ]);
+    }
+
+    Route::post('settings/auth/registration/captcha/enable', [
+        'as' => 'settings.registration.captcha.enable',
+        'uses' => 'SettingsController@enableCaptcha',
         'middleware' => 'permission:settings.auth'
     ]);
 
-    Route::post('settings/auth/2fa/disable', [
-        'as' => 'settings.auth.2fa.disable',
-        'uses' => 'SettingsController@disableTwoFactor',
+    Route::post('settings/auth/registration/captcha/disable', [
+        'as' => 'settings.registration.captcha.disable',
+        'uses' => 'SettingsController@disableCaptcha',
         'middleware' => 'permission:settings.auth'
     ]);
-}
 
-Route::post('settings/auth/registration/captcha/enable', [
-    'as' => 'settings.registration.captcha.enable',
-    'uses' => 'SettingsController@enableCaptcha',
-    'middleware' => 'permission:settings.auth'
-]);
+    Route::get('settings/notifications', [
+        'as' => 'settings.notifications',
+        'uses' => 'SettingsController@notifications',
+        'middleware' => 'permission:settings.notifications'
+    ]);
 
-Route::post('settings/auth/registration/captcha/disable', [
-    'as' => 'settings.registration.captcha.disable',
-    'uses' => 'SettingsController@disableCaptcha',
-    'middleware' => 'permission:settings.auth'
-]);
+    Route::post('settings/notifications', [
+        'as' => 'settings.notifications.update',
+        'uses' => 'SettingsController@update',
+        'middleware' => 'permission:settings.notifications'
+    ]);
 
-Route::get('settings/notifications', [
-    'as' => 'settings.notifications',
-    'uses' => 'SettingsController@notifications',
-    'middleware' => 'permission:settings.notifications'
-]);
+    /**
+     * Activity Log
+     */
 
-Route::post('settings/notifications', [
-    'as' => 'settings.notifications.update',
-    'uses' => 'SettingsController@update',
-    'middleware' => 'permission:settings.notifications'
-]);
+    Route::get('activity', [
+        'as' => 'activity.index',
+        'uses' => 'ActivityController@index'
+    ]);
 
-/**
- * Activity Log
- */
+    Route::get('activity/user/{user}/log', [
+        'as' => 'activity.user',
+        'uses' => 'ActivityController@userActivity'
+    ]);
 
-Route::get('activity', [
-    'as' => 'activity.index',
-    'uses' => 'ActivityController@index'
-]);
+});
 
-Route::get('activity/user/{user}/log', [
-    'as' => 'activity.user',
-    'uses' => 'ActivityController@userActivity'
-]);
 
 /**
  * Installation
diff --git a/storage/settings.json b/storage/settings.json
index 6b532c6..ae9856f 100644
--- a/storage/settings.json
+++ b/storage/settings.json
@@ -1 +1 @@
-{"remember_me":true,"notifications_signup_email":true,"forgot_password":"1","login_reset_token_lifetime":"30","throttle_enabled":true,"throttle_attempts":10,"throttle_lockout_time":2,"reg_enabled":false,"reg_email_confirmation":true,"2fa":{"enabled":true},"app_name":"Portal","registration":{"captcha":{"enabled":false}},"tos":"1","captcha":{"enabled":null}}
\ No newline at end of file
+{"remember_me":true,"notifications_signup_email":true,"forgot_password":true,"login_reset_token_lifetime":"30","throttle_enabled":true,"throttle_attempts":10,"throttle_lockout_time":2,"reg_enabled":false,"reg_email_confirmation":false,"2fa":{"enabled":true},"app_name":"foo","registration":{"captcha":{"enabled":true}},"tos":"1","captcha":{"enabled":false}}
\ No newline at end of file
diff --git a/tests/Feature/FunctionalTestCase.php b/tests/Feature/FunctionalTestCase.php
new file mode 100644
index 0000000..21d4a31
--- /dev/null
+++ b/tests/Feature/FunctionalTestCase.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace Tests\Feature;
+
+use DB;
+use Schema;
+use Settings;
+use Tests\TestCase;
+use Portal\Role;
+use Portal\User;
+use Mockery as m;
+
+class FunctionalTestCase extends TestCase
+{
+    use \Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase;
+
+    protected $seed = true;
+
+    protected $settingsModified = [];
+
+    public function setUp()
+    {
+        $this->afterApplicationCreated(function () {
+            if ($this->isSQLiteConnection()) {
+                DB::connection()->getPdo()->exec("pragma foreign_keys=1");
+            }
+
+            $this->artisan('migrate');
+
+            if ($this->seed) {
+                $this->artisan('db:seed', ['--class' => 'CountriesSeeder']);
+                $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
+                $this->artisan('db:seed', ['--class' => 'PermissionsSeeder']);
+            }
+        });
+
+        $this->beforeApplicationDestroyed(function () {
+            if (Schema::hasTable('migrations')) {
+                $this->artisan('migrate:rollback');
+            }
+            \DB::disconnect();
+        });
+
+        $this->beforeApplicationDestroyed(function () {
+            foreach ($this->settingsModified as $key => $value) {
+                Settings::set($key, $value);
+            }
+
+            Settings::save();
+
+            $this->settingsModified = [];
+        });
+
+        parent::setUp();
+    }
+
+    /**
+     * Set some setting that should automatically be
+     * reverted to it's default value after each test.
+     * @param array $settings
+     */
+    protected function setSettings(array $settings)
+    {
+        foreach ($settings as $key => $value) {
+            $this->settingsModified[$key] = settings($key);
+            Settings::set($key, $value);
+        }
+
+        Settings::save();
+
+        $this->refreshAppAndExecuteCallbacks();
+    }
+
+    /**
+     * @param array $attrubutes
+     * @return mixed
+     */
+    protected function createAndLoginUser(array $attrubutes = [])
+    {
+        $user = $this->createUserWithSocialNetworks($attrubutes);
+
+        $user = $this->setRoleForUser($user, 'User');
+
+        $this->be($user);
+
+        return $user;
+    }
+
+    /**
+     * @param array $attrubutes
+     * @return mixed
+     */
+    protected function createAndLoginAdminUser(array $attrubutes = [])
+    {
+        $user = $this->createUserWithSocialNetworks($attrubutes);
+
+        $user = $this->setRoleForUser($user, 'Admin');
+
+        $this->be($user);
+
+        return $user;
+    }
+
+    /**
+     * @param array $attributes
+     * @return mixed
+     */
+    protected function createUserWithSocialNetworks(array $attributes = [])
+    {
+        $user = factory(User::class)->create($attributes);
+        $user->socialNetworks()->create([]);
+
+        return $user;
+    }
+
+    /**
+     * @return mixed
+     */
+    protected function createSuperUser()
+    {
+        $user = factory(User::class)->create();
+        return $this->makeSuperUser($user);
+    }
+
+    protected function makeSuperUser(User $user = null)
+    {
+        $user = m::mock($user ?: User::class)->makePartial();
+        $user->shouldReceive('can')->andReturn(true);
+
+        return $user;
+    }
+
+    /**
+     * @param User $user
+     * @param $role
+     * @return User
+     */
+    public function setRoleForUser(User $user, $role)
+    {
+        $role = Role::where('name', $role)->first();
+        $user->roles()->attach($role);
+
+        return $user;
+    }
+
+    public function seeInTable($selector, $text, $rowNumber, $columnNumber, $negate = false)
+    {
+        $fullSelector = "{$selector} tbody tr:nth-child({$rowNumber}) > td:nth-child({$columnNumber})";
+        return $this->seeInElement($fullSelector, $text, $negate);
+    }
+
+    public function dontSeeInTable($selector, $text, $rowNumber, $columnNumber)
+    {
+        return $this->seeInTable($selector, $text, $rowNumber, $columnNumber, true);
+    }
+
+    /**
+     * Click on link that matches provided selector.
+     *
+     * @param $selector
+     * @return $this
+     */
+    protected function clickOn($selector)
+    {
+        $link = $this->crawler->filter($selector)->first();
+        return $this->visit($link->link()->getUri());
+    }
+}
diff --git a/tests/Feature/Http/Controllers/ActivityControllerTest.php b/tests/Feature/Http/Controllers/ActivityControllerTest.php
new file mode 100644
index 0000000..27b1e95
--- /dev/null
+++ b/tests/Feature/Http/Controllers/ActivityControllerTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Input;
+use Tests\Feature\FunctionalTestCase;
+use Portal\User;
+use Carbon\Carbon;
+
+class ActivityControllerTest extends FunctionalTestCase
+{
+    /**
+     * @var \Portal\Services\Logging\UserActivity\Logger
+     */
+    public $logger;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->logger = app(\Portal\Services\Logging\UserActivity\Logger::class);
+    }
+
+    public function test_display_all_activities()
+    {
+        $this->withoutMiddleware();
+
+        $user1 = factory(User::class)->create();
+        $user2 = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now());
+        $this->be($user1);
+        $this->logger->log('foo');
+
+        $this->be($user2);
+        $this->logger->log('bar');
+
+        $this->visit('activity');
+
+        $this->assertEquals(2, $this->crawler->filter('table tbody tr')->count());
+
+        $this->seeUserActivity($user1, 'foo', 1);
+        $this->seeUserActivity($user2, 'bar', 2);
+    }
+
+    public function test_display_activities_for_user()
+    {
+        $user = $this->createAndLoginAdminUser();
+
+        $this->logger->log('foo');
+
+        $this->visit('activity')
+            ->clickOn('table tbody a:first-child')
+            ->seePageIs("activity/user/{$user->id}/log")
+            ->seeUserActivity($user, 'foo', 1);
+    }
+
+    public function test_search_activities()
+    {
+        $this->withoutMiddleware();
+
+        $user = factory(User::class)->create();
+        $this->be($user);
+        $this->logger->log('foo');
+        $this->logger->log('bar');
+
+        $this->visit('activity')
+            ->type('fo', 'search')
+            ->press('search-activities-btn');
+
+        $this->seePageIs('activity?search=fo');
+        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
+        $this->seeUserActivity($user, 'foo', 1);
+    }
+
+    private function seeUserActivity($user, $message, $row)
+    {
+        return $this->seeInTable('table', $user->present()->nameOrEmail, $row, 1)
+            ->seeInTable('table', Input::ip(), $row, 2)
+            ->seeInTable('table', $message, $row, 3)
+            ->seeInTable('table', Carbon::now(), $row, 4)
+            ->seeElement("table tbody tr:nth-child({$row}) > td:nth-child(5) > a[data-content='".Input::header('User-agent')."']");
+    }
+
+}
diff --git a/tests/Feature/Http/Controllers/Auth/AuthControllerTest.php b/tests/Feature/Http/Controllers/Auth/AuthControllerTest.php
new file mode 100644
index 0000000..e676f84
--- /dev/null
+++ b/tests/Feature/Http/Controllers/Auth/AuthControllerTest.php
@@ -0,0 +1,399 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers\Auth;
+
+use Authy;
+use Mockery;
+use Settings;
+use Tests\Feature\FunctionalTestCase;
+use Tests\MailTrap;
+use Portal\Events\User\LoggedIn;
+use Portal\Events\User\Registered;
+use Portal\Role;
+use Portal\Support\Enum\UserStatus;
+use Portal\User;
+use Mockery as m;
+
+class AuthControllerTest extends FunctionalTestCase
+{
+    use MailTrap;
+
+    public function test_login()
+    {
+        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
+
+        $this->loginUser('foo', 'bar')
+            ->seePageIs('/');
+    }
+
+    public function test_login_with_wrong_credentials()
+    {
+        $this->loginUser('foo', 'bar')
+            ->seePageIs('login')
+            ->see("These credentials do not match our records.");
+    }
+
+    public function test_throttling()
+    {
+        $this->setSettings([
+            'throttle_enabled' => true,
+            'throttle_attempts' => 3,
+            'throttle_lockout_time' => 2 // 2 minutes
+        ]);
+
+        for ($i = 0; $i < 3; $i++) {
+            $this->loginUser('foo', 'bar');
+        }
+
+        $this->loginUser('foo', 'bar')
+            ->seePageIs('login')
+            ->see("Too many login attempts. Please try again in 120 seconds.");
+    }
+
+    public function test_login_with_remember()
+    {
+        $user = factory(User::class)->create([
+            'username' => 'foo',
+            'password' => 'bar',
+            'last_login' => null,
+            'remember_token' => null
+        ]);
+
+        Settings::set('remember_me', false);
+
+        $this->visit('login')
+            ->dontSeeElement('#remember');
+
+        Settings::set('remember_me', true);
+
+        $this->visit('login')
+            ->seeElement('#remember')
+            ->loginUser('foo', 'bar', true)
+            ->seePageIs('/');
+
+        $user = $user->fresh();
+
+        $this->assertNotNull($user->remember_token);
+        $this->assertNotNull($user->last_login);
+    }
+
+    public function test_banned_user_cannot_log_in()
+    {
+        factory(User::class)->create([
+            'username' => 'foo',
+            'password' => 'bar',
+            'status' => UserStatus::BANNED
+        ]);
+
+        $this->loginUser('foo', 'bar');
+
+        $this->seePageIs('login')
+            ->see("Your account is banned by administrator.");
+    }
+
+    public function test_unconfirmed_user_cannot_login()
+    {
+        factory(User::class)->create([
+            'username' => 'foo',
+            'password' => 'bar',
+            'status' => UserStatus::UNCONFIRMED
+        ]);
+
+        $this->loginUser('foo', 'bar');
+
+        $this->seePageIs('login')
+            ->see("Please confirm your email address first.");
+    }
+
+    /**
+     * @expectedException \Laravel\BrowserKitTesting\HttpException
+     */
+    public function test_registration_view()
+    {
+        $this->setSettings([
+            'reg_enabled' => false
+        ]);
+
+        $this->visit('login')
+            ->dontSee('You don\'t have an account?');
+
+        // This should fire HttpException since registration is disabled.
+        $this->visit('register');
+    }
+
+    public function test_registration_with_email_confirmation()
+    {
+        $this->setSettings([
+            'reg_enabled' => true,
+            'reg_email_confirmation' => true,
+            'registration.captcha.enabled' => false
+        ]);
+
+        $this->expectsEvents(Registered::class);
+
+        $data = $this->getRegistrationFormStubData();
+
+        $this->registerUser($data);
+
+        $expected = array_except($data, ['password', 'password_confirmation', 'tos']);
+        $expected += ['status' => UserStatus::UNCONFIRMED];
+
+        $this->seePageIs('login')
+            ->see('You account is created successfully! Please confirm your email in order to log in.')
+            ->seeInDatabase('users', $expected);
+
+        $token = User::where('email', $data['email'])->first()->confirmation_token;
+
+        $message = $this->fetchInbox()[0];
+
+        $this->assertEquals('test@test.com', $message['to_email']);
+        $this->assertEquals(config('mail.from.address'), $message['from_email']);
+        $this->assertEquals(config('mail.from.name'), $message['from_name']);
+        $this->assertContains(
+            trans('app.thank_you_for_registering', ['app' => settings('app_name')]),
+            trim($message['html_body'])
+        );
+        $this->assertContains(
+            trans('app.confirm_email_on_link_below'),
+            trim($message['html_body'])
+        );
+        $this->assertContains(
+            route('register.confirm-email', $token),
+            trim($message['html_body'])
+        );
+
+        $this->emptyInbox();
+    }
+
+    public function test_registration_without_email_confirmation()
+    {
+        $this->setSettings([
+            'reg_enabled' => true,
+            'reg_email_confirmation' => false,
+            'notifications_signup_email' => false,
+            'registration.captcha.enabled' => false
+        ]);
+
+        $this->expectsEvents(Registered::class);
+
+        $data = $this->getRegistrationFormStubData();
+        $this->registerUser($data);
+
+        $expected = array_except($data, ['password', 'password_confirmation', 'tos']);
+        $expected += ['status' => UserStatus::ACTIVE];
+
+        $this->seePageIs('login')
+            ->see('You account is created successfully! You can log in now.')
+            ->seeInDatabase('users', $expected);
+
+        $this->assertEmpty($this->fetchInbox());
+    }
+
+    public function test_email_notification_when_new_user_was_registered()
+    {
+        $this->setSettings([
+            'app_name' => 'foo',
+            'reg_enabled' => true,
+            'reg_email_confirmation' => false,
+            'notifications_signup_email' => true,
+            'registration.captcha.enabled' => false
+        ]);
+
+        $admin1 = factory(User::class)->create(['email' => 'john.doe@test.com']);
+        $admin2 = factory(User::class)->create(['email' => 'jane.doe@test.com']);
+        $user = factory(User::class)->create(['email' => 'user.doe@test.com']);
+
+        $role = Role::where('name', 'Admin')->first();
+        $role->users()->attach([$admin1->id, $admin2->id]);
+
+        $role = Role::where('name', 'User')->first();
+        $role->users()->attach($user->id);
+
+        $data = $this->getRegistrationFormStubData();
+        $this->registerUser($data);
+
+        $newUser = User::where('email', $data['email'])->first();
+
+        $inbox = $this->fetchInbox();
+
+        $this->assertEquals(2, count($inbox));
+
+        $this->assertEquals('[foo] New User Registration', $inbox[0]['subject']);
+        $this->assertEquals('jane.doe@test.com', $inbox[0]['to_email']);
+        $this->assertContains(
+            trans('app.new_user_was_registered_on', ['app' => settings('app_name')]),
+            trim($inbox[0]['html_body'])
+        );
+        $this->assertContains(
+            trans('app.to_view_details_visit_link_below'),
+            trim($inbox[0]['html_body'])
+        );
+        $this->assertContains(
+            route('user.show', $newUser->id),
+            trim($inbox[0]['html_body'])
+        );
+
+        $this->assertEquals('[foo] New User Registration', $inbox[1]['subject']);
+        $this->assertEquals('john.doe@test.com', $inbox[1]['to_email']);
+
+        $this->emptyInbox();
+    }
+
+    public function test_redirect_to_custom_page_after_login()
+    {
+        $to = '?to=http://www.google.com';
+
+        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
+
+        $this->visit('login' . $to)
+            ->seeElement('input', ['type' => 'hidden', 'name' => 'to'])
+            ->type('foo', 'username')
+            ->type('bar', 'password')
+            ->press('Log In');
+
+        $this->seePageIs('http://www.google.com');
+    }
+
+    public function test_custom_redirect_page_is_available_after_failed_login_attempt()
+    {
+        $to = 'http://www.google.com';
+        $element = 'input';
+        $elementAttrs = ['type' => 'hidden', 'name' => 'to'];
+
+        $this->visit('login?to=' . $to)
+            ->seeElement($element, $elementAttrs)
+            ->type('foo', 'username')
+            ->type('bar', 'password')
+            ->press('Log In');
+
+        $this->seePageIs('login?to=' . urlencode($to))
+            ->seeElement($element, $elementAttrs);
+    }
+
+    public function test_access_to_auth_pages_is_not_allowed_after_authentication()
+    {
+        $this->setSettings([
+            'reg_enabled' => true,
+            '2fa.enabled' => true
+        ]);
+
+        $this->refreshAppAndExecuteCallbacks();
+
+        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
+        $this->loginUser('foo', 'bar');
+
+        $forbiddenGetRoutes = [
+            'login', 'register', 'register/confirmation/123', 'password/remind', 'password/reset/123',
+            'auth/two-factor-authentication', 'auth/facebook/login', 'auth/facebook/callback',
+            'auth/twitter/email'
+        ];
+
+        foreach ($forbiddenGetRoutes as $route) {
+            $this->visit($route)
+                ->seePageIs('/');
+        }
+    }
+
+    private function getRegistrationFormStubData()
+    {
+        return [
+            'email' => 'test@test.com',
+            'username' => 'johndoe',
+            'password' => '123123',
+            'password_confirmation' => '123123',
+            'tos' => 1
+        ];
+    }
+
+    private function registerUser($data)
+    {
+        return $this->visit('login')
+            ->click("Don't have an account?")
+            ->seePageIs('register')
+            ->submitForm('Register', $data);
+    }
+
+    /**
+     * @param $username
+     * @param $password
+     * @param bool $remember
+     * @return $this
+     */
+    private function loginUser($username, $password, $remember = false)
+    {
+        $this->visit('login')
+            ->type($username, 'username')
+            ->type($password, 'password');
+
+        if ($remember) {
+            $this->check('remember');
+        }
+
+        $this->press('Log In');
+
+        return $this;
+    }
+
+    public function test_login_with_2fa_enabled()
+    {
+        $this->setSettings(['2fa.enabled' => true]);
+
+        $this->expectsEvents(LoggedIn::class);
+
+        $user = factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
+
+        Authy::shouldReceive('isEnabled')->andReturn(true);
+        Authy::shouldReceive('tokenIsValid')->with(m::any(), '123')->andReturn(true);
+
+        $this->loginUser('foo', 'bar')
+            ->seePageIs('auth/two-factor-authentication')
+            ->seeInSession('auth.2fa.id', $user->id);
+
+        $this->type('123', 'token')
+            ->press('Validate')
+            ->seePageIs('/');
+    }
+
+    public function test_login_with_wrong_2fa_token()
+    {
+        $this->setSettings(['2fa.enabled' => true]);
+
+        $this->refreshAppAndExecuteCallbacks();
+
+        $user = factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
+
+        Authy::shouldReceive('isEnabled')->andReturn(true);
+        Authy::shouldReceive('tokenIsValid')->with(m::any(), '123')->andReturn(false);
+
+        $this->loginUser('foo', 'bar')
+            ->seePageIs('auth/two-factor-authentication')
+            ->seeInSession('auth.2fa.id', $user->id);
+
+        $this->type('123', 'token')
+            ->press('Validate')
+            ->seePageIs('login')
+            ->see('2FA Token is invalid!');
+    }
+
+    /**
+     * Mock the event dispatcher so all events are silenced and collected.
+     * We will override it to allow model events though, since we want
+     * user notifications to be sent, so we can test them.
+     *
+     * @return $this
+     */
+    protected function withoutEvents()
+    {
+        $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher');
+
+        $mock->shouldReceive('fire', 'dispatch')->andReturnUsing(function ($called) {
+            $this->firedEvents[] = $called;
+        });
+
+        $mock->shouldReceive('until');
+
+        $this->app->instance('events', $mock);
+
+        return $this;
+    }
+}
diff --git a/tests/Feature/Http/Controllers/Auth/PasswordControllerTest.php b/tests/Feature/Http/Controllers/Auth/PasswordControllerTest.php
new file mode 100644
index 0000000..02ed9b1
--- /dev/null
+++ b/tests/Feature/Http/Controllers/Auth/PasswordControllerTest.php
@@ -0,0 +1,167 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers\Authy;
+
+use DB;
+use Hash;
+use Illuminate\Support\Str;
+use Mockery;
+use Tests\Feature\FunctionalTestCase;
+use Tests\MailTrap;
+use Portal\Events\User\RequestedPasswordResetEmail;
+use Portal\User;
+use Mockery as m;
+
+class PasswordControllerTest extends FunctionalTestCase
+{
+    use MailTrap;
+
+    public function test_send_password_reminder()
+    {
+        factory(User::class)->create(['email' => 'test@test.com']);
+
+        $this->expectsEvents(RequestedPasswordResetEmail::class);
+
+        $this->visit('password/remind')
+            ->type('test@test.com', 'email')
+            ->press('Reset Password')
+            ->seePageIs('password/remind')
+            ->see('Password reset email sent. Check your inbox (and spam) folder.');
+
+        $message = $this->fetchInbox()[0];
+
+        $this->assertEquals('test@test.com', $message['to_email']);
+        $this->assertEquals(config('mail.from.address'), $message['from_email']);
+        $this->assertEquals(config('mail.from.name'), $message['from_name']);
+        $this->assertContains(
+            trans('app.request_for_password_reset_made'),
+            $message['html_body']
+        );
+
+        $this->assertContains(
+            trans('app.if_you_did_not_requested'),
+            $message['html_body']
+        );
+
+        $this->emptyInbox();
+    }
+
+    public function test_password_reminder_with_wrong_email()
+    {
+        $this->visit('password/remind')
+            ->type('test@test.com', 'email')
+            ->press('Reset Password')
+            ->seePageIs('password/remind')
+            ->see('The selected email is invalid.');
+    }
+
+    public function test_password_reset()
+    {
+        $this->setSettings(['forgot_password' => true]);
+
+        $user = factory(User::class)->create(['email' => 'test@test.com']);
+
+        $token = $this->createNewToken();
+
+        DB::table('password_resets')->insert([
+            'email' => $user->email,
+            'token' => Hash::make($token),
+            'created_at' => \Carbon\Carbon::now()
+        ]);
+
+        $this->resetPassword($token, $user->email);
+
+        $this->seePageIs('login')
+            ->see('Your password has been reset!');
+
+        $user = $user->fresh();
+
+        $this->assertTrue(Hash::check('123123', $user->password));
+    }
+
+    public function test_password_reset_with_expired_token()
+    {
+        $this->setSettings(['forgot_password' => true]);
+
+        $user = factory(User::class)->create(['email' => 'test@test.com']);
+
+        $token = $this->createNewToken();
+
+        DB::table('password_resets')->insert([
+            'email' => $user->email,
+            'token' => Hash::make($token),
+            'created_at' => \Carbon\Carbon::now()->subHours(2)
+        ]);
+
+        $this->resetPassword($token, $user->email);
+
+        $this->seePageIs("password/reset/{$token}")
+            ->see("This password reset token is invalid.");
+    }
+
+    public function test_password_reset_with_invalid_email()
+    {
+        $this->setSettings(['forgot_password' => true]);
+
+        $user = factory(User::class)->create(['email' => 'test@test.com']);
+
+        $token = $this->createNewToken();
+
+        DB::table('password_resets')->insert([
+            'email' => $user->email,
+            'token' => Hash::make($token),
+            'created_at' => \Carbon\Carbon::now()
+        ]);
+
+        $this->resetPassword($token, 'foo@bar.com');
+
+        $this->seePageIs("password/reset/{$token}")
+            ->see("We can't find a user with that e-mail address.");
+    }
+
+    /**
+     * @param $token
+     * @param $email
+     */
+    private function resetPassword($token, $email)
+    {
+        $this->visit("password/reset/{$token}")
+            ->type($email, 'email')
+            ->type('123123', 'password')
+            ->type('123123', 'password_confirmation')
+            ->press('Update Password');
+    }
+
+    /**
+     * Mock the event dispatcher so all events are silenced and collected.
+     * We will override it to allow model events though, since we want
+     * user notifications to be sent, so we can test them.
+     *
+     * @return $this
+     */
+    protected function withoutEvents()
+    {
+        $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher');
+
+        $mock->shouldReceive('fire', 'dispatch', 'getCommandHandler')->andReturnUsing(function ($called) {
+            $this->firedEvents[] = $called;
+        });
+
+        $mock->shouldReceive('until');
+
+        $this->app->instance('events', $mock);
+
+        return $this;
+    }
+
+    private function createNewToken()
+    {
+        $key = $this->app['config']['app.key'];
+
+        if (Str::startsWith($key, 'base64:')) {
+            $key = base64_decode(substr($key, 7));
+        }
+
+        return hash_hmac('sha256', Str::random(40), $key);
+    }
+}
diff --git a/tests/Feature/Http/Controllers/Auth/SocialAuthControllerTest.php b/tests/Feature/Http/Controllers/Auth/SocialAuthControllerTest.php
new file mode 100644
index 0000000..eaea694
--- /dev/null
+++ b/tests/Feature/Http/Controllers/Auth/SocialAuthControllerTest.php
@@ -0,0 +1,238 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers\Auth;
+
+use Auth;
+use DB;
+use Settings;
+use Socialite;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Support\Enum\UserStatus;
+use Portal\User;
+use Laravel\Socialite\Contracts\User as SocialUserContract;
+use Mockery as m;
+
+class SocialAuthControllerTest extends FunctionalTestCase
+{
+    public function test_social_login_for_new_user()
+    {
+        $this->setSettings(['reg_enabled' => true]);
+
+        $socialUser = new StubSocialUser;
+
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        $this->visit("auth/foo/callback");
+
+        $this->assertUserCreatedAndLoggedIn($socialUser, 'foo');
+    }
+
+    public function test_social_login_for_new_user_if_registration_is_disabled()
+    {
+        Settings::set('reg_enabled', false);
+
+        $socialUser = new StubSocialUser;
+
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        $this->visit("auth/foo/callback");
+
+        $this->seePageIs('login')
+            ->see('Only users who already created an account can log in.');
+    }
+
+    public function test_social_login_for_banned_user()
+    {
+        $user = factory(User::class)->create(['status' => UserStatus::BANNED]);
+        $socialUser = new StubSocialUser;
+
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        DB::table('social_logins')->insert([
+            'user_id' => $user->id,
+            'provider' => 'foo',
+            'provider_id' => $socialUser->getId(),
+            'avatar' => $socialUser->getAvatar(),
+            'created_at' => \Carbon\Carbon::now()
+        ]);
+
+        $this->visit("auth/foo/callback");
+
+        $this->seePageIs('/login')
+            ->see(trans('app.your_account_is_banned'));
+    }
+
+    public function test_social_login_for_existing_user()
+    {
+        $user = factory(User::class)->create();
+        $socialUser = new StubSocialUser;
+
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        DB::table('social_logins')->insert([
+            'user_id' => $user->id,
+            'provider' => 'foo',
+            'provider_id' => $socialUser->getId(),
+            'avatar' => $socialUser->getAvatar(),
+            'created_at' => \Carbon\Carbon::now()
+        ]);
+
+        $this->visit("auth/foo/callback");
+
+        $this->seePageIs('/');
+        $this->assertEquals($user->id, Auth::id());
+    }
+
+    public function test_twitter_login()
+    {
+        $this->setSettings(['reg_enabled' => true]);
+
+        $socialUser = new StubSocialUserWithoutEmail;
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+        Socialite::shouldReceive('driver')->with('twitter')->andReturn($driver);
+
+        $this->visit("auth/twitter/callback")
+            ->seePageIs('auth/twitter/email')
+            ->seeInSession('social.user', $socialUser);
+
+        $socialUser->email = 'john@doe.com';
+
+        $this->type('john@doe.com', 'email')
+            ->press('Log Me In')
+            ->assertUserCreatedAndLoggedIn($socialUser, 'twitter');
+    }
+
+    public function test_missing_email_for_non_twitter_provider()
+    {
+        $this->setSettings(['reg_enabled' => true]);
+
+        $socialUser = new StubSocialUserWithoutEmail;
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        $this->visit("auth/foo/callback")
+            ->seePageIs('login')
+            ->see("You have to provide your email address.");
+    }
+
+    public function test_social_login_for_user_with_one_word_name()
+    {
+        $this->setSettings(['reg_enabled' => true]);
+
+        $socialUser = new StubSocialUserWithOneWordName;
+
+        $driver = m::mock(\Laravel\Socialite\Contracts\Provider::class);
+        $driver->shouldReceive('user')->andReturn($socialUser);
+
+        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
+
+        $this->visit("auth/foo/callback");
+
+        $this->seeInDatabase('users', [
+            'username'   => null,
+            'email'      => $socialUser->getEmail(),
+            'first_name' => 'John',
+            'last_name'  => '',
+            'status'     => UserStatus::ACTIVE
+        ]);
+
+        $user = User::where('email', $socialUser->getEmail())->first();
+
+        $this->seeInDatabase('social_logins', [
+            'user_id'     => $user->id,
+            'provider'    => 'foo',
+            'provider_id' => $socialUser->getId(),
+            'avatar'      => $socialUser->getAvatar()
+        ]);
+
+        $this->seePageIs('/');
+        $this->assertEquals($user->id, Auth::id());
+    }
+
+    /**
+     * @param $socialUser
+     */
+    private function assertUserCreatedAndLoggedIn($socialUser, $provider)
+    {
+        $this->seeInDatabase('users', [
+            'username'   => null,
+            'email'      => $socialUser->getEmail(),
+            'first_name' => 'John',
+            'last_name'  => 'Doe',
+            'status'     => UserStatus::ACTIVE
+        ]);
+
+        $user = User::where('email', $socialUser->getEmail())->first();
+
+        $this->seeInDatabase('social_logins', [
+            'user_id'     => $user->id,
+            'provider'    => $provider,
+            'provider_id' => $socialUser->getId(),
+            'avatar'      => $socialUser->getAvatar()
+        ]);
+
+        $this->seePageIs('/');
+        $this->assertEquals($user->id, Auth::id());
+    }
+
+}
+
+class StubSocialUser implements SocialUserContract
+{
+    public function getId()
+    {
+        return '123';
+    }
+
+    public function getNickname()
+    {
+        return 'johndoe';
+    }
+
+    public function getName()
+    {
+        return 'John Doe';
+    }
+
+    public function getEmail()
+    {
+        return 'john@doe.com';
+    }
+
+    public function getAvatar()
+    {
+        return 'http://www.gravatar.com/avatar';
+    }
+}
+
+class StubSocialUserWithoutEmail extends StubSocialUser
+{
+    public $email = null;
+
+    public function getEmail()
+    {
+        return $this->email;
+    }
+}
+
+class StubSocialUserWithOneWordName extends StubSocialUser
+{
+    public function getName()
+    {
+        return 'John';
+    }
+}
\ No newline at end of file
diff --git a/tests/Feature/Http/Controllers/PermissionsControllerTest.php b/tests/Feature/Http/Controllers/PermissionsControllerTest.php
new file mode 100644
index 0000000..415bba6
--- /dev/null
+++ b/tests/Feature/Http/Controllers/PermissionsControllerTest.php
@@ -0,0 +1,183 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Tests\Feature\FunctionalTestCase;
+use Portal\Events\Permission\Created;
+use Portal\Events\Permission\Updated;
+use Portal\Events\Role\PermissionsUpdated;
+use Portal\Permission;
+use Portal\Role;
+use Mockery as m;
+
+class PermissionsControllerTest extends FunctionalTestCase
+{
+    protected $user;
+
+    protected $seed = false;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->user = $this->createSuperUser();
+        $this->be($this->user);
+    }
+
+    public function test_permissions_list()
+    {
+        $permission = factory(Permission::class)->create();
+
+        $this->visit('permission')
+            ->seeInTable('table', $permission->display_name, 1, 1);
+
+        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
+        $this->assertEquals(2, $this->crawler->filter('table tbody tr:nth-child(1) > td')->count());
+    }
+
+    public function test_permission_list_with_roles()
+    {
+        $permission = factory(Permission::class)->create();
+        $role = factory(Role::class)->create();
+
+        $role->perms()->attach($permission->id);
+
+        $this->visit('permission')
+            ->seeInTable('table', $permission->display_name, 1, 1)
+            ->seeElement('input', ['type' => 'checkbox', 'name' => "roles[$role->id][]"]);
+
+        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
+        $this->assertEquals(3, $this->crawler->filter('table tbody tr:nth-child(1) > td')->count());
+    }
+
+    public function test_save_role_permissions()
+    {
+        $this->expectsEvents(PermissionsUpdated::class);
+
+        $permission = factory(Permission::class)->create();
+        $role = factory(Role::class)->create();
+
+        $role->perms()->attach($permission->id);
+
+        $this->visit('permission')
+            ->submitForm('Save Permissions', [
+                'roles' => [
+                    $role->id => [$permission->id]
+                ]
+            ]);
+
+        $this->seePageIs('permission')
+            ->see('Permissions saved successfully.')
+            ->seeIsChecked("roles[{$role->id}][]")
+            ->seeInDatabase('permission_role', [
+                'role_id' => $role->id,
+                'permission_id' => $permission->id
+            ]);
+    }
+
+    public function test_save_role_permissions_if_no_permission_is_selected_for_specific_role()
+    {
+        $this->expectsEvents(PermissionsUpdated::class);
+
+        $permission = factory(Permission::class)->create();
+        $permission2 = factory(Permission::class)->create();
+        $role = factory(Role::class)->create();
+        $role2 = factory(Role::class)->create();
+
+        $role->perms()->attach($permission->id);
+        $role2->perms()->attach($permission2->id);
+
+        $this->visit('permission');
+
+        $form = $this->getForm('Save Permissions');
+
+        //Uncheck all checkboxes for Role 2
+        $form['roles'][$role2->id][0]->untick();
+        $form['roles'][$role2->id][1]->untick();
+
+        $this->makeRequestUsingForm($form);
+
+        $this->seePageIs('permission')
+            ->see('Permissions saved successfully.')
+            ->seeInDatabase('permission_role', [
+                'role_id' => $role->id,
+                'permission_id' => $permission->id
+            ])
+            ->dontSeeInDatabase('permission_role', [
+                'role_id' => $role2->id,
+                'permission_id' => $permission2->id
+            ]);
+    }
+
+    public function test_create_permission()
+    {
+        $this->app->instance('middleware.disable', false);
+
+        $this->expectsEvents(Created::class);
+
+        $data = $this->stubPermissionData();
+
+        $this->visit('permission')
+            ->click('Add Permission')
+            ->seePageIs('permission/create')
+            ->submitForm('Create Permission', $data);
+
+        $this->seePageIs('permission')
+            ->see('Permission created successfully.')
+            ->seeInDatabase('permissions', $data);
+    }
+
+    public function test_update_permission()
+    {
+        $this->expectsEvents(Updated::class);
+
+        $permission = factory(Permission::class)->create();
+
+        $data = $this->stubPermissionData();
+
+        $this->visit('permission')
+            ->clickOn('a[title="Edit Permission"]')
+            ->seePageIs("permission/{$permission->id}/edit")
+            ->submitForm('Update Permission', $data);
+
+        $this->seePageIs('permission')
+            ->see('Permission updated successfully.')
+            ->seeInDatabase('permissions', $data + ['id' => $permission->id]);
+    }
+
+    public function test_delete()
+    {
+        $this->expectsEvents(\Portal\Events\Permission\Deleted::class);
+
+        $permission = factory(Permission::class)->create();
+
+        $this->delete(route('permission.destroy', $permission->id))
+            ->followRedirects();
+
+        $this->seePageIs('permission')
+            ->see('Permission deleted successfully.')
+            ->dontSeeInDatabase('permissions', ['id' => $permission->id]);
+
+    }
+
+    public function test_if_non_removable_permissions_can_be_removed()
+    {
+        $permission = factory(Permission::class)->create(['removable' => false]);
+
+        $this->visit('permission');
+        $this->assertEquals(0, $this->crawler->filter("a[title='Delete Permission']")->first()->count());
+
+        $this->delete(route('permission.destroy', $permission->id))
+            ->followRedirects();
+
+        $this->assertResponseStatus(404);
+    }
+
+    private function stubPermissionData()
+    {
+        return [
+            'name' => 'foo_permission',
+            'display_name' => 'Foo Permission',
+            'description' => 'the description'
+        ];
+    }
+}
diff --git a/tests/Feature/Http/Controllers/ProfileControllerTest.php b/tests/Feature/Http/Controllers/ProfileControllerTest.php
new file mode 100644
index 0000000..c02cf7b
--- /dev/null
+++ b/tests/Feature/Http/Controllers/ProfileControllerTest.php
@@ -0,0 +1,326 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Authy;
+use Hash;
+use Input;
+use Settings;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Events\User\ChangedAvatar;
+use Portal\Events\User\UpdatedProfileDetails;
+use Portal\Role;
+use Portal\Support\Enum\UserStatus;
+use Carbon\Carbon;
+
+class ProfileControllerTest extends FunctionalTestCase
+{
+    protected $user;
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->user = $this->createAndLoginUser();
+    }
+
+    public function test_can_access_profile_page()
+    {
+        $this->visit('/')
+            ->click('My Profile')
+            ->seePageIs('profile');
+    }
+
+    public function test_update_details()
+    {
+        $this->expectsEvents(UpdatedProfileDetails::class);
+
+        $data = $this->getStubDetailsData();
+
+        $this->visit('profile')
+            ->submitForm('Update Details', $data)
+            ->seePageIs('profile')
+            ->see('Profile updated successfully.')
+            ->seeInDatabase('users', $data + ['id' => $this->user->id]);
+    }
+
+    public function test_cannot_change_role_or_status()
+    {
+        $data = $this->getStubDetailsData();
+
+        $extendedData = $data + [
+            'role' => Role::whereName('Admin')->first()->id,
+            'status' => UserStatus::BANNED,
+        ];
+
+        $this->visit('profile')
+            ->submitForm('Update Details', $extendedData)
+            ->seePageIs('profile')
+            ->see('Profile updated successfully.')
+            ->seeInDatabase('users', $data + ['id' => $this->user->id, 'status' => UserStatus::ACTIVE])
+            ->dontSeeInDatabase('role_user', [
+                'user_id' => $this->user->id,
+                'role_id' => $extendedData['role']
+            ]);
+    }
+
+    public function test_update_avatar()
+    {
+        $this->expectsEvents(ChangedAvatar::class);
+
+        $uploads = ['avatar' => base_path('tests/files/image.png')];
+
+        $input = [
+            'points' => [
+                'x1' => 0,
+                'y1' => 0,
+                'x2' => 200,
+                'y2' => 200
+            ]
+        ] + $uploads;
+
+        $this->visit("profile")
+            ->submitForm('Save', $input, $uploads)
+            ->seePageIs('profile')
+            ->see('Avatar changed successfully.');
+
+        $user = $this->user->fresh();
+
+        $uploadedFile = public_path("upload/users/{$user->avatar}");
+
+        $this->assertNotNull($user->avatar);
+        $this->assertFileExists($uploadedFile);
+
+        list($width, $height) = getimagesize($uploadedFile);
+
+        $this->assertEquals(160, $width);
+        $this->assertEquals(160, $height);
+
+        @unlink($uploadedFile);
+    }
+
+    public function test_update_avatar_with_invalid_image_file()
+    {
+        $file = storage_path("app/portal-test.php");
+
+        file_put_contents($file, "<?php ");
+
+        $uploads = ['avatar' => $file];
+
+        $input = [
+            'points' => [
+                'x1' => 0,
+                'y1' => 0,
+                'x2' => 200,
+                'y2' => 200
+            ]
+        ] + $uploads;
+
+        $this->visit("profile")
+            ->submitForm('Save', $input, $uploads)
+            ->seePageIs('profile')
+            ->see("The avatar must be an image.");
+
+        $user = $this->user->fresh();
+
+        $this->assertNull($user->avatar);
+
+        @unlink($file);
+    }
+
+    public function test_update_avatar_external()
+    {
+        $this->expectsEvents(ChangedAvatar::class);
+
+        $data = ['url' => '//www.gravatar.com/avatar'];
+        $this->post(route('profile.update.avatar-external', $this->user->id), $data)
+            ->followRedirects()
+            ->seePageIs('profile')
+            ->see('Avatar changed successfully.');
+
+        $this->seeInDatabase('users', ['id' => $this->user->id, 'avatar' => $data['url']]);
+    }
+
+    public function test_update_social_networks()
+    {
+        $data = [
+            'facebook' => 'facebook',
+            'twitter' => 'twitter',
+            'google_plus' => 'g+',
+            'linked_in' => 'li',
+            'dribbble' => 'Dribble',
+            'skype' => 'skyyype'
+        ];
+
+        $this->visit("profile")
+            ->submitForm('Update Social Networks', ['socials' => $data])
+            ->seeInDatabase('user_social_networks', $data)
+            ->seePageIs("profile")
+            ->see("Social networks updated successfully.");
+    }
+
+    public function test_update_user_login_details()
+    {
+        $data = [
+            'email' => 'john@doe.com',
+            'username' => 'milos',
+            'password' => 'milos123123',
+            'password_confirmation' => 'milos123123'
+        ];
+
+        $this->visit("profile")
+            ->submitForm("update-login-details-btn", $data)
+            ->seePageIs("profile")
+            ->see('Login details updated successfully.');
+
+        $user = $this->user->fresh();
+
+        $this->assertEquals($data['email'], $user->email);
+        $this->assertEquals($data['username'], $user->username);
+        $this->assertTrue(Hash::check($data['password'], $user->password));
+    }
+
+    public function test_password_is_not_changed_if_omitted_on_update()
+    {
+        $this->user = $this->createAndLoginUser([
+            'email' => 'john@doe.com',
+            'password' => '123123'
+        ]);
+
+        $data = ['email' => 'test@test.com', 'password' => '', 'password_confirmation' => ''];
+
+        $this->visit("profile")
+            ->submitForm("update-login-details-btn", $data)
+            ->seePageIs("profile")
+            ->see('Login details updated successfully.');
+
+        $user = $this->user->fresh();
+
+        $this->assertEquals($data['email'], $user->email);
+        $this->assertTrue(Hash::check('123123', $user->password));
+    }
+
+    public function test_2fa_form_visibility()
+    {
+        Settings::set('2fa.enabled', false);
+
+        $this->visit("profile")
+            ->dontSee('Two-Factor Authentication');
+
+        Settings::set('2fa.enabled', true);
+
+        $this->visit("profile")
+            ->see('Two-Factor Authentication');
+    }
+
+    public function test_enable_2fa()
+    {
+        $this->expectsEvents(\Portal\Events\User\TwoFactorEnabled::class);
+
+        Settings::set('2fa.enabled', true);
+
+        Authy::shouldReceive('isEnabled')->andReturn(false);
+        Authy::shouldReceive('register')->andReturnNull();
+
+        $data = ['country_code' => '1', 'phone_number' => '123'];
+
+        $this->visit("profile")
+            ->submitForm('Enable', $data)
+            ->seePageIs("profile")
+            ->seeInDatabase('users', [
+                'id' => $this->user->id,
+                'two_factor_country_code' => $data['country_code'],
+                'two_factor_phone' => $data['phone_number']
+            ])
+            ->see('Two-Factor Authentication enabled successfully.');
+    }
+
+    public function test_disable_2fa()
+    {
+        $this->expectsEvents(\Portal\Events\User\TwoFactorDisabled::class);
+
+        Settings::set('2fa.enabled', true);
+
+        Authy::shouldReceive('isEnabled')->andReturn(true);
+        Authy::shouldReceive('delete')->andReturnNull();
+
+        $this->visit("profile")
+            ->press('Disable')
+            ->seePageIs("profile")
+            ->seeInDatabase('users', [
+                'id' => $this->user->id,
+                'two_factor_country_code' => null,
+                'two_factor_phone' => null
+            ])
+            ->see('Two-Factor Authentication disabled successfully.');
+    }
+
+    public function test_activity_log()
+    {
+        $logger = app(\Portal\Services\Logging\UserActivity\Logger::class);
+
+        Carbon::setTestNow(Carbon::now());
+
+        $logger->log('foo');
+        $logger->log('bar');
+
+        $buttonSelector = "a[data-content='".Input::header('User-agent')."']";
+
+        $this->visit('profile/activity')
+            ->seeInTable('table', Input::ip(), 1, 1)
+            ->seeInTable('table', 'foo', 1, 2)
+            ->seeInTable('table', Carbon::now()->toDateTimeString(), 1, 3)
+            ->seeElement("table tbody tr:nth-child(1) > td:nth-child(4) > {$buttonSelector}")
+            ->seeInTable('table', Input::ip(), 2, 1)
+            ->seeInTable('table', 'bar', 2, 2)
+            ->seeInTable('table', Carbon::now()->toDateTimeString(), 2, 3)
+            ->seeElement("table tbody tr:nth-child(2) > td:nth-child(4) > {$buttonSelector}");
+    }
+
+    public function test_session_invalidation()
+    {
+        putenv('SESSION_DRIVER=database');
+
+        $this->refreshApplication();
+
+        if ($this->isSQLiteConnection()) {
+            $this->executeCallbacks();
+        }
+
+        Carbon::setTestNow(Carbon::now());
+
+        $user = $this->createAndLoginAdminUser();
+
+        $this->visit('user')
+            ->click('Active Sessions')
+            ->seePageIs("profile/sessions")
+            ->seeInTable('table', Input::ip(), 1, 1)
+            ->seeInTable('table', Input::header("User-agent"), 1, 2)
+            ->seeInTable('table', Carbon::now()->toDateString(), 1, 3);
+
+        $this->assertEquals(1, $this->crawler->filter("table tbody tr")->count());
+
+        $url = $this->crawler->filter('a[title="Invalidate Session"]')->first()->link()->getUri();
+
+        $this->delete($url)
+            ->followRedirects()
+            ->dontSeeInDatabase('sessions', ['user_id' => $user->id]);
+    }
+
+    /**
+     * @return array
+     */
+    private function getStubDetailsData()
+    {
+        $data = [
+            'first_name' => 'foo',
+            'last_name'  => 'bar',
+            'birthday'   => Carbon::now()->subYears(25)->format('Y-m-d'),
+            'phone'      => '12345667',
+            'address'    => 'the address',
+            'country_id' => 688 //Serbia,
+        ];
+
+        return $data;
+    }
+}
diff --git a/tests/Feature/Http/Controllers/RolesControllerTest.php b/tests/Feature/Http/Controllers/RolesControllerTest.php
new file mode 100644
index 0000000..fec51ef
--- /dev/null
+++ b/tests/Feature/Http/Controllers/RolesControllerTest.php
@@ -0,0 +1,134 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Tests\Feature\FunctionalTestCase;
+use Portal\Role;
+use Mockery as m;
+use Portal\User;
+
+class RolesControllerTest extends FunctionalTestCase
+{
+    protected $user;
+
+    protected $seed = false;
+
+    /**
+     * @before
+     */
+    public function setUp()
+    {
+        parent::setUp();
+        $this->user = $this->createSuperUser();
+        $this->be($this->user);
+    }
+
+    public function test_roles_list_is_displayed_properly()
+    {
+        $role1 = factory(Role::class)->create(['removable' => true]);
+        $role2 = factory(Role::class)->create(['removable' => false]);
+
+        $this->user->roles()->attach($role2->id);
+
+        $this->visit('role')
+            ->seeInTable('table', $role1->name, 1, 1)
+            ->seeInTable('table', $role1->display_name, 1, 2)
+            ->seeInTable('table', "0", 1, 3)
+            ->seeElement('table tbody tr:nth-child(1) > td a[title="Delete Role"]')
+            ->seeInTable('table', $role2->name, 2, 1)
+            ->seeInTable('table', $role2->display_name, 2, 2)
+            ->seeInTable('table', "1", 2, 3)
+            ->dontSeeElement('table tbody tr:nth-child(2) > td a[title="Delete Role"]');
+    }
+
+    public function test_create_role()
+    {
+        $data = $this->roleStubData();
+
+        $this->visit('role')
+            ->click('Add Role')
+            ->seePageIs('role/create')
+            ->submitForm('Create Role', $data);
+
+        $this->seePageIs('role')
+            ->see('Role created successfully.')
+            ->seeInDatabase('roles', $data);
+    }
+
+    public function test_edit_role()
+    {
+        $role = factory(Role::class)->create();
+
+        $this->visit('role')
+            ->clickOn('a[title="Edit Role"]')
+            ->seePageIs("role/{$role->id}/edit")
+            ->seeInField('name', $role->name)
+            ->seeInField('display_name', $role->display_name)
+            ->seeInField('description', $role->description);
+
+        $data = $this->roleStubData();
+
+        $this->submitForm('Update Role', $data)
+            ->seePageIs("role")
+            ->see('Role updated successfully.')
+            ->seeInDatabase('roles', $data + ['id' => $role->id]);
+    }
+
+    public function test_delete_role()
+    {
+        $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
+
+        $role = factory(Role::class)->create(['removable' => true]);
+
+        $this->delete(route('role.delete', $role->id))
+            ->dontSeeInDatabase('roles', ['id' => $role->id]);
+    }
+
+    public function test_users_receive_default_role_after_their_role_is_deleted()
+    {
+        $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
+
+        $user = factory(User::class)->create();
+        $role = factory(Role::class)->create(['removable' => true]);
+        $userRole = Role::where('name', 'User')->first();
+
+        $this->setRoleForUser($user, $role->name);
+
+        $this->assertTrue($user->hasRole($role->name));
+
+        $this->delete(route('role.delete', $role->id))
+            ->seeInDatabase('role_user', [
+                'role_id' => $userRole->id,
+                'user_id' => $user->id
+            ]);
+
+        $user = $user->fresh();
+
+        $this->assertFalse($user->hasRole($role->name));
+        $this->assertTrue($user->hasRole($userRole->name));
+    }
+
+    public function test_delete_unremovable_role()
+    {
+        $role = factory(Role::class)->create(['removable' => false]);
+
+        // This call should throw an exception
+        // because this role cannot be deleted
+        $this->delete(route('role.delete', $role->id));
+
+        $this->assertResponseStatus(404);
+        $this->see('Oops, 404!');
+    }
+
+    /**
+     * @return array
+     */
+    private function roleStubData()
+    {
+        return [
+            'name' => 'foo',
+            'display_name' => 'Foooooo',
+            'description' => 'the description'
+        ];
+    }
+}
diff --git a/tests/Feature/Http/Controllers/SettingsControllerTest.php b/tests/Feature/Http/Controllers/SettingsControllerTest.php
new file mode 100644
index 0000000..ea9b424
--- /dev/null
+++ b/tests/Feature/Http/Controllers/SettingsControllerTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Settings;
+use Tests\Feature\FunctionalTestCase;
+
+class SettingsControllerTest extends FunctionalTestCase
+{
+    public function test_update_app_name()
+    {
+        $user = $this->createSuperUser();
+        $this->be($user);
+
+        $oldName = Settings::get('app_name', 'Portal');
+
+        Settings::set('app_name', 'bar');
+
+        $name = 'foo';
+
+        $this->visit('settings')
+            ->seeInField('app_name', 'bar')
+            ->type('foo', 'app_name')
+            ->press('Update Settings');
+
+        $this->assertEquals($name, Settings::get('app_name'));
+
+        $this->visit('logout')
+            ->seeInElement("#footer p", $name);
+
+        Settings::set('app_name', $oldName);
+        Settings::save();
+    }
+}
diff --git a/tests/Feature/Http/Controllers/UsersControllerTest.php b/tests/Feature/Http/Controllers/UsersControllerTest.php
new file mode 100644
index 0000000..d6e5eac
--- /dev/null
+++ b/tests/Feature/Http/Controllers/UsersControllerTest.php
@@ -0,0 +1,486 @@
+<?php
+
+namespace Tests\Feature\Http\Controllers;
+
+use Authy;
+use Hash;
+use Input;
+use Settings;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Events\User\TwoFactorEnabledByAdmin;
+use Portal\Events\User\UpdatedByAdmin;
+use Portal\Role;
+use Portal\Support\Enum\UserStatus;
+use Portal\User;
+use Carbon\Carbon;
+use Mockery as m;
+
+class UsersControllerTest extends FunctionalTestCase
+{
+
+    public function test_users_table_is_displayed()
+    {
+        $this->be($this->makeSuperUser());
+
+        $active = factory(User::class)->times(4)->create();
+        $banned = factory(User::class)->times(2)->create(['status' => UserStatus::BANNED]);
+        $unconfirmed = factory(User::class)->times(2)->create(['status' => UserStatus::UNCONFIRMED]);
+
+        $users = $active->merge($banned);
+        $users = $users->merge($unconfirmed);
+
+        $users = $users->reverse();
+
+        $this->visit('user')
+            ->seeInElement("h1.page-header", "Users")
+            ->seeInElement('h1.page-header small', 'list of registered users')
+            ->seeElement("#add-user");
+
+        foreach ($users as $i => $user) {
+            $this->seeInTable("#users-table-wrapper table", $user->present()->username, $i + 1, 1);
+            $this->seeInTable("#users-table-wrapper table", $user->present()->name, $i + 1, 2);
+            $this->seeInTable("#users-table-wrapper table", $user->email, $i + 1, 3);
+            $this->seeInTable("#users-table-wrapper table", $user->created_at->format('Y-m-d'), $i + 1, 4);
+            $this->seeInTable("#users-table-wrapper table", $user->status, $i + 1, 5);
+        }
+    }
+
+    public function test_users_pagination()
+    {
+        $this->be($this->makeSuperUser());
+
+        factory(User::class)->times(21)->create();
+
+        $this->visit('user');
+
+        $pagination = $this->crawler->filter(".pagination");
+        $paginationLinks = $this->crawler->filter('.pagination a');
+
+        $this->assertEquals(1, $pagination->count());
+        $this->assertEquals(2, $paginationLinks->count());
+    }
+
+    public function test_users_search()
+    {
+        $user1 = factory(User::class)->create(['first_name' => 'Milos', 'last_name' => 'Stojanovic']);
+        $user2 = factory(User::class)->create(['first_name' => 'John', 'last_name' => 'Doe']);
+        $user3 = factory(User::class)->create(['first_name' => 'Jane', 'last_name' => 'Doe']);
+
+        $this->be($this->makeSuperUser($user1));
+
+        $this->visit('user')
+            ->submitForm('search-users-btn', ['search' => 'doe'])
+            ->seePageIs('user?search=doe&status=')
+            ->seeInField('search', 'doe')
+            ->seeInTable('table', $user2->present()->name, 1, 2)
+            ->seeInTable('table', $user3->present()->name, 2, 2);
+    }
+
+    public function test_users_filter_by_status()
+    {
+        $this->be($this->makeSuperUser());
+
+        factory(User::class)->times(2)->create();
+        factory(User::class)->times(3)->create();
+
+        $this->visit('user?status=' . UserStatus::BANNED)
+            ->seeIsSelected('status', UserStatus::BANNED);
+
+        $this->assertEquals(1, $this->crawler->filter('#users-table-wrapper table tbody tr')->count());
+    }
+
+    public function test_add_user()
+    {
+        $this->beSuperUser();
+
+        $this->visit('user')
+            ->click('Add User')
+            ->seePageIs('user/create');
+
+        $data = $this->stubUserData();
+
+        $this->submitForm('Create User', $data);
+
+        $user = User::where('email', $data['email'])->first();
+
+        $expected = array_except($data, ['role', 'password', 'password_confirmation']);
+
+        $this->seeInDatabase('users', $expected)
+            ->seePageIs('user')
+            ->see('User created successfully.')
+            ->assertTrue(Hash::check('123123', $user->password));
+    }
+
+    public function test_add_user_without_country()
+    {
+        $this->beSuperUser();
+
+        $this->visit('user')
+            ->click('Add User')
+            ->seePageIs('user/create');
+
+        $data = $this->stubUserData();
+        $data['country_id'] = 0;
+
+        $this->submitForm('Create User', $data);
+
+        $user = User::where('email', $data['email'])->first();
+
+        $expected = array_except($data, ['role', 'password', 'password_confirmation']);
+        $expected['country_id'] = null;
+
+        $this->seeInDatabase('users', $expected)
+            ->seePageIs('user')
+            ->see('User created successfully.')
+            ->assertTrue(Hash::check('123123', $user->password));
+    }
+
+    public function test_add_user_validation()
+    {
+        $this->beSuperUser();
+
+        $this->visit('user/create')
+            ->press('Create User')
+            ->seePageIs('user/create')
+            ->see('The email field is required.')
+            ->see('The password field is required.');
+
+        $this->visit('user/create')
+            ->type('asdfa', 'email')
+            ->type('123', 'password')
+            ->type('122', 'password_confirmation')
+            ->press('Create User')
+            ->seePageIs('user/create')
+            ->see('The email must be a valid email address.')
+            ->see('The password must be at least 6 characters.')
+            ->see('The password confirmation does not match.');
+    }
+
+    public function test_view_user_page()
+    {
+        $user = $this->createAndLoginAdminUser();
+
+        $this->visit('user')
+            ->clickOn('a[title="View User"]')
+            ->seePageIs("user/{$user->id}/show")
+            ->seeLink('Edit', route('user.edit', $user->id));
+    }
+
+    public function test_update_user_details()
+    {
+        $this->expectsEvents(UpdatedByAdmin::class);
+
+        $this->createAndLoginAdminUser();
+
+        $user = $this->createUserWithSocialNetworks();
+        $user = $this->setRoleForUser($user, 'User');
+
+        $this->visit('user')
+            ->seeLink('', "user/{$user->id}/edit");
+
+        $this->visit("user/{$user->id}/edit");
+
+        $data = [
+            'role' => Role::whereName('User')->first()->id,
+            'status' => UserStatus::BANNED,
+            'first_name' => 'foo',
+            'last_name' => 'bar',
+            'birthday' => Carbon::now()->subYears(25)->format('Y-m-d'),
+            'phone' => '12345667',
+            'address' => 'the address',
+            'country_id' => 688 //Serbia,
+        ];
+
+        $this->submitForm('update-details-btn', $data);
+
+        $expected = array_except($data, 'role') + ['id' => $user->id];
+
+        $this->seeInDatabase('users', $expected)
+            ->seeInDatabase('role_user', ['user_id' => $user->id, 'role_id' => $data['role']])
+            ->seePageIs("user/{$user->id}/edit")
+            ->see('User updated successfully.');
+    }
+
+    public function test_update_user_social_networks()
+    {
+        $user = $this->createAndLoginAdminUser();
+
+        $data = [
+            'facebook' => 'facebook',
+            'twitter' => 'twitter',
+            'google_plus' => 'g+',
+            'linked_in' => 'li',
+            'dribbble' => 'Dribble',
+            'skype' => 'skyyype'
+        ];
+
+        $this->visit("user/{$user->id}/edit")
+            ->submitForm('Update Social Networks', ['socials' => $data])
+            ->seeInDatabase('user_social_networks', $data)
+            ->seePageIs("user/{$user->id}/edit")
+            ->see("Social networks updated successfully.");
+    }
+
+    public function test_update_user_login_details()
+    {
+        $user = $this->createAndLoginAdminUser([
+            'email' => 'test@test.com',
+            'username' => 'test',
+            'password' => 'milos123'
+        ]);
+
+        $data = [
+            'email' => 'john@doe.com',
+            'username' => 'milos',
+            'password' => '123123',
+            'password_confirmation' => '123123'
+        ];
+
+        $this->visit("user/{$user->id}/edit")
+            ->submitForm("update-login-details-btn", $data)
+            ->seePageIs("user/{$user->id}/edit")
+            ->see('Login details updated successfully.');
+
+        $user = $user->fresh();
+
+        $this->assertEquals($data['email'], $user->email);
+        $this->assertEquals($data['username'], $user->username);
+        $this->assertTrue(Hash::check($data['password'], $user->password));
+    }
+
+    public function test_2fa_form_visibility()
+    {
+        Settings::set('2fa.enabled', false);
+        $user = $this->createAndLoginAdminUser();
+
+        $this->visit("user/{$user->id}/edit")
+            ->dontSee('Two-Factor Authentication');
+
+        Settings::set('2fa.enabled', true);
+
+        $this->visit("user/{$user->id}/edit")
+            ->see('Two-Factor Authentication');
+    }
+
+    public function test_enable_2fa_for_user()
+    {
+        $this->expectsEvents(TwoFactorEnabledByAdmin::class);
+
+        Settings::set('2fa.enabled', true);
+        $user = $this->createAndLoginAdminUser();
+
+        Authy::shouldReceive('isEnabled')->andReturn(false);
+        Authy::shouldReceive('register')->andReturnNull();
+
+        $data = ['country_code' => '1', 'phone_number' => '123'];
+
+        $this->visit("user/{$user->id}/edit")
+            ->submitForm('Enable', $data)
+            ->seePageIs("user/{$user->id}/edit")
+            ->seeInDatabase('users', [
+                'id' => $user->id,
+                'two_factor_country_code' => $data['country_code'],
+                'two_factor_phone' => $data['phone_number']
+            ])
+            ->see('Two-Factor Authentication enabled successfully.');
+    }
+
+    public function test_disable_2fa_for_user()
+    {
+        $this->expectsEvents(\Portal\Events\User\TwoFactorDisabledByAdmin::class);
+
+        Settings::set('2fa.enabled', true);
+        $user = $this->createAndLoginAdminUser();
+
+        Authy::shouldReceive('isEnabled')->andReturn(true);
+        Authy::shouldReceive('delete')->andReturnNull();
+
+        $this->visit("user/{$user->id}/edit")
+            ->press('Disable')
+            ->seePageIs("user/{$user->id}/edit")
+            ->seeInDatabase('users', [
+                'id' => $user->id,
+                'two_factor_country_code' => null,
+                'two_factor_phone' => null
+            ])
+            ->see('Two-Factor Authentication disabled successfully.');
+    }
+
+    public function test_avatar_update()
+    {
+        $user = $this->createAndLoginAdminUser();
+
+        $uploads = ['avatar' => base_path('tests/files/image.png')];
+
+        $input = [
+            'points' => [
+                'x1' => 0,
+                'y1' => 0,
+                'x2' => 200,
+                'y2' => 200
+            ]
+        ] + $uploads;
+
+        $this->visit("user/{$user->id}/edit")
+            ->submitForm('Save', $input, $uploads);
+
+        $this->seePageIs("user/{$user->id}/edit")
+            ->see('Avatar changed successfully.');
+
+        $user = $user->fresh();
+
+        $uploadedFile = public_path("upload/users/{$user->avatar}");
+
+        $this->assertNotNull($user->avatar);
+        $this->assertFileExists($uploadedFile);
+
+        list($width, $height) = getimagesize($uploadedFile);
+
+        $this->assertEquals(160, $width);
+        $this->assertEquals(160, $height);
+
+        @unlink($uploadedFile);
+    }
+
+    public function test_avatar_update_with_invalid_file()
+    {
+        $user = $this->createAndLoginAdminUser();
+
+        $file = storage_path("app/portal-test.php");
+
+        file_put_contents($file, "<?php ");
+
+        $uploads = ['avatar' => $file];
+
+        $input = [
+            'points' => [
+                'x1' => 0,
+                'y1' => 0,
+                'x2' => 200,
+                'y2' => 200
+            ]
+        ] + $uploads;
+
+        $this->visit("user/{$user->id}/edit")
+            ->submitForm('Save', $input, $uploads);
+
+        $this->seePageIs("user/{$user->id}/edit")
+            ->see("The avatar must be an image.");
+
+        $user = $user->fresh();
+
+        $this->assertNull($user->avatar);
+
+        @unlink($file);
+    }
+
+    /**
+     * @expectedException \Laravel\BrowserKitTesting\HttpException
+     */
+    public function test_session_page_is_not_available_for_non_database_driver()
+    {
+        putenv('SESSION_DRIVER=array');
+
+        $this->refreshApp();
+
+        $user = $this->createAndLoginAdminUser();
+
+        $this->visit('user')
+            ->dontSeeElement('a[title="User Sessions"]');
+
+        // this page should not be accessible if
+        // database session driver is not being used
+        $this->visit("user/{$user->id}/sessions");
+    }
+
+    public function test_invalidate_session()
+    {
+        putenv('SESSION_DRIVER=database');
+
+        $this->refreshApp();
+
+        Carbon::setTestNow(Carbon::now());
+
+        $user = $this->createAndLoginAdminUser();
+
+        $this->visit('user')
+            ->clickOn('a[title="User Sessions"]')
+            ->seePageIs("user/{$user->id}/sessions")
+            ->seeInTable('table', Input::ip(), 1, 1)
+            ->seeInTable('table', Input::header("User-agent"), 1, 2)
+            ->seeInTable('table', Carbon::now()->toDateString(), 1, 3);
+
+        $this->assertEquals(1, $this->crawler->filter("table tbody tr")->count());
+
+        $url = $this->crawler->filter('a[title="Invalidate Session"]')->first()->link()->getUri();
+
+        $this->delete($url)
+            ->followRedirects()
+            ->dontSeeInDatabase('sessions', ['user_id' => $user->id])
+            ->seePageIs("user/{$user->id}/sessions")
+            ->see('Session invalidated successfully.');
+    }
+
+    public function test_delete_user()
+    {
+        $this->createAndLoginAdminUser();
+
+        $user = $this->createUserWithSocialNetworks();
+        $user = $this->setRoleForUser($user, 'User');
+
+        $this->delete(route('user.delete', $user->id))
+            ->followRedirects()
+            ->seePageIs('user')
+            ->see("User deleted successfully.");
+    }
+
+    public function test_if_user_can_delete_himself()
+    {
+        $admin = $this->createAndLoginAdminUser();
+
+        $this->delete(route('user.delete', $admin->id))
+            ->followRedirects()
+            ->seePageIs('user')
+            ->see("You cannot delete yourself.");
+    }
+
+    /**
+     * @param array $override
+     * @return array
+     */
+    private function stubUserData(array $override = [])
+    {
+        return array_merge([
+            'role' => Role::where('name', 'User')->first()->id,
+            'status' => UserStatus::ACTIVE,
+            'first_name' => 'John',
+            'last_name' => 'Doe',
+            'birthday' => Carbon::now()->subYears(20)->format('Y-m-d'),
+            'phone' => '123456',
+            'address' => 'some address',
+            'country_id' => 688,
+            'email' => 'john@doe.com',
+            'username' => 'johndoe',
+            'password' => '123123',
+            'password_confirmation' => '123123'
+        ], $override);
+    }
+
+    private function beSuperUser()
+    {
+        $user = $this->createSuperUser();
+
+        $this->be($user);
+
+        return $user;
+    }
+
+    private function refreshApp()
+    {
+        $this->refreshApplication();
+
+        if ($this->isSQLiteConnection()) {
+            $this->executeCallbacks();
+        }
+    }
+}
diff --git a/tests/Feature/Listeners/BaseListenerTestCase.php b/tests/Feature/Listeners/BaseListenerTestCase.php
new file mode 100644
index 0000000..9f4a5cb
--- /dev/null
+++ b/tests/Feature/Listeners/BaseListenerTestCase.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Tests\Feature\Listeners;
+
+use Input;
+use Tests\Feature\FunctionalTestCase;
+use Portal\User;
+
+class BaseListenerTestCase extends FunctionalTestCase
+{
+    protected $user;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->user = factory(User::class)->create();
+        $this->be($this->user);
+    }
+
+    protected function assertMessageLogged($msg)
+    {
+        $this->seeInDatabase('user_activity', [
+            'user_id' => $this->user->id,
+            'ip_address' => Input::ip(),
+            'user_agent' => Input::header('User-agent'),
+            'description' => $msg
+        ]);
+    }
+}
\ No newline at end of file
diff --git a/tests/Feature/Listeners/PermissionEventsSubscriberTest.php b/tests/Feature/Listeners/PermissionEventsSubscriberTest.php
new file mode 100644
index 0000000..019289e
--- /dev/null
+++ b/tests/Feature/Listeners/PermissionEventsSubscriberTest.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Tests\Feature\Listeners;
+
+use Mockery as m;
+use Portal\Events\Permission\Created;
+use Portal\Events\Permission\Deleted;
+use Portal\Events\Permission\Updated;
+
+class PermissionEventsSubscriberTest extends BaseListenerTestCase
+{
+    protected $perm;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->perm = factory(\Portal\Permission::class)->create();
+    }
+
+    public function test_onCreate()
+    {
+        event(new Created($this->perm));
+        $this->assertMessageLogged("Created new permission called {$this->perm->display_name}.");
+    }
+
+    public function test_onUpdate()
+    {
+        event(new Updated($this->perm));
+        $this->assertMessageLogged("Updated the permission named {$this->perm->display_name}.");
+    }
+
+    public function test_onDelete()
+    {
+        event(new Deleted($this->perm));
+        $this->assertMessageLogged("Deleted permission named {$this->perm->display_name}.");
+    }
+
+}
diff --git a/tests/Feature/Listeners/RoleEventsSubscriberTest.php b/tests/Feature/Listeners/RoleEventsSubscriberTest.php
new file mode 100644
index 0000000..ff9a2d8
--- /dev/null
+++ b/tests/Feature/Listeners/RoleEventsSubscriberTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Tests\Feature\Listeners;
+
+use Portal\Events\Role\Created;
+use Portal\Events\Role\Deleted;
+use Portal\Events\Role\PermissionsUpdated;
+use Portal\Events\Role\Updated;
+
+class RoleEventsSubscriberTest extends BaseListenerTestCase
+{
+    protected $role;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->role = factory(\Portal\Role::class)->create();
+    }
+
+    public function test_onCreate()
+    {
+        event(new Created($this->role));
+        $this->assertMessageLogged("Created new role called {$this->role->display_name}.");
+    }
+
+    public function test_onUpdate()
+    {
+        event(new Updated($this->role));
+        $this->assertMessageLogged("Updated role with name {$this->role->display_name}.");
+    }
+
+    public function test_onDelete()
+    {
+        event(new Deleted($this->role));
+        $this->assertMessageLogged("Deleted role named {$this->role->display_name}.");
+    }
+
+    public function test_onPermissionsUpdate()
+    {
+        event(new PermissionsUpdated($this->role));
+        $this->assertMessageLogged("Updated role permissions.");
+    }
+
+}
diff --git a/tests/Feature/Listeners/UserEventsSubscriberTest.php b/tests/Feature/Listeners/UserEventsSubscriberTest.php
new file mode 100644
index 0000000..a968284
--- /dev/null
+++ b/tests/Feature/Listeners/UserEventsSubscriberTest.php
@@ -0,0 +1,148 @@
+<?php
+
+namespace Tests\Feature\Listeners;
+
+use Mockery as m;
+
+class UserEventsSubscriberTest extends BaseListenerTestCase
+{
+    protected $theUser;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->theUser = factory(\Portal\User::class)->create();
+    }
+
+    public function test_onLogin()
+    {
+        event(new \Portal\Events\User\LoggedIn);
+        $this->assertMessageLogged('Logged in.');
+    }
+
+    public function test_onLogout()
+    {
+        event(new \Portal\Events\User\LoggedOut());
+        $this->assertMessageLogged('Logged out.');
+    }
+
+    public function test_onRegister()
+    {
+        event(new \Portal\Events\User\Registered($this->user));
+        $this->assertMessageLogged('Created an account.');
+    }
+
+    public function test_onAvatarChange()
+    {
+        event(new \Portal\Events\User\ChangedAvatar);
+        $this->assertMessageLogged('Updated profile avatar.');
+    }
+
+    public function test_onProfileDetailsUpdate()
+    {
+        event(new \Portal\Events\User\UpdatedProfileDetails);
+        $this->assertMessageLogged('Updated profile details.');
+    }
+
+    public function test_onDelete()
+    {
+        event(new \Portal\Events\User\Deleted($this->theUser));
+
+        $message = sprintf(
+            "Deleted user %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onBan()
+    {
+        event(new \Portal\Events\User\Banned($this->theUser));
+
+        $message = sprintf(
+            "Banned user %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onUpdateByAdmin()
+    {
+        event(new \Portal\Events\User\UpdatedByAdmin($this->theUser));
+
+        $message = sprintf(
+            "Updated profile details for %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onCreate()
+    {
+        event(new \Portal\Events\User\Created($this->theUser));
+
+        $message = sprintf(
+            "Created an account for user %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onSettingsUpdate()
+    {
+        event(new \Portal\Events\Settings\Updated);
+        $this->assertMessageLogged('Updated website settings.');
+    }
+
+    public function test_onTwoFactorEnable()
+    {
+        event(new \Portal\Events\User\TwoFactorEnabled);
+        $this->assertMessageLogged('Enabled Two-Factor Authentication.');
+    }
+
+    public function test_onTwoFactorDisable()
+    {
+        event(new \Portal\Events\User\TwoFactorDisabled);
+        $this->assertMessageLogged('Disabled Two-Factor Authentication.');
+    }
+
+    public function test_onTwoFactorEnabledByAdmin()
+    {
+        event(new \Portal\Events\User\TwoFactorEnabledByAdmin($this->theUser));
+
+        $message = sprintf(
+            "Enabled Two-Factor Authentication for user %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onTwoFactorDisabledByAdmin()
+    {
+        event(new \Portal\Events\User\TwoFactorDisabledByAdmin($this->theUser));
+
+        $message = sprintf(
+            "Disabled Two-Factor Authentication for user %s.",
+            $this->theUser->present()->nameOrEmail
+        );
+
+        $this->assertMessageLogged($message);
+    }
+
+    public function test_onPasswordResetEmailRequest()
+    {
+        event(new \Portal\Events\User\RequestedPasswordResetEmail($this->user));
+        $this->assertMessageLogged("Requested password reset email.");
+    }
+
+    public function test_onPasswordReset()
+    {
+        event(new \Portal\Events\User\ResetedPasswordViaEmail($this->user));
+        $this->assertMessageLogged("Reseted password using \"Forgot Password\" option.");
+    }
+}
diff --git a/tests/Feature/Repositories/Activity/EloquentActivityTest.php b/tests/Feature/Repositories/Activity/EloquentActivityTest.php
new file mode 100644
index 0000000..748a42e
--- /dev/null
+++ b/tests/Feature/Repositories/Activity/EloquentActivityTest.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace Tests\Feature\Repositories\Activity;
+
+use Tests\Feature\FunctionalTestCase;
+use Portal\Repositories\Activity\EloquentActivity;
+use Portal\Services\Logging\UserActivity\Activity;
+use Portal\User;
+use Carbon\Carbon;
+use Mockery as m;
+
+class EloquentActivityTest extends FunctionalTestCase
+{
+    /**
+     * @var EloquentActivity
+     */
+    protected $repo;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(EloquentActivity::class);
+    }
+
+    public function test_log()
+    {
+        $user = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now());
+
+        $data = [
+            'user_id' => $user->id,
+            'ip_address' => '123.456.789.012',
+            'user_agent' => 'foo',
+            'description' => 'descriptionnnn'
+        ];
+
+        $this->repo->log($data);
+
+        $this->seeInDatabase('user_activity', $data);
+    }
+
+    public function test_paginateActivitiesForUser()
+    {
+        $user = factory(User::class)->create();
+
+        $activities = factory(Activity::class)->times(10)->make();
+        $user->activities()->saveMany($activities);
+
+        $result = $this->repo->paginateActivitiesForUser($user->id, 6)->toArray();
+
+        $this->assertEquals(6, count($result['data']));
+        $this->assertEquals(10, $result['total']);
+        $this->assertArraySubset($activities[0]->toArray(), $result['data'][0]);
+        $this->assertArraySubset($activities[5]->toArray(), $result['data'][5]);
+    }
+
+    public function test_getLatestActivitiesForUser()
+    {
+        $user = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now()->subDay());
+        $activities1 = factory(Activity::class)->times(5)->make();
+        $user->activities()->saveMany($activities1);
+
+        Carbon::setTestNow(null);
+        $activities2 = factory(Activity::class)->times(5)->make();
+        $user->activities()->saveMany($activities2);
+
+        $result = $this->repo->getLatestActivitiesForUser($user->id, 6)->toArray();
+
+        $this->assertEquals(6, count($result));
+        $this->assertArraySubset($activities2[0]->toArray(), $result[0]);
+        $this->assertArraySubset($activities1[0]->toArray(), $result[5]);
+    }
+
+    public function test_paginateActivities()
+    {
+        $activities = factory(Activity::class)->times(10)->create();
+
+        $result = $this->repo->paginateActivities(6)->toArray();
+
+        $this->assertEquals(6, count($result['data']));
+        $this->assertEquals(10, $result['total']);
+        $this->assertArraySubset($activities[0]->toArray(), $result['data'][0]);
+        $this->assertArraySubset($activities[5]->toArray(), $result['data'][5]);
+    }
+
+    public function test_userActivityForPeriod()
+    {
+        $user = factory(User::class)->create();
+        $now = Carbon::now();
+
+        Carbon::setTestNow($now->copy()->subDays(15));
+        factory(Activity::class)->times(5)->create(['user_id' => $user->id]);
+
+        Carbon::setTestNow($now->copy()->subDays(11));
+        factory(Activity::class)->times(2)->create(['user_id' => $user->id]);
+
+        Carbon::setTestNow($now->copy()->subDays(5));
+        factory(Activity::class)->times(3)->create(['user_id' => $user->id]);
+
+        Carbon::setTestNow($now->copy()->subDays(2));
+        factory(Activity::class)->times(2)->create(['user_id' => $user->id]);
+
+        Carbon::setTestNow(null);
+
+        $result = $this->repo->userActivityForPeriod(
+            $user->id, Carbon::now()->subWeeks(2), Carbon::now()
+        );
+
+        $this->assertEquals($result->get(Carbon::now()->subDays(14)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(13)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(12)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(11)->toDateString()), 2);
+        $this->assertEquals($result->get(Carbon::now()->subDays(10)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(9)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(8)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(7)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(6)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(5)->toDateString()), 3);
+        $this->assertEquals($result->get(Carbon::now()->subDays(4)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(3)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->subDays(2)->toDateString()), 2);
+        $this->assertEquals($result->get(Carbon::now()->subDays(1)->toDateString()), 0);
+        $this->assertEquals($result->get(Carbon::now()->toDateString()), 0);
+    }
+}
diff --git a/tests/Feature/Repositories/Country/EloquentCountryTest.php b/tests/Feature/Repositories/Country/EloquentCountryTest.php
new file mode 100644
index 0000000..a42bfdb
--- /dev/null
+++ b/tests/Feature/Repositories/Country/EloquentCountryTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Tests\Feature\Repositories\Country;
+
+use Mockery as m;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Country;
+use Portal\Repositories\Country\EloquentCountry;
+
+class EloquentCountryTest extends FunctionalTestCase
+{
+    /**
+     * @var EloquentCountry
+     */
+    protected $repo;
+
+    protected $seed = false;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(EloquentCountry::class);
+    }
+
+    public function test_lists()
+    {
+        $countries = factory(Country::class)->times(8)->create();
+        $countries = $countries->sortBy(function ($country) {
+            return $country->name;
+        })->pluck('name', 'id');
+
+        $this->assertEquals($countries->toArray(), $this->repo->lists()->toArray());
+    }
+}
diff --git a/tests/Feature/Repositories/Permission/EloquentPermissionTest.php b/tests/Feature/Repositories/Permission/EloquentPermissionTest.php
new file mode 100644
index 0000000..0aa2326
--- /dev/null
+++ b/tests/Feature/Repositories/Permission/EloquentPermissionTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Tests\Feature\Repositories\Permission;
+
+use Cache;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Events\Permission\Created;
+use Portal\Permission;
+use Portal\Repositories\Permission\EloquentPermission;
+
+class EloquentPermissionTest extends FunctionalTestCase
+{
+    /**
+     * @var EloquentPermission
+     */
+    protected $repo;
+
+    protected $seed = false;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(EloquentPermission::class);
+    }
+
+    public function test_all()
+    {
+        $permissions = factory(Permission::class)->times(4)->create();
+
+        $this->assertEquals($permissions->toArray(), $this->repo->all()->toArray());
+    }
+
+    public function test_create()
+    {
+        $this->expectsEvents(Created::class);
+
+        $data = $this->getPermissionStubData();
+
+        $perm = $this->repo->create($data);
+
+        $this->seeInDatabase('permissions', $data + ['id' => $perm->id]);
+    }
+
+    public function test_update()
+    {
+        $this->expectsEvents(\Portal\Events\Permission\Updated::class);
+
+        Cache::put('foo', 'bar');
+
+        $data = $this->getPermissionStubData();
+
+        $perm = factory(Permission::class)->create();
+
+        $this->repo->update($perm->id, $data);
+
+        $this->seeInDatabase('permissions', $data + ['id' => $perm->id])
+            ->assertNull(Cache::get('foo'));
+    }
+
+    public function test_delete()
+    {
+        $this->expectsEvents(\Portal\Events\Permission\Deleted::class);
+
+        Cache::put('foo', 'bar');
+
+        $perm = factory(Permission::class)->create();
+
+        $this->repo->delete($perm->id);
+
+        $this->notSeeInDatabase('permissions', ['id' => $perm->id])
+            ->assertNull(Cache::get('foo'));
+    }
+
+    /**
+     * @return array
+     */
+    private function getPermissionStubData()
+    {
+        return [
+            'name'         => str_random(5),
+            'display_name' => str_random(5),
+            'description'  => 'foo',
+            'removable'    => true
+        ];
+    }
+}
diff --git a/tests/Feature/Repositories/Role/EloquentRoleTest.php b/tests/Feature/Repositories/Role/EloquentRoleTest.php
new file mode 100644
index 0000000..26add27
--- /dev/null
+++ b/tests/Feature/Repositories/Role/EloquentRoleTest.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Tests\Feature\Repositories\Role;
+
+use Mockery as m;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Events\Role\Created;
+use Portal\Repositories\Role\EloquentRole;
+use Portal\Role;
+use Portal\User;
+
+class EloquentRoleTest extends FunctionalTestCase
+{
+    /**
+     * @var EloquentRole
+     */
+    protected $repo;
+
+    protected $seed = false;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(EloquentRole::class);
+    }
+
+    public function test_all()
+    {
+        $roles = factory(Role::class)->times(4)->create();
+
+        $this->assertEquals(
+            $roles->toArray(),
+            $this->repo->all()->toArray()
+        );
+    }
+
+    public function test_getAllWithUsersCount()
+    {
+        $roles = factory(Role::class)->times(4)->create();
+        $users = factory(User::class)->times(3)->create();
+
+        $this->setRoleForUser($users[0], $roles[0]->name);
+        $this->setRoleForUser($users[1], $roles[0]->name);
+        $this->setRoleForUser($users[2], $roles[1]->name);
+
+        $roles[0]->users_count = 2;
+        $roles[1]->users_count = 1;
+        $roles[2]->users_count = 0;
+        $roles[3]->users_count = 0;
+
+        $this->assertEquals($roles->toArray(), $this->repo->getAllWithUsersCount()->toArray());
+    }
+
+    public function test_create()
+    {
+        $this->expectsEvents(Created::class);
+
+        $data = ['name' => 'foo', 'display_name' => 'Foo'];
+        $role = $this->repo->create($data);
+
+        $this->seeInDatabase('roles', $data + ['id' => $role->id]);
+    }
+
+    public function test_update()
+    {
+        $this->expectsEvents(\Portal\Events\Role\Updated::class);
+
+        $role = factory(Role::class)->create();
+
+        $data = ['name' => 'foo', 'display_name' => 'Foo'];
+
+        $this->repo->update($role->id, $data);
+
+        $this->seeInDatabase('roles', $data + ['id' => $role->id]);
+    }
+
+    public function test_delete()
+    {
+        $this->expectsEvents(\Portal\Events\Role\Deleted::class);
+
+        $role = factory(Role::class)->create();
+
+        $this->repo->delete($role->id);
+
+        $this->dontSeeInDatabase('roles', ['id' => $role->id]);
+    }
+
+    public function test_updatePermissions()
+    {
+        $role = factory(Role::class)->create();
+        $permissions = factory(\Portal\Permission::class)->times(2)->create();
+
+        $this->repo->updatePermissions($role->id, $permissions->pluck('id')->toArray());
+
+        $this->seeInDatabase('permission_role', ['role_id' => $role->id, 'permission_id' => $permissions[0]->id]);
+        $this->seeInDatabase('permission_role', ['role_id' => $role->id, 'permission_id' => $permissions[1]->id]);
+    }
+
+    public function test_lists()
+    {
+        $roles = factory(Role::class)->times(4)->create();
+        $roles = $roles->pluck('name', 'id');
+
+        $this->assertEquals($roles->toArray(), $this->repo->lists()->toArray());
+    }
+}
diff --git a/tests/Feature/Repositories/Session/DbSessionTest.php b/tests/Feature/Repositories/Session/DbSessionTest.php
new file mode 100644
index 0000000..694b222
--- /dev/null
+++ b/tests/Feature/Repositories/Session/DbSessionTest.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace Tests\Feature\Repositories\Session;
+
+use Carbon\Carbon;
+use DB;
+use Mockery as m;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Repositories\Session\DbSession;
+use Portal\User;
+
+class DbSessionTest extends FunctionalTestCase
+{
+    /**
+     * @var DbSession
+     */
+    protected $repo;
+
+    protected $seed = false;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(DbSession::class);
+    }
+
+    public function test_getUserSessions()
+    {
+        $user = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now());
+
+        $data1 = $this->getSessionStubData($user);
+        $data2 = $this->getSessionStubData($user);
+
+        DB::table('sessions')->insert($data1);
+        DB::table('sessions')->insert($data2);
+
+        $expected = collect([
+            (object) array_except($data1, ['payload', 'user_id']),
+            (object) array_except($data2, ['payload', 'user_id']),
+        ]);
+        $expected = $expected->sortBy('id')->keyBy('id')->toArray();
+
+        $actual = collect($this->repo->getUserSessions($user->id))
+            ->sortBy('id')
+            ->keyBy('id')
+            ->toArray();
+
+
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function test_if_get_user_sessions_will_return_active_sessions_only()
+    {
+        $user = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now());
+
+        $data1 = $this->getSessionStubData($user);
+        $data2 = $this->getSessionStubData($user);
+        $data2['last_activity'] = Carbon::now()->subMinutes(config('session.lifetime') + 1)->timestamp;
+
+        DB::table('sessions')->insert($data1);
+        DB::table('sessions')->insert($data2);
+
+        $expected = collect([
+            (object) array_except($data1, ['payload', 'user_id']),
+        ]);
+        $expected = $expected->sortBy('id')->keyBy('id')->toArray();
+
+        $actual = collect($this->repo->getUserSessions($user->id))
+            ->sortBy('id')
+            ->keyBy('id')
+            ->toArray();
+
+
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function test_invalidateUserSession()
+    {
+        $user = factory(User::class)->create([
+            'remember_token' => str_random(60)
+        ]);
+
+        $data = $this->getSessionStubData($user);
+        DB::table('sessions')->insert($data);
+
+        $this->repo->invalidateUserSession($user->id, $data['id']);
+
+        $this->dontSeeInDatabase('sessions', $data)
+            ->seeInDatabase('users', ['remember_token' => null]);
+    }
+
+    private function getSessionStubData($user)
+    {
+        $faker = app(\Faker\Generator::class);
+
+        return [
+            'id' => str_random(),
+            'user_id' => $user->id,
+            'ip_address' => $faker->ipv4,
+            'user_agent' => $faker->userAgent,
+            'payload' => 'foo',
+            'last_activity' => Carbon::now()->timestamp
+        ];
+    }
+}
diff --git a/tests/Feature/Repositories/User/EloquentUserTest.php b/tests/Feature/Repositories/User/EloquentUserTest.php
new file mode 100644
index 0000000..9657392
--- /dev/null
+++ b/tests/Feature/Repositories/User/EloquentUserTest.php
@@ -0,0 +1,379 @@
+<?php
+
+namespace Tests\Feature\Repositories\User;
+
+use DB;
+use Tests\Feature\FunctionalTestCase;
+use Portal\Repositories\User\EloquentUser;
+use Portal\Role;
+use Portal\Support\Enum\UserStatus;
+use Portal\User;
+use Carbon\Carbon;
+use Mockery as m;
+
+class EloquentUserTest extends FunctionalTestCase
+{
+    /**
+     * @var EloquentUser
+     */
+    protected $repo;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->repo = app(EloquentUser::class);
+    }
+
+    public function test_find()
+    {
+        $user = factory(User::class)->create();
+
+        $this->assertArraySubset(
+            $user->toArray(),
+            $this->repo->find($user->id)->toArray()
+        );
+
+        $this->assertNull($this->repo->find(123));
+    }
+
+    public function test_findByEmail()
+    {
+        $user = factory(User::class)->create();
+
+        $this->assertArraySubset(
+            $user->toArray(),
+            $this->repo->findByEmail($user->email)->toArray()
+        );
+
+        $this->assertNull($this->repo->findByEmail('foo@bar.com'));
+    }
+
+    public function test_findBySocialId()
+    {
+        $user = factory(User::class)->create();
+
+        DB::table('social_logins')->insert([
+            'user_id' => $user->id,
+            'provider' => 'foo',
+            'provider_id' => '123',
+            'avatar' => '',
+            'created_at' => Carbon::now()
+        ]);
+
+        $this->assertArraySubset(
+            $user->toArray(),
+            $this->repo->findBySocialId('foo', '123')->toArray()
+        );
+
+        $this->assertNull($this->repo->findBySocialId('bar', '111'));
+    }
+
+    public function test_create()
+    {
+        $data = factory(User::class)->make()->toArray();
+
+        $this->repo->create($data + ['password' => 'foo']);
+
+        $this->seeInDatabase('users', $data);
+    }
+
+    public function test_create_without_country()
+    {
+        $data1 = factory(User::class)->make(['country_id' => "0"])->toArray();
+        $data2 = factory(User::class)->make(['country_id' => 0])->toArray();
+
+        $this->repo->create($data1 + ['password' => 'foo']);
+        $this->repo->create($data2 + ['password' => 'bar']);
+
+        $expected1 = $data1;
+        $expected1['country_id'] = null;
+
+        $expected2 = $data2;
+        $expected2['country_id'] = null;
+
+        $this->seeInDatabase('users', $expected1);
+        $this->seeInDatabase('users', $expected2);
+    }
+
+    public function test_associateSocialAccountForUser()
+    {
+        $user = factory(User::class)->create();
+
+        Carbon::setTestNow(Carbon::now());
+
+        $socialUser = new \Laravel\Socialite\One\User();
+        $socialUser->map(['id' => '123', 'avatar' => 'foo']);
+
+        $this->repo->associateSocialAccountForUser($user->id, 'facebook', $socialUser);
+
+        $this->seeInDatabase('social_logins', [
+            'user_id' => $user->id,
+            'provider' => 'facebook',
+            'provider_id' => '123',
+            'avatar' => 'foo',
+            'created_at' => Carbon::now()
+        ]);
+
+        Carbon::setTestNow(null);
+    }
+
+    public function test_paginate()
+    {
+        $users = factory(User::class)->times(5)->create();
+
+        $result = $this->repo->paginate(2)->toArray();
+
+        $this->assertEquals(2, count($result['data']));
+        $this->assertEquals(5, $result['total']);
+        $this->assertArraySubset($users[0]->toArray(), $result['data'][0]);
+        $this->assertArraySubset($users[1]->toArray(), $result['data'][1]);
+    }
+
+    public function test_paginate_with_status()
+    {
+        factory(User::class)->times(3)->create();
+        factory(User::class)->create(['status' => UserStatus::BANNED]);
+
+        $active = $this->repo->paginate(2, null, UserStatus::ACTIVE)->toArray();
+        $banned = $this->repo->paginate(2, null, UserStatus::BANNED)->toArray();
+
+        $this->assertEquals(2, count($active['data']));
+        $this->assertEquals(3, $active['total']);
+
+        $this->assertEquals(1, count($banned['data']));
+        $this->assertEquals(1, $banned['total']);
+    }
+
+    public function test_paginate_with_search()
+    {
+        factory(User::class)->create(['first_name' => 'John', 'last_name' => 'Doe', 'username' => 'jdoe', 'email' => 'joe@test.com']);
+        factory(User::class)->create(['first_name' => 'Jane', 'last_name' => 'Doe', 'username' => 'janedoe', 'email' => 'jane@doe.com']);
+        factory(User::class)->create(['first_name' => 'Milos', 'last_name' => 'Stojanovic', 'email' => 'test@test.com']);
+
+        $this->assertEquals(2, $this->repo->paginate(25, 'doe')->total());
+        $this->assertEquals(1, $this->repo->paginate(25, 'Milos')->total());
+        $this->assertEquals(2, $this->repo->paginate(25, 'test')->total());
+        $this->assertEquals(2, $this->repo->paginate(25, 'an')->total());
+    }
+
+    public function test_update()
+    {
+        $user = factory(User::class)->create();
+
+        $data = [
+            'first_name' => 'John',
+            'last_name' => 'Doe',
+            'username' => 'foo',
+            'email' => 'test@test.com'
+        ];
+
+        $this->repo->update($user->id, $data);
+
+        $this->seeInDatabase('users', $data + ['id' => $user->id]);
+    }
+
+    public function test_update_without_country()
+    {
+        $user1 = factory(User::class)->create();
+        $user2 = factory(User::class)->create();
+
+        $data = [
+            'first_name' => 'John',
+            'last_name' => 'Doe',
+            'username' => 'foo',
+            'email' => 'test@test.com',
+            'country_id' => "0"
+        ];
+
+        $data2 = [
+            'first_name' => 'Jane',
+            'last_name' => 'Doe',
+            'username' => 'bar',
+            'email' => 'test2@test.com',
+            'country_id' => 0
+        ];
+
+        $this->repo->update($user1->id, $data);
+        $this->repo->update($user2->id, $data2);
+
+        $data['country_id'] = null;
+        $data2['country_id'] = null;
+
+        $this->seeInDatabase('users', $data + ['id' => $user1->id]);
+        $this->seeInDatabase('users', $data2 + ['id' => $user2->id]);
+    }
+
+    public function test_updateSocialNetworks()
+    {
+        $user = factory(User::class)->create();
+
+        $data = [
+            'facebook' => 'foo',
+            'twitter' => 'bar',
+            'dribbble' => 'bazz',
+            'skype' => 'skyyyype',
+            'linked_in' => 'li',
+            'google_plus' => 'g+'
+        ];
+
+        $this->repo->updateSocialNetworks($user->id, $data);
+
+        $this->seeInDatabase('user_social_networks', $data + ['user_id' => $user->id]);
+    }
+
+    public function test_delete()
+    {
+        $user = factory(User::class)->create();
+
+        $this->repo->delete($user->id);
+
+        $this->notSeeInDatabase('users', ['id' => $user->id]);
+    }
+
+    public function test_count()
+    {
+        factory(User::class)->times(7)->create();
+
+        $this->assertEquals(7, $this->repo->count());
+    }
+
+    public function test_newUsersCount()
+    {
+        Carbon::setTestNow(Carbon::now()->subMonth());
+        factory(User::class)->times(3)->create();
+
+        Carbon::setTestNow(null);
+        factory(User::class)->times(5)->create();
+
+        $this->assertEquals(5, $this->repo->newUsersCount());
+    }
+
+    public function test_countByStatus()
+    {
+        factory(User::class)->times(3)->create();
+        factory(User::class)->create(['status' => UserStatus::BANNED]);
+        factory(User::class)->times(2)->create(['status' => UserStatus::UNCONFIRMED]);
+
+        $this->assertEquals(3, $this->repo->countByStatus(UserStatus::ACTIVE));
+        $this->assertEquals(1, $this->repo->countByStatus(UserStatus::BANNED));
+        $this->assertEquals(2, $this->repo->countByStatus(UserStatus::UNCONFIRMED));
+    }
+
+    public function test_latest()
+    {
+        Carbon::setTestNow(Carbon::now()->subDay());
+        $user1 = factory(User::class)->create();
+
+        Carbon::setTestNow(null);
+        $users = factory(User::class)->times(3)->create();
+
+        $latestTwo = $this->repo->latest(2);
+        $latestFour = $this->repo->latest(4);
+
+        $this->assertEquals(2, count($latestTwo));
+        $this->assertEquals(4, count($latestFour));
+
+        $this->assertArraySubset($users[0]->toArray(), $latestTwo[0]->toArray());
+        $this->assertArraySubset($users[1]->toArray(), $latestTwo[1]->toArray());
+        $this->assertArraySubset($user1->toArray(), $latestFour[3]->toArray());
+    }
+
+    public function test_countOfNewUsersPerMonth()
+    {
+        Carbon::setTestNow(Carbon::now()->startOfYear());
+        factory(User::class)->times(2)->create();
+
+        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(2));
+        factory(User::class)->times(4)->create();
+
+        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(6));
+        factory(User::class)->times(2)->create();
+
+        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(7));
+        factory(User::class)->times(1)->create();
+
+        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(10));
+        factory(User::class)->times(4)->create();
+
+        Carbon::setTestNow(null);
+
+        $expected = [
+            'January' => 2,
+            'February' => 0,
+            'March' => 4,
+            'April' => 0,
+            'May' => 0,
+            'June' => 0,
+            'July' => 2,
+            'August' => 1,
+            'September' => 0,
+            'October' => 0,
+            'November' => 4,
+            'December' => 0
+        ];
+
+        $usersPerMonth = $this->repo->countOfNewUsersPerMonth(
+            Carbon::now()->startOfYear(),
+            Carbon::now()->endOfYear()
+        );
+
+        $this->assertEquals($expected, $usersPerMonth);
+    }
+
+    public function test_getUsersWithRole()
+    {
+        $admins = factory(User::class)->times(2)->create();
+        $role = Role::where('name', 'Admin')->first();
+        $role->users()->attach($admins->pluck('id')->toArray());
+
+        $user = factory(User::class)->create();
+        $role = Role::where('name', 'User')->first();
+        $role->users()->attach($user->id);
+
+        $result = $this->repo->getUsersWithRole('Admin');
+        $this->assertEquals(2, $result->count());
+        $this->assertArraySubset($admins[0]->toArray(), $result[0]->toArray());
+        $this->assertArraySubset($admins[1]->toArray(), $result[1]->toArray());
+
+        $result = $this->repo->getUsersWithRole('User');
+        $this->assertEquals(1, $result->count());
+        $this->assertArraySubset($user->toArray(), $result[0]->toArray());
+    }
+
+    public function test_setRole()
+    {
+        $user = factory(User::class)->create();
+        $role = Role::where('name', 'Admin')->first();
+
+        $this->repo->setRole($user->id, $role->id);
+
+        $this->seeInDatabase('role_user', [
+           'role_id' => $role->id,
+            'user_id' => $user->id
+        ]);
+    }
+
+    public function test_switchRolesForUsers()
+    {
+        $role = Role::where('name', 'User')->first();
+        $roleAdmin = Role::where('name', 'Admin')->first();
+
+        $user1 = factory(User::class)->create();
+        $user2 = factory(User::class)->create();
+
+        $this->setRoleForUser($user1, 'User');
+        $this->setRoleForUser($user2, 'User');
+
+        $this->repo->switchRolesForUsers($role->id, $roleAdmin->id);
+
+        $this->seeInDatabase('role_user', [
+            'role_id' => $roleAdmin->id,
+            'user_id' => $user1->id
+        ]);
+
+        $this->seeInDatabase('role_user', [
+            'role_id' => $roleAdmin->id,
+            'user_id' => $user2->id
+        ]);
+    }
+}
diff --git a/tests/MailTrap.php b/tests/MailTrap.php
index dc08189..d30d4e9 100644
--- a/tests/MailTrap.php
+++ b/tests/MailTrap.php
@@ -1,5 +1,9 @@
 <?php
 
+namespace Tests;
+
+use Config;
+use Exception;
 use GuzzleHttp\Client;
 
 trait MailTrap
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 4819724..6e13a05 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -1,6 +1,8 @@
 <?php
 
-class TestCase extends Illuminate\Foundation\Testing\TestCase
+namespace Tests;
+
+class TestCase extends \Laravel\BrowserKitTesting\TestCase
 {
     protected $seed = true;
 
@@ -18,9 +20,11 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
      */
     public function createApplication()
     {
+        ini_set('memory_limit', '2048M');
+
         $app = require __DIR__.'/../bootstrap/app.php';
 
-        $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
+        $app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
 
         return $app;
     }
@@ -48,4 +52,3 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
         return \DB::connection() instanceof \Illuminate\Database\SQLiteConnection;
     }
 }
-
diff --git a/tests/functional/FunctionalTestCase.php b/tests/functional/FunctionalTestCase.php
deleted file mode 100644
index 9fdc688..0000000
--- a/tests/functional/FunctionalTestCase.php
+++ /dev/null
@@ -1,163 +0,0 @@
-<?php
-
-
-use Portal\Role;
-use Portal\User;
-use Mockery as m;
-
-class FunctionalTestCase extends TestCase
-{
-    use \Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase;
-
-    protected $seed = true;
-
-    protected $settingsModified = [];
-
-    public function setUp()
-    {
-        $this->afterApplicationCreated(function () {
-            if ($this->isSQLiteConnection()) {
-                DB::connection()->getPdo()->exec("pragma foreign_keys=1");
-            }
-
-            $this->artisan('migrate');
-
-            if ($this->seed) {
-                $this->artisan('db:seed', ['--class' => 'CountriesSeeder']);
-                $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
-                $this->artisan('db:seed', ['--class' => 'PermissionsSeeder']);
-            }
-        });
-
-        $this->beforeApplicationDestroyed(function () {
-            if (Schema::hasTable('migrations')) {
-                $this->artisan('migrate:rollback');
-            }
-            \DB::disconnect();
-        });
-
-        $this->beforeApplicationDestroyed(function () {
-            foreach ($this->settingsModified as $key => $value) {
-                Settings::set($key, $value);
-            }
-
-            Settings::save();
-
-            $this->settingsModified = [];
-        });
-
-        parent::setUp();
-    }
-
-    /**
-     * Set some setting that should automatically be
-     * reverted to it's default value after each test.
-     * @param array $settings
-     */
-    protected function setSettings(array $settings)
-    {
-        foreach ($settings as $key => $value) {
-            $this->settingsModified[$key] = settings($key);
-            Settings::set($key, $value);
-        }
-
-        Settings::save();
-
-        $this->refreshAppAndExecuteCallbacks();
-    }
-
-    /**
-     * @param array $attrubutes
-     * @return mixed
-     */
-    protected function createAndLoginUser(array $attrubutes = [])
-    {
-        $user = $this->createUserWithSocialNetworks($attrubutes);
-
-        $user = $this->setRoleForUser($user, 'User');
-
-        $this->be($user);
-
-        return $user;
-    }
-
-    /**
-     * @param array $attrubutes
-     * @return mixed
-     */
-    protected function createAndLoginAdminUser(array $attrubutes = [])
-    {
-        $user = $this->createUserWithSocialNetworks($attrubutes);
-
-        $user = $this->setRoleForUser($user, 'Admin');
-
-        $this->be($user);
-
-        return $user;
-    }
-
-    /**
-     * @param array $attributes
-     * @return mixed
-     */
-    protected function createUserWithSocialNetworks(array $attributes = [])
-    {
-        $user = factory(User::class)->create($attributes);
-        $user->socialNetworks()->create([]);
-
-        return $user;
-    }
-
-    /**
-     * @return mixed
-     */
-    protected function createSuperUser()
-    {
-        $user = factory(User::class)->create();
-        return $this->makeSuperUser($user);
-    }
-
-    protected function makeSuperUser(User $user = null)
-    {
-        $user = m::mock($user ?: User::class)->makePartial();
-        $user->shouldReceive('can')->andReturn(true);
-
-        return $user;
-    }
-
-    /**
-     * @param User $user
-     * @param $role
-     * @return User
-     */
-    public function setRoleForUser(User $user, $role)
-    {
-        $role = Role::where('name', $role)->first();
-        $user->roles()->attach($role);
-
-        return $user;
-    }
-
-    public function seeInTable($selector, $text, $rowNumber, $columnNumber, $negate = false)
-    {
-        $fullSelector = "{$selector} tbody tr:nth-child({$rowNumber}) > td:nth-child({$columnNumber})";
-        return $this->seeInElement($fullSelector, $text, $negate);
-    }
-
-    public function dontSeeInTable($selector, $text, $rowNumber, $columnNumber)
-    {
-        return $this->seeInTable($selector, $text, $rowNumber, $columnNumber, true);
-    }
-
-    /**
-     * Click on link that matches provided selector.
-     *
-     * @param $selector
-     * @return $this
-     */
-    protected function clickOn($selector)
-    {
-        $link = $this->crawler->filter($selector)->first();
-        return $this->visit($link->link()->getUri());
-    }
-}
diff --git a/tests/functional/Http/Controllers/ActivityControllerTest.php b/tests/functional/Http/Controllers/ActivityControllerTest.php
deleted file mode 100644
index 27a7b4f..0000000
--- a/tests/functional/Http/Controllers/ActivityControllerTest.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-
-use Portal\User;
-use Carbon\Carbon;
-
-class ActivityControllerTest extends FunctionalTestCase
-{
-    /**
-     * @var \Portal\Services\Logging\UserActivity\Logger
-     */
-    public $logger;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->logger = app(Portal\Services\Logging\UserActivity\Logger::class);
-    }
-
-    public function test_display_all_activities()
-    {
-        $this->withoutMiddleware();
-
-        $user1 = factory(User::class)->create();
-        $user2 = factory(User::class)->create();
-
-        Carbon::setTestNow(Carbon::now());
-        $this->be($user1);
-        $this->logger->log('foo');
-
-        $this->be($user2);
-        $this->logger->log('bar');
-
-        $this->visit('activity');
-
-        $this->assertEquals(2, $this->crawler->filter('table tbody tr')->count());
-
-        $this->seeUserActivity($user1, 'foo', 1);
-        $this->seeUserActivity($user2, 'bar', 2);
-    }
-
-    public function test_display_activities_for_user()
-    {
-        $user = $this->createAndLoginAdminUser();
-
-        $this->logger->log('foo');
-
-        $this->visit('activity')
-            ->clickOn('table tbody a:first-child')
-            ->seePageIs("activity/user/{$user->id}/log")
-            ->seeUserActivity($user, 'foo', 1);
-    }
-
-    public function test_search_activities()
-    {
-        $this->withoutMiddleware();
-
-        $user = factory(User::class)->create();
-        $this->be($user);
-        $this->logger->log('foo');
-        $this->logger->log('bar');
-
-        $this->visit('activity')
-            ->type('fo', 'search')
-            ->press('search-activities-btn');
-
-        $this->seePageIs('activity?search=fo');
-        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
-        $this->seeUserActivity($user, 'foo', 1);
-    }
-
-    private function seeUserActivity($user, $message, $row)
-    {
-        return $this->seeInTable('table', $user->present()->nameOrEmail, $row, 1)
-            ->seeInTable('table', Input::ip(), $row, 2)
-            ->seeInTable('table', $message, $row, 3)
-            ->seeInTable('table', Carbon::now(), $row, 4)
-            ->seeElement("table tbody tr:nth-child({$row}) > td:nth-child(5) > a[data-content='".Input::header('User-agent')."']");
-    }
-
-}
diff --git a/tests/functional/Http/Controllers/Auth/AuthControllerTest.php b/tests/functional/Http/Controllers/Auth/AuthControllerTest.php
deleted file mode 100644
index a8871ca..0000000
--- a/tests/functional/Http/Controllers/Auth/AuthControllerTest.php
+++ /dev/null
@@ -1,393 +0,0 @@
-<?php
-
-
-use Portal\Events\User\LoggedIn;
-use Portal\Events\User\Registered;
-use Portal\Role;
-use Portal\Support\Enum\UserStatus;
-use Portal\User;
-use Mockery as m;
-
-class AuthControllerTest extends FunctionalTestCase
-{
-    use MailTrap;
-
-    public function test_login()
-    {
-        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
-
-        $this->loginUser('foo', 'bar')
-            ->seePageIs('/');
-    }
-
-    public function test_login_with_wrong_credentials()
-    {
-        $this->loginUser('foo', 'bar')
-            ->seePageIs('login')
-            ->see("These credentials do not match our records.");
-    }
-
-    public function test_throttling()
-    {
-        $this->setSettings([
-            'throttle_enabled' => true,
-            'throttle_attempts' => 3,
-            'throttle_lockout_time' => 2 // 2 minutes
-        ]);
-
-        for ($i = 0; $i < 3; $i++) {
-            $this->loginUser('foo', 'bar');
-        }
-
-        $this->loginUser('foo', 'bar')
-            ->seePageIs('login')
-            ->see("Too many login attempts. Please try again in 120 seconds.");
-    }
-
-    public function test_login_with_remember()
-    {
-        $user = factory(User::class)->create([
-            'username' => 'foo',
-            'password' => 'bar',
-            'last_login' => null,
-            'remember_token' => null
-        ]);
-
-        Settings::set('remember_me', false);
-
-        $this->visit('login')
-            ->dontSeeElement('#remember');
-
-        Settings::set('remember_me', true);
-
-        $this->visit('login')
-            ->seeElement('#remember')
-            ->loginUser('foo', 'bar', true)
-            ->seePageIs('/');
-
-        $user = $user->fresh();
-
-        $this->assertNotNull($user->remember_token);
-        $this->assertNotNull($user->last_login);
-    }
-
-    public function test_banned_user_cannot_log_in()
-    {
-        factory(User::class)->create([
-            'username' => 'foo',
-            'password' => 'bar',
-            'status' => UserStatus::BANNED
-        ]);
-
-        $this->loginUser('foo', 'bar');
-
-        $this->seePageIs('login')
-            ->see("Your account is banned by administrator.");
-    }
-
-    public function test_unconfirmed_user_cannot_login()
-    {
-        factory(User::class)->create([
-            'username' => 'foo',
-            'password' => 'bar',
-            'status' => UserStatus::UNCONFIRMED
-        ]);
-
-        $this->loginUser('foo', 'bar');
-
-        $this->seePageIs('login')
-            ->see("Please confirm your email address first.");
-    }
-
-    /**
-     * @expectedException Illuminate\Foundation\Testing\HttpException
-     */
-    public function test_registration_view()
-    {
-        $this->setSettings([
-            'reg_enabled' => false
-        ]);
-
-        $this->visit('login')
-            ->dontSee('You don\'t have an account?');
-
-        // This should fire HttpException since registration is disabled.
-        $this->visit('register');
-    }
-
-    public function test_registration_with_email_confirmation()
-    {
-        $this->setSettings([
-            'reg_enabled' => true,
-            'reg_email_confirmation' => true,
-            'captcha.enabled' => false
-        ]);
-
-        $this->expectsEvents(Registered::class);
-
-        $data = $this->getRegistrationFormStubData();
-
-        $this->registerUser($data);
-
-        $expected = array_except($data, ['password', 'password_confirmation', 'tos']);
-        $expected += ['status' => UserStatus::UNCONFIRMED];
-
-        $this->seePageIs('login')
-            ->see('You account is created successfully! Please confirm your email in order to log in.')
-            ->seeInDatabase('users', $expected);
-
-        $token = User::where('email', $data['email'])->first()->confirmation_token;
-
-        $message = $this->fetchInbox()[0];
-
-        $this->assertEquals('test@test.com', $message['to_email']);
-        $this->assertEquals(config('mail.from.address'), $message['from_email']);
-        $this->assertEquals(config('mail.from.name'), $message['from_name']);
-        $this->assertContains(
-            trans('app.thank_you_for_registering', ['app' => settings('app_name')]),
-            trim($message['html_body'])
-        );
-        $this->assertContains(
-            trans('app.confirm_email_on_link_below'),
-            trim($message['html_body'])
-        );
-        $this->assertContains(
-            route('register.confirm-email', $token),
-            trim($message['html_body'])
-        );
-
-        $this->emptyInbox();
-    }
-
-    public function test_registration_without_email_confirmation()
-    {
-        $this->setSettings([
-            'reg_enabled' => true,
-            'reg_email_confirmation' => false,
-            'notifications_signup_email' => false,
-            'captcha.enabled' => false
-        ]);
-
-        $this->expectsEvents(Registered::class);
-
-        $data = $this->getRegistrationFormStubData();
-        $this->registerUser($data);
-
-        $expected = array_except($data, ['password', 'password_confirmation', 'tos']);
-        $expected += ['status' => UserStatus::ACTIVE];
-
-        $this->seePageIs('login')
-            ->see('You account is created successfully! You can log in now.')
-            ->seeInDatabase('users', $expected);
-
-        $this->assertEmpty($this->fetchInbox());
-    }
-
-    public function test_email_notification_when_new_user_was_registered()
-    {
-        $this->setSettings([
-            'app_name' => 'foo',
-            'reg_enabled' => true,
-            'reg_email_confirmation' => false,
-            'notifications_signup_email' => true,
-            'captcha.enabled' => false
-        ]);
-
-        $admin1 = factory(User::class)->create(['email' => 'john.doe@test.com']);
-        $admin2 = factory(User::class)->create(['email' => 'jane.doe@test.com']);
-        $user = factory(User::class)->create(['email' => 'user.doe@test.com']);
-
-        $role = Role::where('name', 'Admin')->first();
-        $role->users()->attach([$admin1->id, $admin2->id]);
-
-        $role = Role::where('name', 'User')->first();
-        $role->users()->attach($user->id);
-
-        $data = $this->getRegistrationFormStubData();
-        $this->registerUser($data);
-
-        $newUser = User::where('email', $data['email'])->first();
-
-        $inbox = $this->fetchInbox();
-
-        $this->assertEquals(2, count($inbox));
-
-        $this->assertEquals('[foo] New User Registration', $inbox[0]['subject']);
-        $this->assertEquals('jane.doe@test.com', $inbox[0]['to_email']);
-        $this->assertContains(
-            trans('app.new_user_was_registered_on', ['app' => settings('app_name')]),
-            trim($inbox[0]['html_body'])
-        );
-        $this->assertContains(
-            trans('app.to_view_details_visit_link_below'),
-            trim($inbox[0]['html_body'])
-        );
-        $this->assertContains(
-            route('user.show', $newUser->id),
-            trim($inbox[0]['html_body'])
-        );
-
-        $this->assertEquals('[foo] New User Registration', $inbox[1]['subject']);
-        $this->assertEquals('john.doe@test.com', $inbox[1]['to_email']);
-
-        $this->emptyInbox();
-    }
-
-    public function test_redirect_to_custom_page_after_login()
-    {
-        $to = '?to=http://www.google.com';
-
-        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
-
-        $this->visit('login' . $to)
-            ->seeElement('input', ['type' => 'hidden', 'name' => 'to'])
-            ->type('foo', 'username')
-            ->type('bar', 'password')
-            ->press('Log In');
-
-        $this->seePageIs('http://www.google.com');
-    }
-
-    public function test_custom_redirect_page_is_available_after_failed_login_attempt()
-    {
-        $to = 'http://www.google.com';
-        $element = 'input';
-        $elementAttrs = ['type' => 'hidden', 'name' => 'to'];
-
-        $this->visit('login?to=' . $to)
-            ->seeElement($element, $elementAttrs)
-            ->type('foo', 'username')
-            ->type('bar', 'password')
-            ->press('Log In');
-
-        $this->seePageIs('login?to=' . urlencode($to))
-            ->seeElement($element, $elementAttrs);
-    }
-
-    public function test_access_to_auth_pages_is_not_allowed_after_authentication()
-    {
-        $this->setSettings([
-            'reg_enabled' => true,
-            '2fa.enabled' => true
-        ]);
-
-        $this->refreshAppAndExecuteCallbacks();
-
-        factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
-        $this->loginUser('foo', 'bar');
-
-        $forbiddenGetRoutes = [
-            'login', 'register', 'register/confirmation/123', 'password/remind', 'password/reset/123',
-            'auth/two-factor-authentication', 'auth/facebook/login', 'auth/facebook/callback',
-            'auth/twitter/email'
-        ];
-
-        foreach ($forbiddenGetRoutes as $route) {
-            $this->visit($route)
-                ->seePageIs('/');
-        }
-    }
-
-    private function getRegistrationFormStubData()
-    {
-        return [
-            'email' => 'test@test.com',
-            'username' => 'johndoe',
-            'password' => '123123',
-            'password_confirmation' => '123123',
-            'tos' => 1
-        ];
-    }
-
-    private function registerUser($data)
-    {
-        return $this->visit('login')
-            ->click("Don't have an account?")
-            ->seePageIs('register')
-            ->submitForm('Register', $data);
-    }
-
-    /**
-     * @param $username
-     * @param $password
-     * @param bool $remember
-     * @return $this
-     */
-    private function loginUser($username, $password, $remember = false)
-    {
-        $this->visit('login')
-            ->type($username, 'username')
-            ->type($password, 'password');
-
-        if ($remember) {
-            $this->check('remember');
-        }
-
-        $this->press('Log In');
-
-        return $this;
-    }
-
-    public function test_login_with_2fa_enabled()
-    {
-        $this->setSettings(['2fa.enabled' => true]);
-
-        $this->expectsEvents(LoggedIn::class);
-
-        $user = factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
-
-        Authy::shouldReceive('isEnabled')->andReturn(true);
-        Authy::shouldReceive('tokenIsValid')->with(m::any(), '123')->andReturn(true);
-
-        $this->loginUser('foo', 'bar')
-            ->seePageIs('auth/two-factor-authentication')
-            ->seeInSession('auth.2fa.id', $user->id);
-
-        $this->type('123', 'token')
-            ->press('Validate')
-            ->seePageIs('/');
-    }
-
-    public function test_login_with_wrong_2fa_token()
-    {
-        $this->setSettings(['2fa.enabled' => true]);
-
-        $this->refreshAppAndExecuteCallbacks();
-
-        $user = factory(User::class)->create(['username' => 'foo', 'password' => 'bar']);
-
-        Authy::shouldReceive('isEnabled')->andReturn(true);
-        Authy::shouldReceive('tokenIsValid')->with(m::any(), '123')->andReturn(false);
-
-        $this->loginUser('foo', 'bar')
-            ->seePageIs('auth/two-factor-authentication')
-            ->seeInSession('auth.2fa.id', $user->id);
-
-        $this->type('123', 'token')
-            ->press('Validate')
-            ->seePageIs('login')
-            ->see('2FA Token is invalid!');
-    }
-
-    /**
-     * Mock the event dispatcher so all events are silenced and collected.
-     * We will override it to allow model events though, since we want
-     * user notifications to be sent, so we can test them.
-     *
-     * @return $this
-     */
-    protected function withoutEvents()
-    {
-        $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher');
-
-        $mock->shouldReceive('fire')->andReturnUsing(function ($called) {
-            $this->firedEvents[] = $called;
-        });
-
-        $mock->shouldReceive('until');
-
-        $this->app->instance('events', $mock);
-
-        return $this;
-    }
-}
diff --git a/tests/functional/Http/Controllers/Auth/PasswordControllerTest.php b/tests/functional/Http/Controllers/Auth/PasswordControllerTest.php
deleted file mode 100644
index fb48ffc..0000000
--- a/tests/functional/Http/Controllers/Auth/PasswordControllerTest.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-
-use Portal\Events\User\RequestedPasswordResetEmail;
-use Portal\User;
-use Mockery as m;
-
-class PasswordControllerTest extends FunctionalTestCase
-{
-    use MailTrap;
-
-    public function test_send_password_reminder()
-    {
-        $user = factory(User::class)->create(['email' => 'test@test.com']);
-
-        $this->expectsEvents(RequestedPasswordResetEmail::class);
-
-        $this->visit('password/remind')
-            ->type('test@test.com', 'email')
-            ->press('Reset Password')
-            ->seePageIs('password/remind')
-            ->see('Password reset email sent. Check your inbox (and spam) folder.');
-
-        $message = $this->fetchInbox()[0];
-
-        $token = DB::table('password_resets')
-            ->where('email', $user->email)
-            ->first()->token;
-
-        $this->assertEquals('test@test.com', $message['to_email']);
-        $this->assertEquals(config('mail.from.address'), $message['from_email']);
-        $this->assertEquals(config('mail.from.name'), $message['from_name']);
-        $this->assertContains(
-            trans('app.request_for_password_reset_made'),
-            $message['html_body']
-        );
-
-        $this->assertContains(
-            url("password/reset/{$token}"),
-            $message['html_body']
-        );
-
-        $this->assertContains(
-            trans('app.if_you_did_not_requested'),
-            $message['html_body']
-        );
-
-        $this->emptyInbox();
-    }
-
-    public function test_password_reminder_with_wrong_email()
-    {
-        $this->visit('password/remind')
-            ->type('test@test.com', 'email')
-            ->press('Reset Password')
-            ->seePageIs('password/remind')
-            ->see('The selected email is invalid.');
-    }
-
-    public function test_password_reset()
-    {
-        $user = factory(User::class)->create(['email' => 'test@test.com']);
-
-        $token = str_random(60);
-
-        DB::table('password_resets')->insert([
-            'email' => $user->email,
-            'token' => $token,
-            'created_at' => \Carbon\Carbon::now()
-        ]);
-
-        $this->resetPassword($token, $user->email);
-
-        $this->seePageIs('login')
-            ->see('Your password has been reset!');
-
-        $user = $user->fresh();
-
-        $this->assertTrue(Hash::check('123123', $user->password));
-    }
-
-    public function test_password_reset_with_expired_token()
-    {
-        $user = factory(User::class)->create(['email' => 'test@test.com']);
-
-        $token = str_random(60);
-
-        DB::table('password_resets')->insert([
-            'email' => $user->email,
-            'token' => $token,
-            'created_at' => \Carbon\Carbon::now()->subHours(2)
-        ]);
-
-        $this->resetPassword($token, $user->email);
-
-        $this->seePageIs("password/reset/{$token}")
-            ->see("This password reset token is invalid.");
-    }
-
-    public function test_password_reset_with_invalid_email()
-    {
-        $user = factory(User::class)->create(['email' => 'test@test.com']);
-
-        $token = str_random(60);
-
-        DB::table('password_resets')->insert([
-            'email' => $user->email,
-            'token' => $token,
-            'created_at' => \Carbon\Carbon::now()
-        ]);
-
-        $this->resetPassword($token, 'foo@bar.com');
-
-        $this->seePageIs("password/reset/{$token}")
-            ->see("We can't find a user with that e-mail address.");
-    }
-
-    /**
-     * @param $token
-     * @param $email
-     */
-    private function resetPassword($token, $email)
-    {
-        $this->visit("password/reset/{$token}")
-            ->type($email, 'email')
-            ->type('123123', 'password')
-            ->type('123123', 'password_confirmation')
-            ->press('Update Password');
-    }
-
-    /**
-     * Mock the event dispatcher so all events are silenced and collected.
-     * We will override it to allow model events though, since we want
-     * user notifications to be sent, so we can test them.
-     *
-     * @return $this
-     */
-    protected function withoutEvents()
-    {
-        $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher');
-
-        $mock->shouldReceive('fire')->andReturnUsing(function ($called) {
-            $this->firedEvents[] = $called;
-        });
-
-        $mock->shouldReceive('until');
-
-        $this->app->instance('events', $mock);
-
-        return $this;
-    }
-}
diff --git a/tests/functional/Http/Controllers/Auth/SocialAuthControllerTest.php b/tests/functional/Http/Controllers/Auth/SocialAuthControllerTest.php
deleted file mode 100644
index c80901f..0000000
--- a/tests/functional/Http/Controllers/Auth/SocialAuthControllerTest.php
+++ /dev/null
@@ -1,207 +0,0 @@
-<?php
-
-use Portal\Support\Enum\UserStatus;
-use Portal\User;
-use Laravel\Socialite\Contracts\User as SocialUserContract;
-use Mockery as m;
-
-class SocialAuthControllerTest extends FunctionalTestCase
-{
-    public function test_social_login_for_new_user()
-    {
-        $this->setSettings(['reg_enabled' => true]);
-
-        $socialUser = new StubSocialUser;
-
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-
-        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
-
-        $this->visit("auth/foo/callback");
-
-        $this->assertUserCreatedAndLoggedIn($socialUser, 'foo');
-    }
-
-    public function test_social_login_for_new_user_if_registration_is_disabled()
-    {
-        Settings::set('reg_enabled', false);
-
-        $socialUser = new StubSocialUser;
-
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-
-        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
-
-        $this->visit("auth/foo/callback");
-
-        $this->seePageIs('login')
-            ->see('Only users who already created an account can log in.');
-    }
-
-    public function test_social_login_for_existing_user()
-    {
-        $user = factory(User::class)->create();
-        $socialUser = new StubSocialUser;
-
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-
-        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
-
-        DB::table('social_logins')->insert([
-            'user_id' => $user->id,
-            'provider' => 'foo',
-            'provider_id' => $socialUser->getId(),
-            'avatar' => $socialUser->getAvatar(),
-            'created_at' => \Carbon\Carbon::now()
-        ]);
-
-        $this->visit("auth/foo/callback");
-
-        $this->seePageIs('/');
-        $this->assertEquals($user->id, Auth::id());
-    }
-
-    public function test_twitter_login()
-    {
-        $this->setSettings(['reg_enabled' => true]);
-
-        $socialUser = new StubSocialUserWithoutEmail;
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-        Socialite::shouldReceive('driver')->with('twitter')->andReturn($driver);
-
-        $this->visit("auth/twitter/callback")
-            ->seePageIs('auth/twitter/email')
-            ->seeInSession('social.user', $socialUser);
-
-        $socialUser->email = 'john@doe.com';
-
-        $this->type('john@doe.com', 'email')
-            ->press('Log Me In')
-            ->assertUserCreatedAndLoggedIn($socialUser, 'twitter');
-    }
-
-    public function test_missing_email_for_non_twitter_provider()
-    {
-        $this->setSettings(['reg_enabled' => true]);
-
-        $socialUser = new StubSocialUserWithoutEmail;
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
-
-        $this->visit("auth/foo/callback")
-            ->seePageIs('login')
-            ->see("You have to provide your email address.");
-    }
-
-    public function test_social_login_for_user_with_one_word_name()
-    {
-        $this->setSettings(['reg_enabled' => true]);
-
-        $socialUser = new StubSocialUserWithOneWordName;
-
-        $driver = m::mock(Laravel\Socialite\Contracts\Provider::class);
-        $driver->shouldReceive('user')->andReturn($socialUser);
-
-        Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
-
-        $this->visit("auth/foo/callback");
-
-        $this->seeInDatabase('users', [
-            'username'   => null,
-            'email'      => $socialUser->getEmail(),
-            'first_name' => 'John',
-            'last_name'  => '',
-            'status'     => UserStatus::ACTIVE
-        ]);
-
-        $user = User::where('email', $socialUser->getEmail())->first();
-
-        $this->seeInDatabase('social_logins', [
-            'user_id'     => $user->id,
-            'provider'    => 'foo',
-            'provider_id' => $socialUser->getId(),
-            'avatar'      => $socialUser->getAvatar()
-        ]);
-
-        $this->seePageIs('/');
-        $this->assertEquals($user->id, Auth::id());
-    }
-
-    /**
-     * @param $socialUser
-     */
-    private function assertUserCreatedAndLoggedIn($socialUser, $provider)
-    {
-        $this->seeInDatabase('users', [
-            'username'   => null,
-            'email'      => $socialUser->getEmail(),
-            'first_name' => 'John',
-            'last_name'  => 'Doe',
-            'status'     => UserStatus::ACTIVE
-        ]);
-
-        $user = User::where('email', $socialUser->getEmail())->first();
-
-        $this->seeInDatabase('social_logins', [
-            'user_id'     => $user->id,
-            'provider'    => $provider,
-            'provider_id' => $socialUser->getId(),
-            'avatar'      => $socialUser->getAvatar()
-        ]);
-
-        $this->seePageIs('/');
-        $this->assertEquals($user->id, Auth::id());
-    }
-
-}
-
-class StubSocialUser implements SocialUserContract
-{
-    public function getId()
-    {
-        return '123';
-    }
-
-    public function getNickname()
-    {
-        return 'johndoe';
-    }
-
-    public function getName()
-    {
-        return 'John Doe';
-    }
-
-    public function getEmail()
-    {
-        return 'john@doe.com';
-    }
-
-    public function getAvatar()
-    {
-        return 'http://www.gravatar.com/avatar';
-    }
-}
-
-class StubSocialUserWithoutEmail extends StubSocialUser
-{
-    public $email = null;
-
-    public function getEmail()
-    {
-        return $this->email;
-    }
-}
-
-class StubSocialUserWithOneWordName extends StubSocialUser
-{
-    public function getName()
-    {
-        return 'John';
-    }
-}
\ No newline at end of file
diff --git a/tests/functional/Http/Controllers/PermissionsControllerTest.php b/tests/functional/Http/Controllers/PermissionsControllerTest.php
deleted file mode 100644
index e2ed1ec..0000000
--- a/tests/functional/Http/Controllers/PermissionsControllerTest.php
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-
-use Portal\Events\Permission\Created;
-use Portal\Events\Permission\Updated;
-use Portal\Events\Role\PermissionsUpdated;
-use Portal\Permission;
-use Portal\Role;
-use Mockery as m;
-
-class PermissionsControllerTest extends FunctionalTestCase
-{
-    protected $user;
-
-    protected $seed = false;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->user = $this->createSuperUser();
-        $this->be($this->user);
-    }
-
-    public function test_permissions_list()
-    {
-        $permission = factory(Permission::class)->create();
-
-        $this->visit('permission')
-            ->seeInTable('table', $permission->display_name, 1, 1);
-
-        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
-        $this->assertEquals(2, $this->crawler->filter('table tbody tr:nth-child(1) > td')->count());
-    }
-
-    public function test_permission_list_with_roles()
-    {
-        $permission = factory(Permission::class)->create();
-        $role = factory(Role::class)->create();
-
-        $role->perms()->attach($permission->id);
-
-        $this->visit('permission')
-            ->seeInTable('table', $permission->display_name, 1, 1)
-            ->seeElement('input', ['type' => 'checkbox', 'name' => "roles[$role->id][]"]);
-
-        $this->assertEquals(1, $this->crawler->filter('table tbody tr')->count());
-        $this->assertEquals(3, $this->crawler->filter('table tbody tr:nth-child(1) > td')->count());
-    }
-
-    public function test_save_role_permissions()
-    {
-        $this->expectsEvents(PermissionsUpdated::class);
-
-        $permission = factory(Permission::class)->create();
-        $role = factory(Role::class)->create();
-
-        $role->perms()->attach($permission->id);
-
-        $this->visit('permission')
-            ->submitForm('Save Permissions', [
-                'roles' => [
-                    $role->id => [$permission->id]
-                ]
-            ]);
-
-        $this->seePageIs('permission')
-            ->see('Permissions saved successfully.')
-            ->seeIsChecked("roles[{$role->id}][]")
-            ->seeInDatabase('permission_role', [
-                'role_id' => $role->id,
-                'permission_id' => $permission->id
-            ]);
-    }
-
-    public function test_save_role_permissions_if_no_permission_is_selected_for_specific_role()
-    {
-        $this->expectsEvents(PermissionsUpdated::class);
-
-        $permission = factory(Permission::class)->create();
-        $permission2 = factory(Permission::class)->create();
-        $role = factory(Role::class)->create();
-        $role2 = factory(Role::class)->create();
-
-        $role->perms()->attach($permission->id);
-        $role2->perms()->attach($permission2->id);
-
-        $this->visit('permission');
-
-        $form = $this->getForm('Save Permissions');
-
-        //Uncheck all checkboxes for Role 2
-        $form['roles'][$role2->id][0]->untick();
-        $form['roles'][$role2->id][1]->untick();
-
-        $this->makeRequestUsingForm($form);
-
-        $this->seePageIs('permission')
-            ->see('Permissions saved successfully.')
-            ->seeInDatabase('permission_role', [
-                'role_id' => $role->id,
-                'permission_id' => $permission->id
-            ])
-            ->dontSeeInDatabase('permission_role', [
-                'role_id' => $role2->id,
-                'permission_id' => $permission2->id
-            ]);
-    }
-
-    public function test_create_permission()
-    {
-        $this->app->instance('middleware.disable', false);
-
-        $this->expectsEvents(Created::class);
-
-        $data = $this->stubPermissionData();
-
-        $this->visit('permission')
-            ->click('Add Permission')
-            ->seePageIs('permission/create')
-            ->submitForm('Create Permission', $data);
-
-        $this->seePageIs('permission')
-            ->see('Permission created successfully.')
-            ->seeInDatabase('permissions', $data);
-    }
-
-    public function test_update_permission()
-    {
-        $this->expectsEvents(Updated::class);
-
-        $permission = factory(Permission::class)->create();
-
-        $data = $this->stubPermissionData();
-
-        $this->visit('permission')
-            ->clickOn('a[title="Edit Permission"]')
-            ->seePageIs("permission/{$permission->id}/edit")
-            ->submitForm('Update Permission', $data);
-
-        $this->seePageIs('permission')
-            ->see('Permission updated successfully.')
-            ->seeInDatabase('permissions', $data + ['id' => $permission->id]);
-    }
-
-    public function test_delete()
-    {
-        $this->expectsEvents(\Portal\Events\Permission\Deleted::class);
-
-        $permission = factory(Permission::class)->create();
-
-        $this->delete(route('permission.destroy', $permission->id))
-            ->followRedirects();
-
-        $this->seePageIs('permission')
-            ->see('Permission deleted successfully.')
-            ->dontSeeInDatabase('permissions', ['id' => $permission->id]);
-
-    }
-
-    public function test_if_non_removable_permissions_can_be_removed()
-    {
-        $permission = factory(Permission::class)->create(['removable' => false]);
-
-        $this->visit('permission');
-        $this->assertEquals(0, $this->crawler->filter("a[title='Delete Permission']")->first()->count());
-
-        $this->delete(route('permission.destroy', $permission->id))
-            ->followRedirects();
-
-        $this->assertResponseStatus(404);
-    }
-
-    private function stubPermissionData()
-    {
-        return [
-            'name' => 'foo_permission',
-            'display_name' => 'Foo Permission',
-            'description' => 'the description'
-        ];
-    }
-}
diff --git a/tests/functional/Http/Controllers/ProfileControllerTest.php b/tests/functional/Http/Controllers/ProfileControllerTest.php
deleted file mode 100644
index 6d89bda..0000000
--- a/tests/functional/Http/Controllers/ProfileControllerTest.php
+++ /dev/null
@@ -1,292 +0,0 @@
-<?php
-
-
-use Portal\Events\User\ChangedAvatar;
-use Portal\Events\User\UpdatedProfileDetails;
-use Portal\Role;
-use Portal\Support\Enum\UserStatus;
-use Portal\User;
-use Carbon\Carbon;
-
-class ProfileControllerTest extends FunctionalTestCase
-{
-    protected $user;
-
-    public function setUp()
-    {
-        parent::setUp();
-
-        $this->user = $this->createAndLoginUser();
-    }
-
-    public function test_can_access_profile_page()
-    {
-        $this->visit('/')
-            ->click('My Profile')
-            ->seePageIs('profile');
-    }
-
-    public function test_update_details()
-    {
-        $this->expectsEvents(UpdatedProfileDetails::class);
-
-        $data = $this->getStubDetailsData();
-
-        $this->visit('profile')
-            ->submitForm('Update Details', $data)
-            ->seePageIs('profile')
-            ->see('Profile updated successfully.')
-            ->seeInDatabase('users', $data + ['id' => $this->user->id]);
-    }
-
-    public function test_cannot_change_role_or_status()
-    {
-        $data = $this->getStubDetailsData();
-
-        $extendedData = $data + [
-            'role' => Role::whereName('Admin')->first()->id,
-            'status' => UserStatus::BANNED,
-        ];
-
-        $this->visit('profile')
-            ->submitForm('Update Details', $extendedData)
-            ->seePageIs('profile')
-            ->see('Profile updated successfully.')
-            ->seeInDatabase('users', $data + ['id' => $this->user->id, 'status' => UserStatus::ACTIVE])
-            ->dontSeeInDatabase('role_user', [
-                'user_id' => $this->user->id,
-                'role_id' => $extendedData['role']
-            ]);
-    }
-
-    public function test_update_avatar()
-    {
-        $this->expectsEvents(ChangedAvatar::class);
-
-        $uploads = ['avatar' => base_path('tests/files/image.png')];
-
-        $input = [
-            'points' => [
-                'x1' => 0,
-                'y1' => 0,
-                'x2' => 200,
-                'y2' => 200
-            ]
-        ] + $uploads;
-
-        $this->visit("profile")
-            ->submitForm('Save', $input, $uploads)
-            ->seePageIs('profile')
-            ->see('Avatar changed successfully.');
-
-        $user = $this->user->fresh();
-
-        $uploadedFile = public_path("upload/users/{$user->avatar}");
-
-        $this->assertNotNull($user->avatar);
-        $this->assertFileExists($uploadedFile);
-
-        list($width, $height) = getimagesize($uploadedFile);
-
-        $this->assertEquals(160, $width);
-        $this->assertEquals(160, $height);
-
-        @unlink($uploadedFile);
-    }
-
-    public function test_update_avatar_external()
-    {
-        $this->expectsEvents(ChangedAvatar::class);
-
-        $data = ['url' => '//www.gravatar.com/avatar'];
-        $this->post(route('profile.update.avatar-external', $this->user->id), $data)
-            ->followRedirects()
-            ->seePageIs('profile')
-            ->see('Avatar changed successfully.');
-
-        $this->seeInDatabase('users', ['id' => $this->user->id, 'avatar' => $data['url']]);
-    }
-
-    public function test_update_social_networks()
-    {
-        $data = [
-            'facebook' => 'facebook',
-            'twitter' => 'twitter',
-            'google_plus' => 'g+',
-            'linked_in' => 'li',
-            'dribbble' => 'Dribble',
-            'skype' => 'skyyype'
-        ];
-
-        $this->visit("profile")
-            ->submitForm('Update Social Networks', ['socials' => $data])
-            ->seeInDatabase('user_social_networks', $data)
-            ->seePageIs("profile")
-            ->see("Social networks updated successfully.");
-    }
-
-    public function test_update_user_login_details()
-    {
-        $data = [
-            'email' => 'john@doe.com',
-            'username' => 'milos',
-            'password' => 'milos123123',
-            'password_confirmation' => 'milos123123'
-        ];
-
-        $this->visit("profile")
-            ->submitForm("update-login-details-btn", $data)
-            ->seePageIs("profile")
-            ->see('Login details updated successfully.');
-
-        $user = $this->user->fresh();
-
-        $this->assertEquals($data['email'], $user->email);
-        $this->assertEquals($data['username'], $user->username);
-        $this->assertTrue(Hash::check($data['password'], $user->password));
-    }
-
-    public function test_password_is_not_changed_if_omitted_on_update()
-    {
-        $this->user = $this->createAndLoginUser([
-            'email' => 'john@doe.com',
-            'password' => '123123'
-        ]);
-
-        $data = ['email' => 'test@test.com', 'password' => '', 'password_confirmation' => ''];
-
-        $this->visit("profile")
-            ->submitForm("update-login-details-btn", $data)
-            ->seePageIs("profile")
-            ->see('Login details updated successfully.');
-
-        $user = $this->user->fresh();
-
-        $this->assertEquals($data['email'], $user->email);
-        $this->assertTrue(Hash::check('123123', $user->password));
-    }
-
-    public function test_2fa_form_visibility()
-    {
-        Settings::set('2fa.enabled', false);
-
-        $this->visit("profile")
-            ->dontSee('Two-Factor Authentication');
-
-        Settings::set('2fa.enabled', true);
-
-        $this->visit("profile")
-            ->see('Two-Factor Authentication');
-    }
-
-    public function test_enable_2fa()
-    {
-        $this->expectsEvents(\Portal\Events\User\TwoFactorEnabled::class);
-
-        Settings::set('2fa.enabled', true);
-
-        Authy::shouldReceive('isEnabled')->andReturn(false);
-        Authy::shouldReceive('register')->andReturnNull();
-
-        $data = ['country_code' => '1', 'phone_number' => '123'];
-
-        $this->visit("profile")
-            ->submitForm('Enable', $data)
-            ->seePageIs("profile")
-            ->seeInDatabase('users', [
-                'id' => $this->user->id,
-                'two_factor_country_code' => $data['country_code'],
-                'two_factor_phone' => $data['phone_number']
-            ])
-            ->see('Two-Factor Authentication enabled successfully.');
-    }
-
-    public function test_disable_2fa()
-    {
-        $this->expectsEvents(\Portal\Events\User\TwoFactorDisabled::class);
-
-        Settings::set('2fa.enabled', true);
-
-        Authy::shouldReceive('isEnabled')->andReturn(true);
-        Authy::shouldReceive('delete')->andReturnNull();
-
-        $this->visit("profile")
-            ->press('Disable')
-            ->seePageIs("profile")
-            ->seeInDatabase('users', [
-                'id' => $this->user->id,
-                'two_factor_country_code' => null,
-                'two_factor_phone' => null
-            ])
-            ->see('Two-Factor Authentication disabled successfully.');
-    }
-
-    public function test_activity_log()
-    {
-        $logger = app(Portal\Services\Logging\UserActivity\Logger::class);
-
-        Carbon::setTestNow(Carbon::now());
-
-        $logger->log('foo');
-        $logger->log('bar');
-
-        $buttonSelector = "a[data-content='".Input::header('User-agent')."']";
-
-        $this->visit('profile/activity')
-            ->seeInTable('table', Input::ip(), 1, 1)
-            ->seeInTable('table', 'foo', 1, 2)
-            ->seeInTable('table', Carbon::now()->toDateTimeString(), 1, 3)
-            ->seeElement("table tbody tr:nth-child(1) > td:nth-child(4) > {$buttonSelector}")
-            ->seeInTable('table', Input::ip(), 2, 1)
-            ->seeInTable('table', 'bar', 2, 2)
-            ->seeInTable('table', Carbon::now()->toDateTimeString(), 2, 3)
-            ->seeElement("table tbody tr:nth-child(2) > td:nth-child(4) > {$buttonSelector}");
-    }
-
-    public function test_session_invalidation()
-    {
-        putenv('SESSION_DRIVER=database');
-
-        $this->refreshApplication();
-
-        if ($this->isSQLiteConnection()) {
-            $this->executeCallbacks();
-        }
-
-        Carbon::setTestNow(Carbon::now());
-
-        $user = $this->createAndLoginAdminUser();
-
-        $this->visit('user')
-            ->click('Active Sessions')
-            ->seePageIs("profile/sessions")
-            ->seeInTable('table', Input::ip(), 1, 1)
-            ->seeInTable('table', Input::header("User-agent"), 1, 2)
-            ->seeInTable('table', Carbon::now()->toDateString(), 1, 3);
-
-        $this->assertEquals(1, $this->crawler->filter("table tbody tr")->count());
-
-        $url = $this->crawler->filter('a[title="Invalidate Session"]')->first()->link()->getUri();
-
-        $this->delete($url)
-            ->followRedirects()
-            ->dontSeeInDatabase('sessions', ['user_id' => $user->id]);
-    }
-
-    /**
-     * @return array
-     */
-    private function getStubDetailsData()
-    {
-        $data = [
-            'first_name' => 'foo',
-            'last_name'  => 'bar',
-            'birthday'   => Carbon::now()->subYears(25)->format('Y-m-d'),
-            'phone'      => '12345667',
-            'address'    => 'the address',
-            'country_id' => 688 //Serbia,
-        ];
-
-        return $data;
-    }
-}
diff --git a/tests/functional/Http/Controllers/RolesControllerTest.php b/tests/functional/Http/Controllers/RolesControllerTest.php
deleted file mode 100644
index 87e0dd1..0000000
--- a/tests/functional/Http/Controllers/RolesControllerTest.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-
-use Portal\Role;
-use Mockery as m;
-use Portal\User;
-
-class RolesControllerTest extends FunctionalTestCase
-{
-    protected $user;
-
-    protected $seed = false;
-
-    /**
-     * @before
-     */
-    public function setUp()
-    {
-        parent::setUp();
-        $this->user = $this->createSuperUser();
-        $this->be($this->user);
-    }
-
-    public function test_roles_list_is_displayed_properly()
-    {
-        $role1 = factory(Role::class)->create(['removable' => true]);
-        $role2 = factory(Role::class)->create(['removable' => false]);
-
-        $this->user->roles()->attach($role2->id);
-
-        $this->visit('role')
-            ->seeInTable('table', $role1->name, 1, 1)
-            ->seeInTable('table', $role1->display_name, 1, 2)
-            ->seeInTable('table', "0", 1, 3)
-            ->seeElement('table tbody tr:nth-child(1) > td a[title="Delete Role"]')
-            ->seeInTable('table', $role2->name, 2, 1)
-            ->seeInTable('table', $role2->display_name, 2, 2)
-            ->seeInTable('table', "1", 2, 3)
-            ->dontSeeElement('table tbody tr:nth-child(2) > td a[title="Delete Role"]');
-    }
-
-    public function test_create_role()
-    {
-        $data = $this->roleStubData();
-
-        $this->visit('role')
-            ->click('Add Role')
-            ->seePageIs('role/create')
-            ->submitForm('Create Role', $data);
-
-        $this->seePageIs('role')
-            ->see('Role created successfully.')
-            ->seeInDatabase('roles', $data);
-    }
-
-    public function test_edit_role()
-    {
-        $role = factory(Role::class)->create();
-
-        $this->visit('role')
-            ->clickOn('a[title="Edit Role"]')
-            ->seePageIs("role/{$role->id}/edit")
-            ->seeInField('name', $role->name)
-            ->seeInField('display_name', $role->display_name)
-            ->seeInField('description', $role->description);
-
-        $data = $this->roleStubData();
-
-        $this->submitForm('Update Role', $data)
-            ->seePageIs("role")
-            ->see('Role updated successfully.')
-            ->seeInDatabase('roles', $data + ['id' => $role->id]);
-    }
-
-    public function test_delete_role()
-    {
-        $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
-
-        $role = factory(Role::class)->create(['removable' => true]);
-
-        $this->delete(route('role.delete', $role->id))
-            ->dontSeeInDatabase('roles', ['id' => $role->id]);
-    }
-
-    public function test_users_receive_default_role_after_their_role_is_deleted()
-    {
-        $this->artisan('db:seed', ['--class' => 'RolesSeeder']);
-
-        $user = factory(User::class)->create();
-        $role = factory(Role::class)->create(['removable' => true]);
-        $userRole = Role::where('name', 'User')->first();
-
-        $this->setRoleForUser($user, $role->name);
-
-        $this->assertTrue($user->hasRole($role->name));
-
-        $this->delete(route('role.delete', $role->id))
-            ->seeInDatabase('role_user', [
-                'role_id' => $userRole->id,
-                'user_id' => $user->id
-            ]);
-
-        $user = $user->fresh();
-
-        $this->assertFalse($user->hasRole($role->name));
-        $this->assertTrue($user->hasRole($userRole->name));
-    }
-
-    public function test_delete_unremovable_role()
-    {
-        $role = factory(Role::class)->create(['removable' => false]);
-
-        // This call should throw an exception
-        // because this role cannot be deleted
-        $this->delete(route('role.delete', $role->id));
-
-        $this->assertResponseStatus(404);
-        $this->see('Oops, 404!');
-    }
-
-    /**
-     * @return array
-     */
-    private function roleStubData()
-    {
-        return [
-            'name' => 'foo',
-            'display_name' => 'Foooooo',
-            'description' => 'the description'
-        ];
-    }
-}
diff --git a/tests/functional/Http/Controllers/SettingsControllerTest.php b/tests/functional/Http/Controllers/SettingsControllerTest.php
deleted file mode 100644
index 204bc16..0000000
--- a/tests/functional/Http/Controllers/SettingsControllerTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-class SettingsControllerTest extends FunctionalTestCase
-{
-    public function test_update_app_name()
-    {
-        $user = $this->createSuperUser();
-        $this->be($user);
-
-        $oldName = Settings::get('app_name', 'Portal');
-
-        Settings::set('app_name', 'bar');
-
-        $name = 'foo';
-
-        $this->visit('settings')
-            ->seeInField('app_name', 'bar')
-            ->type('foo', 'app_name')
-            ->press('Update Settings');
-
-        $this->assertEquals($name, Settings::get('app_name'));
-
-        $this->visit('logout')
-            ->seeInElement("#footer p", $name);
-
-        Settings::set('app_name', $oldName);
-        Settings::save();
-    }
-}
diff --git a/tests/functional/Http/Controllers/UsersControllerTest.php b/tests/functional/Http/Controllers/UsersControllerTest.php
deleted file mode 100644
index 10074f9..0000000
--- a/tests/functional/Http/Controllers/UsersControllerTest.php
+++ /dev/null
@@ -1,447 +0,0 @@
-<?php
-
-use Portal\Events\User\TwoFactorEnabledByAdmin;
-use Portal\Events\User\UpdatedByAdmin;
-use Portal\Role;
-use Portal\Support\Enum\UserStatus;
-use Portal\User;
-use Carbon\Carbon;
-use Mockery as m;
-
-class UsersControllerTest extends FunctionalTestCase
-{
-
-    public function test_users_table_is_displayed()
-    {
-        $this->be($this->makeSuperUser());
-
-        $active = factory(User::class)->times(4)->create();
-        $banned = factory(User::class)->times(2)->create(['status' => UserStatus::BANNED]);
-        $unconfirmed = factory(User::class)->times(2)->create(['status' => UserStatus::UNCONFIRMED]);
-
-        $users = $active->merge($banned);
-        $users = $users->merge($unconfirmed);
-
-        $users = $users->reverse();
-
-        $this->visit('user')
-            ->seeInElement("h1.page-header", "Users")
-            ->seeInElement('h1.page-header small', 'list of registered users')
-            ->seeElement("#add-user");
-
-        foreach ($users as $i => $user) {
-            $this->seeInTable("#users-table-wrapper table", $user->present()->username, $i + 1, 1);
-            $this->seeInTable("#users-table-wrapper table", $user->present()->name, $i + 1, 2);
-            $this->seeInTable("#users-table-wrapper table", $user->email, $i + 1, 3);
-            $this->seeInTable("#users-table-wrapper table", $user->created_at->format('Y-m-d'), $i + 1, 4);
-            $this->seeInTable("#users-table-wrapper table", $user->status, $i + 1, 5);
-        }
-    }
-
-    public function test_users_pagination()
-    {
-        $this->be($this->makeSuperUser());
-
-        factory(User::class)->times(21)->create();
-
-        $this->visit('user');
-
-        $pagination = $this->crawler->filter(".pagination");
-        $paginationLinks = $this->crawler->filter('.pagination a');
-
-        $this->assertEquals(1, $pagination->count());
-        $this->assertEquals(2, $paginationLinks->count());
-    }
-
-    public function test_users_search()
-    {
-        $user1 = factory(User::class)->create(['first_name' => 'Milos', 'last_name' => 'Stojanovic']);
-        $user2 = factory(User::class)->create(['first_name' => 'John', 'last_name' => 'Doe']);
-        $user3 = factory(User::class)->create(['first_name' => 'Jane', 'last_name' => 'Doe']);
-
-        $this->be($this->makeSuperUser($user1));
-
-        $this->visit('user')
-            ->submitForm('search-users-btn', ['search' => 'doe'])
-            ->seePageIs('user?search=doe&status=')
-            ->seeInField('search', 'doe')
-            ->seeInTable('table', $user2->present()->name, 1, 2)
-            ->seeInTable('table', $user3->present()->name, 2, 2);
-    }
-
-    public function test_users_filter_by_status()
-    {
-        $this->be($this->makeSuperUser());
-
-        factory(User::class)->times(2)->create();
-        factory(User::class)->times(3)->create();
-
-        $this->visit('user?status=' . UserStatus::BANNED)
-            ->seeIsSelected('status', UserStatus::BANNED);
-
-        $this->assertEquals(1, $this->crawler->filter('#users-table-wrapper table tbody tr')->count());
-    }
-
-    public function test_add_user()
-    {
-        $this->beSuperUser();
-
-        $this->visit('user')
-            ->click('Add User')
-            ->seePageIs('user/create');
-
-        $data = $this->stubUserData();
-
-        $this->submitForm('Create User', $data);
-
-        $user = User::where('email', $data['email'])->first();
-
-        $expected = array_except($data, ['role', 'password', 'password_confirmation']);
-
-        $this->seeInDatabase('users', $expected)
-            ->seePageIs('user')
-            ->see('User created successfully.')
-            ->assertTrue(Hash::check('123123', $user->password));
-    }
-
-    public function test_add_user_without_country()
-    {
-        $this->beSuperUser();
-
-        $this->visit('user')
-            ->click('Add User')
-            ->seePageIs('user/create');
-
-        $data = $this->stubUserData();
-        $data['country_id'] = 0;
-
-        $this->submitForm('Create User', $data);
-
-        $user = User::where('email', $data['email'])->first();
-
-        $expected = array_except($data, ['role', 'password', 'password_confirmation']);
-        $expected['country_id'] = null;
-
-        $this->seeInDatabase('users', $expected)
-            ->seePageIs('user')
-            ->see('User created successfully.')
-            ->assertTrue(Hash::check('123123', $user->password));
-    }
-
-    public function test_add_user_validation()
-    {
-        $this->beSuperUser();
-
-        $this->visit('user/create')
-            ->press('Create User')
-            ->seePageIs('user/create')
-            ->see('The email field is required.')
-            ->see('The password field is required.');
-
-        $this->visit('user/create')
-            ->type('asdfa', 'email')
-            ->type('123', 'password')
-            ->type('122', 'password_confirmation')
-            ->press('Create User')
-            ->seePageIs('user/create')
-            ->see('The email must be a valid email address.')
-            ->see('The password must be at least 6 characters.')
-            ->see('The password confirmation does not match.');
-    }
-
-    public function test_view_user_page()
-    {
-        $user = $this->createAndLoginAdminUser();
-
-        $this->visit('user')
-            ->clickOn('a[title="View User"]')
-            ->seePageIs("user/{$user->id}/show")
-            ->seeLink('Edit', route('user.edit', $user->id));
-    }
-
-    public function test_update_user_details()
-    {
-        $this->expectsEvents(UpdatedByAdmin::class);
-
-        $this->createAndLoginAdminUser();
-
-        $user = $this->createUserWithSocialNetworks();
-        $user = $this->setRoleForUser($user, 'User');
-
-        $this->visit('user')
-            ->seeLink('', "user/{$user->id}/edit");
-
-        $this->visit("user/{$user->id}/edit");
-
-        $data = [
-            'role' => Role::whereName('User')->first()->id,
-            'status' => UserStatus::BANNED,
-            'first_name' => 'foo',
-            'last_name' => 'bar',
-            'birthday' => Carbon::now()->subYears(25)->format('Y-m-d'),
-            'phone' => '12345667',
-            'address' => 'the address',
-            'country_id' => 688 //Serbia,
-        ];
-
-        $this->submitForm('update-details-btn', $data);
-
-        $expected = array_except($data, 'role') + ['id' => $user->id];
-
-        $this->seeInDatabase('users', $expected)
-            ->seeInDatabase('role_user', ['user_id' => $user->id, 'role_id' => $data['role']])
-            ->seePageIs("user/{$user->id}/edit")
-            ->see('User updated successfully.');
-    }
-
-    public function test_update_user_social_networks()
-    {
-        $user = $this->createAndLoginAdminUser();
-
-        $data = [
-            'facebook' => 'facebook',
-            'twitter' => 'twitter',
-            'google_plus' => 'g+',
-            'linked_in' => 'li',
-            'dribbble' => 'Dribble',
-            'skype' => 'skyyype'
-        ];
-
-        $this->visit("user/{$user->id}/edit")
-            ->submitForm('Update Social Networks', ['socials' => $data])
-            ->seeInDatabase('user_social_networks', $data)
-            ->seePageIs("user/{$user->id}/edit")
-            ->see("Social networks updated successfully.");
-    }
-
-    public function test_update_user_login_details()
-    {
-        $user = $this->createAndLoginAdminUser([
-            'email' => 'test@test.com',
-            'username' => 'test',
-            'password' => 'milos123'
-        ]);
-
-        $data = [
-            'email' => 'john@doe.com',
-            'username' => 'milos',
-            'password' => '123123',
-            'password_confirmation' => '123123'
-        ];
-
-        $this->visit("user/{$user->id}/edit")
-            ->submitForm("update-login-details-btn", $data)
-            ->seePageIs("user/{$user->id}/edit")
-            ->see('Login details updated successfully.');
-
-        $user = $user->fresh();
-
-        $this->assertEquals($data['email'], $user->email);
-        $this->assertEquals($data['username'], $user->username);
-        $this->assertTrue(Hash::check($data['password'], $user->password));
-    }
-
-    public function test_2fa_form_visibility()
-    {
-        Settings::set('2fa.enabled', false);
-        $user = $this->createAndLoginAdminUser();
-
-        $this->visit("user/{$user->id}/edit")
-            ->dontSee('Two-Factor Authentication');
-
-        Settings::set('2fa.enabled', true);
-
-        $this->visit("user/{$user->id}/edit")
-            ->see('Two-Factor Authentication');
-    }
-
-    public function test_enable_2fa_for_user()
-    {
-        $this->expectsEvents(TwoFactorEnabledByAdmin::class);
-
-        Settings::set('2fa.enabled', true);
-        $user = $this->createAndLoginAdminUser();
-
-        Authy::shouldReceive('isEnabled')->andReturn(false);
-        Authy::shouldReceive('register')->andReturnNull();
-
-        $data = ['country_code' => '1', 'phone_number' => '123'];
-
-        $this->visit("user/{$user->id}/edit")
-            ->submitForm('Enable', $data)
-            ->seePageIs("user/{$user->id}/edit")
-            ->seeInDatabase('users', [
-                'id' => $user->id,
-                'two_factor_country_code' => $data['country_code'],
-                'two_factor_phone' => $data['phone_number']
-            ])
-            ->see('Two-Factor Authentication enabled successfully.');
-    }
-
-    public function test_disable_2fa_for_user()
-    {
-        $this->expectsEvents(\Portal\Events\User\TwoFactorDisabledByAdmin::class);
-
-        Settings::set('2fa.enabled', true);
-        $user = $this->createAndLoginAdminUser();
-
-        Authy::shouldReceive('isEnabled')->andReturn(true);
-        Authy::shouldReceive('delete')->andReturnNull();
-
-        $this->visit("user/{$user->id}/edit")
-            ->press('Disable')
-            ->seePageIs("user/{$user->id}/edit")
-            ->seeInDatabase('users', [
-                'id' => $user->id,
-                'two_factor_country_code' => null,
-                'two_factor_phone' => null
-            ])
-            ->see('Two-Factor Authentication disabled successfully.');
-    }
-
-    public function test_avatar_update()
-    {
-        $user = $this->createAndLoginAdminUser();
-
-        $uploads = ['avatar' => base_path('tests/files/image.png')];
-
-        $input = [
-            'points' => [
-                'x1' => 0,
-                'y1' => 0,
-                'x2' => 200,
-                'y2' => 200
-            ]
-        ] + $uploads;
-
-        $this->visit("user/{$user->id}/edit")
-            ->submitForm('Save', $input, $uploads);
-
-        $this->seePageIs("user/{$user->id}/edit")
-            ->see('Avatar changed successfully.');
-
-        $user = $user->fresh();
-
-        $uploadedFile = public_path("upload/users/{$user->avatar}");
-
-        $this->assertNotNull($user->avatar);
-        $this->assertFileExists($uploadedFile);
-
-        list($width, $height) = getimagesize($uploadedFile);
-
-        $this->assertEquals(160, $width);
-        $this->assertEquals(160, $height);
-
-        @unlink($uploadedFile);
-    }
-
-    /**
-     * @expectedException Illuminate\Foundation\Testing\HttpException
-     */
-    public function test_session_page_is_not_available_for_non_database_driver()
-    {
-        putenv('SESSION_DRIVER=array');
-
-        $this->refreshApp();
-
-        $user = $this->createAndLoginAdminUser();
-
-        $this->visit('user')
-            ->dontSeeElement('a[title="User Sessions"]');
-
-        // this page should not be accessible if
-        // database session driver is not being used
-        $this->visit("user/{$user->id}/sessions");
-    }
-
-    public function test_invalidate_session()
-    {
-        putenv('SESSION_DRIVER=database');
-
-        $this->refreshApp();
-
-        Carbon::setTestNow(Carbon::now());
-
-        $user = $this->createAndLoginAdminUser();
-
-        $this->visit('user')
-            ->clickOn('a[title="User Sessions"]')
-            ->seePageIs("user/{$user->id}/sessions")
-            ->seeInTable('table', Input::ip(), 1, 1)
-            ->seeInTable('table', Input::header("User-agent"), 1, 2)
-            ->seeInTable('table', Carbon::now()->toDateString(), 1, 3);
-
-        $this->assertEquals(1, $this->crawler->filter("table tbody tr")->count());
-
-        $url = $this->crawler->filter('a[title="Invalidate Session"]')->first()->link()->getUri();
-
-        $this->delete($url)
-            ->followRedirects()
-            ->dontSeeInDatabase('sessions', ['user_id' => $user->id])
-            ->seePageIs("user/{$user->id}/sessions")
-            ->see('Session invalidated successfully.');
-    }
-
-    public function test_delete_user()
-    {
-        $this->createAndLoginAdminUser();
-
-        $user = $this->createUserWithSocialNetworks();
-        $user = $this->setRoleForUser($user, 'User');
-
-        $this->delete(route('user.delete', $user->id))
-            ->followRedirects()
-            ->seePageIs('user')
-            ->see("User deleted successfully.");
-    }
-
-    public function test_if_user_can_delete_himself()
-    {
-        $admin = $this->createAndLoginAdminUser();
-
-        $this->delete(route('user.delete', $admin->id))
-            ->followRedirects()
-            ->seePageIs('user')
-            ->see("You cannot delete yourself.");
-    }
-
-    /**
-     * @param array $override
-     * @return array
-     */
-    private function stubUserData(array $override = [])
-    {
-        return array_merge([
-            'role' => Role::where('name', 'User')->first()->id,
-            'status' => UserStatus::ACTIVE,
-            'first_name' => 'John',
-            'last_name' => 'Doe',
-            'birthday' => Carbon::now()->subYears(20)->format('Y-m-d'),
-            'phone' => '123456',
-            'address' => 'some address',
-            'country_id' => 688,
-            'email' => 'john@doe.com',
-            'username' => 'johndoe',
-            'password' => '123123',
-            'password_confirmation' => '123123'
-        ], $override);
-    }
-
-    private function beSuperUser()
-    {
-        $user = $this->createSuperUser();
-
-        $this->be($user);
-
-        return $user;
-    }
-
-    private function refreshApp()
-    {
-        $this->refreshApplication();
-
-        if ($this->isSQLiteConnection()) {
-            $this->executeCallbacks();
-        }
-    }
-}
diff --git a/tests/functional/Listeners/BaseListenerTestCase.php b/tests/functional/Listeners/BaseListenerTestCase.php
deleted file mode 100644
index df99719..0000000
--- a/tests/functional/Listeners/BaseListenerTestCase.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-
-use Portal\User;
-
-class BaseListenerTestCase extends FunctionalTestCase
-{
-    protected $user;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->user = factory(User::class)->create();
-        $this->be($this->user);
-    }
-
-    protected function assertMessageLogged($msg)
-    {
-        $this->seeInDatabase('user_activity', [
-            'user_id' => $this->user->id,
-            'ip_address' => Input::ip(),
-            'user_agent' => Input::header('User-agent'),
-            'description' => $msg
-        ]);
-    }
-}
\ No newline at end of file
diff --git a/tests/functional/Listeners/PermissionEventsSubscriberTest.php b/tests/functional/Listeners/PermissionEventsSubscriberTest.php
deleted file mode 100644
index 18b422f..0000000
--- a/tests/functional/Listeners/PermissionEventsSubscriberTest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-use Mockery as m;
-use Portal\Events\Permission\Created;
-use Portal\Events\Permission\Deleted;
-use Portal\Events\Permission\Updated;
-
-class PermissionEventsSubscriberTest extends BaseListenerTestCase
-{
-    protected $perm;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->perm = factory(\Portal\Permission::class)->create();
-    }
-
-    public function test_onCreate()
-    {
-        event(new Created($this->perm));
-        $this->assertMessageLogged("Created new permission called {$this->perm->display_name}.");
-    }
-
-    public function test_onUpdate()
-    {
-        event(new Updated($this->perm));
-        $this->assertMessageLogged("Updated the permission named {$this->perm->display_name}.");
-    }
-
-    public function test_onDelete()
-    {
-        event(new Deleted($this->perm));
-        $this->assertMessageLogged("Deleted permission named {$this->perm->display_name}.");
-    }
-
-}
diff --git a/tests/functional/Listeners/RoleEventsSubscriberTest.php b/tests/functional/Listeners/RoleEventsSubscriberTest.php
deleted file mode 100644
index c5ac690..0000000
--- a/tests/functional/Listeners/RoleEventsSubscriberTest.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-
-use Portal\Events\Role\Created;
-use Portal\Events\Role\Deleted;
-use Portal\Events\Role\PermissionsUpdated;
-use Portal\Events\Role\Updated;
-
-class RoleEventsSubscriberTest extends BaseListenerTestCase
-{
-    protected $role;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->role = factory(\Portal\Role::class)->create();
-    }
-
-    public function test_onCreate()
-    {
-        event(new Created($this->role));
-        $this->assertMessageLogged("Created new role called {$this->role->display_name}.");
-    }
-
-    public function test_onUpdate()
-    {
-        event(new Updated($this->role));
-        $this->assertMessageLogged("Updated role with name {$this->role->display_name}.");
-    }
-
-    public function test_onDelete()
-    {
-        event(new Deleted($this->role));
-        $this->assertMessageLogged("Deleted role named {$this->role->display_name}.");
-    }
-
-    public function test_onPermissionsUpdate()
-    {
-        event(new PermissionsUpdated($this->role));
-        $this->assertMessageLogged("Updated role permissions.");
-    }
-
-}
diff --git a/tests/functional/Listeners/UserEventsSubscriberTest.php b/tests/functional/Listeners/UserEventsSubscriberTest.php
deleted file mode 100644
index 22fc32f..0000000
--- a/tests/functional/Listeners/UserEventsSubscriberTest.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-
-use Mockery as m;
-
-class UserEventsSubscriberTest extends BaseListenerTestCase
-{
-    protected $theUser;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->theUser = factory(\Portal\User::class)->create();
-    }
-
-    public function test_onLogin()
-    {
-        event(new \Portal\Events\User\LoggedIn);
-        $this->assertMessageLogged('Logged in.');
-    }
-
-    public function test_onLogout()
-    {
-        event(new \Portal\Events\User\LoggedOut());
-        $this->assertMessageLogged('Logged out.');
-    }
-
-    public function test_onRegister()
-    {
-        event(new \Portal\Events\User\Registered($this->user));
-        $this->assertMessageLogged('Created an account.');
-    }
-
-    public function test_onAvatarChange()
-    {
-        event(new \Portal\Events\User\ChangedAvatar);
-        $this->assertMessageLogged('Updated profile avatar.');
-    }
-
-    public function test_onProfileDetailsUpdate()
-    {
-        event(new \Portal\Events\User\UpdatedProfileDetails);
-        $this->assertMessageLogged('Updated profile details.');
-    }
-
-    public function test_onDelete()
-    {
-        event(new \Portal\Events\User\Deleted($this->theUser));
-
-        $message = sprintf(
-            "Deleted user %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onBan()
-    {
-        event(new \Portal\Events\User\Banned($this->theUser));
-
-        $message = sprintf(
-            "Banned user %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onUpdateByAdmin()
-    {
-        event(new \Portal\Events\User\UpdatedByAdmin($this->theUser));
-
-        $message = sprintf(
-            "Updated profile details for %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onCreate()
-    {
-        event(new \Portal\Events\User\Created($this->theUser));
-
-        $message = sprintf(
-            "Created an account for user %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onSettingsUpdate()
-    {
-        event(new \Portal\Events\Settings\Updated);
-        $this->assertMessageLogged('Updated website settings.');
-    }
-
-    public function test_onTwoFactorEnable()
-    {
-        event(new \Portal\Events\User\TwoFactorEnabled);
-        $this->assertMessageLogged('Enabled Two-Factor Authentication.');
-    }
-
-    public function test_onTwoFactorDisable()
-    {
-        event(new \Portal\Events\User\TwoFactorDisabled);
-        $this->assertMessageLogged('Disabled Two-Factor Authentication.');
-    }
-
-    public function test_onTwoFactorEnabledByAdmin()
-    {
-        event(new \Portal\Events\User\TwoFactorEnabledByAdmin($this->theUser));
-
-        $message = sprintf(
-            "Enabled Two-Factor Authentication for user %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onTwoFactorDisabledByAdmin()
-    {
-        event(new \Portal\Events\User\TwoFactorDisabledByAdmin($this->theUser));
-
-        $message = sprintf(
-            "Disabled Two-Factor Authentication for user %s.",
-            $this->theUser->present()->nameOrEmail
-        );
-
-        $this->assertMessageLogged($message);
-    }
-
-    public function test_onPasswordResetEmailRequest()
-    {
-        event(new \Portal\Events\User\RequestedPasswordResetEmail($this->user));
-        $this->assertMessageLogged("Requested password reset email.");
-    }
-
-    public function test_onPasswordReset()
-    {
-        event(new \Portal\Events\User\ResetedPasswordViaEmail($this->user));
-        $this->assertMessageLogged("Reseted password using \"Forgot Password\" option.");
-    }
-}
diff --git a/tests/functional/Repositories/Activity/EloquentActivityTest.php b/tests/functional/Repositories/Activity/EloquentActivityTest.php
deleted file mode 100644
index f81daf3..0000000
--- a/tests/functional/Repositories/Activity/EloquentActivityTest.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-
-use Portal\Repositories\Activity\EloquentActivity;
-use Portal\Services\Logging\UserActivity\Activity;
-use Portal\User;
-use Carbon\Carbon;
-use Mockery as m;
-
-class EloquentActivityTest extends FunctionalTestCase
-{
-    /**
-     * @var EloquentActivity
-     */
-    protected $repo;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(EloquentActivity::class);
-    }
-
-    public function test_log()
-    {
-        $user = factory(User::class)->create();
-
-        Carbon::setTestNow(Carbon::now());
-
-        $data = [
-            'user_id' => $user->id,
-            'ip_address' => '123.456.789.012',
-            'user_agent' => 'foo',
-            'description' => 'descriptionnnn'
-        ];
-
-        $this->repo->log($data);
-
-        $this->seeInDatabase('user_activity', $data);
-    }
-
-    public function test_paginateActivitiesForUser()
-    {
-        $user = factory(User::class)->create();
-
-        $activities = factory(Activity::class)->times(10)->make();
-        $user->activities()->saveMany($activities);
-
-        $result = $this->repo->paginateActivitiesForUser($user->id, 6)->toArray();
-
-        $this->assertEquals(6, count($result['data']));
-        $this->assertEquals(10, $result['total']);
-        $this->assertArraySubset($activities[0]->toArray(), $result['data'][0]);
-        $this->assertArraySubset($activities[5]->toArray(), $result['data'][5]);
-    }
-
-    public function test_getLatestActivitiesForUser()
-    {
-        $user = factory(User::class)->create();
-
-        Carbon::setTestNow(Carbon::now()->subDay());
-        $activities1 = factory(Activity::class)->times(5)->make();
-        $user->activities()->saveMany($activities1);
-
-        Carbon::setTestNow(null);
-        $activities2 = factory(Activity::class)->times(5)->make();
-        $user->activities()->saveMany($activities2);
-
-        $result = $this->repo->getLatestActivitiesForUser($user->id, 6)->toArray();
-
-        $this->assertEquals(6, count($result));
-        $this->assertArraySubset($activities2[0]->toArray(), $result[0]);
-        $this->assertArraySubset($activities1[0]->toArray(), $result[5]);
-    }
-
-    public function test_paginateActivities()
-    {
-        $activities = factory(Activity::class)->times(10)->create();
-
-        $result = $this->repo->paginateActivities(6)->toArray();
-
-        $this->assertEquals(6, count($result['data']));
-        $this->assertEquals(10, $result['total']);
-        $this->assertArraySubset($activities[0]->toArray(), $result['data'][0]);
-        $this->assertArraySubset($activities[5]->toArray(), $result['data'][5]);
-    }
-
-    public function test_userActivityForPeriod()
-    {
-        $user = factory(User::class)->create();
-        $now = Carbon::now();
-
-        Carbon::setTestNow($now->copy()->subDays(15));
-        factory(Activity::class)->times(5)->create(['user_id' => $user->id]);
-
-        Carbon::setTestNow($now->copy()->subDays(11));
-        factory(Activity::class)->times(2)->create(['user_id' => $user->id]);
-
-        Carbon::setTestNow($now->copy()->subDays(5));
-        factory(Activity::class)->times(3)->create(['user_id' => $user->id]);
-
-        Carbon::setTestNow($now->copy()->subDays(2));
-        factory(Activity::class)->times(2)->create(['user_id' => $user->id]);
-
-        Carbon::setTestNow(null);
-
-        $result = $this->repo->userActivityForPeriod(
-            $user->id, Carbon::now()->subWeeks(2), Carbon::now()
-        );
-
-        $this->assertEquals($result->get(Carbon::now()->subDays(14)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(13)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(12)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(11)->toDateString()), 2);
-        $this->assertEquals($result->get(Carbon::now()->subDays(10)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(9)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(8)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(7)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(6)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(5)->toDateString()), 3);
-        $this->assertEquals($result->get(Carbon::now()->subDays(4)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(3)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->subDays(2)->toDateString()), 2);
-        $this->assertEquals($result->get(Carbon::now()->subDays(1)->toDateString()), 0);
-        $this->assertEquals($result->get(Carbon::now()->toDateString()), 0);
-    }
-}
diff --git a/tests/functional/Repositories/Country/EloquentCountryTest.php b/tests/functional/Repositories/Country/EloquentCountryTest.php
deleted file mode 100644
index b9ab516..0000000
--- a/tests/functional/Repositories/Country/EloquentCountryTest.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-use Mockery as m;
-use Portal\Country;
-use Portal\Repositories\Country\EloquentCountry;
-
-class EloquentCountryTest extends FunctionalTestCase
-{
-    /**
-     * @var EloquentCountry
-     */
-    protected $repo;
-
-    protected $seed = false;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(EloquentCountry::class);
-    }
-
-    public function test_lists()
-    {
-        $countries = factory(Country::class)->times(8)->create();
-        $countries = $countries->sortBy(function ($country) {
-            return $country->name;
-        })->pluck('name', 'id');
-
-        $this->assertEquals($countries->toArray(), $this->repo->lists()->toArray());
-    }
-}
diff --git a/tests/functional/Repositories/Permission/EloquentPermissionTest.php b/tests/functional/Repositories/Permission/EloquentPermissionTest.php
deleted file mode 100644
index 65a5447..0000000
--- a/tests/functional/Repositories/Permission/EloquentPermissionTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-
-use Portal\Events\Permission\Created;
-use Portal\Permission;
-use Portal\Repositories\Permission\EloquentPermission;
-
-class EloquentPermissionTest extends FunctionalTestCase
-{
-    /**
-     * @var EloquentPermission
-     */
-    protected $repo;
-
-    protected $seed = false;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(EloquentPermission::class);
-    }
-
-    public function test_all()
-    {
-        $permissions = factory(Permission::class)->times(4)->create();
-
-        $this->assertEquals($permissions->toArray(), $this->repo->all()->toArray());
-    }
-
-    public function test_create()
-    {
-        $this->expectsEvents(Created::class);
-
-        $data = $this->getPermissionStubData();
-
-        $perm = $this->repo->create($data);
-
-        $this->seeInDatabase('permissions', $data + ['id' => $perm->id]);
-    }
-
-    public function test_update()
-    {
-        $this->expectsEvents(\Portal\Events\Permission\Updated::class);
-
-        Cache::put('foo', 'bar');
-
-        $data = $this->getPermissionStubData();
-
-        $perm = factory(Permission::class)->create();
-
-        $this->repo->update($perm->id, $data);
-
-        $this->seeInDatabase('permissions', $data + ['id' => $perm->id])
-            ->assertNull(Cache::get('foo'));
-    }
-
-    public function test_delete()
-    {
-        $this->expectsEvents(\Portal\Events\Permission\Deleted::class);
-
-        Cache::put('foo', 'bar');
-
-        $perm = factory(Permission::class)->create();
-
-        $this->repo->delete($perm->id);
-
-        $this->notSeeInDatabase('permissions', ['id' => $perm->id])
-            ->assertNull(Cache::get('foo'));
-    }
-
-    /**
-     * @return array
-     */
-    private function getPermissionStubData()
-    {
-        return [
-            'name'         => str_random(5),
-            'display_name' => str_random(5),
-            'description'  => 'foo',
-            'removable'    => true
-        ];
-    }
-}
diff --git a/tests/functional/Repositories/Role/EloquentRoleTest.php b/tests/functional/Repositories/Role/EloquentRoleTest.php
deleted file mode 100644
index 6e1a4be..0000000
--- a/tests/functional/Repositories/Role/EloquentRoleTest.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-use Mockery as m;
-use Portal\Events\Role\Created;
-use Portal\Repositories\Role\EloquentRole;
-use Portal\Role;
-use Portal\User;
-
-class EloquentRoleTest extends FunctionalTestCase
-{
-    /**
-     * @var EloquentRole
-     */
-    protected $repo;
-
-    protected $seed = false;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(EloquentRole::class);
-    }
-
-    public function test_all()
-    {
-        $roles = factory(Role::class)->times(4)->create();
-
-        $this->assertEquals($roles->toArray(), $this->repo->all()->toArray());
-    }
-
-    public function test_getAllWithUsersCount()
-    {
-        $roles = factory(Role::class)->times(4)->create();
-        $users = factory(User::class)->times(3)->create();
-
-        $this->setRoleForUser($users[0], $roles[0]->name);
-        $this->setRoleForUser($users[1], $roles[0]->name);
-        $this->setRoleForUser($users[2], $roles[1]->name);
-
-        $roles[0]->users_count = 2;
-        $roles[1]->users_count = 1;
-        $roles[2]->users_count = 0;
-        $roles[3]->users_count = 0;
-
-        $this->assertEquals($roles->toArray(), $this->repo->getAllWithUsersCount()->toArray());
-    }
-
-    public function test_create()
-    {
-        $this->expectsEvents(Created::class);
-
-        $data = ['name' => 'foo', 'display_name' => 'Foo'];
-        $role = $this->repo->create($data);
-
-        $this->seeInDatabase('roles', $data + ['id' => $role->id]);
-    }
-
-    public function test_update()
-    {
-        $this->expectsEvents(\Portal\Events\Role\Updated::class);
-
-        $role = factory(Role::class)->create();
-
-        $data = ['name' => 'foo', 'display_name' => 'Foo'];
-
-        $this->repo->update($role->id, $data);
-
-        $this->seeInDatabase('roles', $data + ['id' => $role->id]);
-    }
-
-    public function test_delete()
-    {
-        $this->expectsEvents(\Portal\Events\Role\Deleted::class);
-
-        $role = factory(Role::class)->create();
-
-        $this->repo->delete($role->id);
-
-        $this->dontSeeInDatabase('roles', ['id' => $role->id]);
-    }
-
-    public function test_updatePermissions()
-    {
-        $role = factory(Role::class)->create();
-        $permissions = factory(\Portal\Permission::class)->times(2)->create();
-
-        $this->repo->updatePermissions($role->id, $permissions->pluck('id')->toArray());
-
-        $this->seeInDatabase('permission_role', ['role_id' => $role->id, 'permission_id' => $permissions[0]->id]);
-        $this->seeInDatabase('permission_role', ['role_id' => $role->id, 'permission_id' => $permissions[1]->id]);
-    }
-
-    public function test_lists()
-    {
-        $roles = factory(Role::class)->times(4)->create();
-        $roles = $roles->pluck('name', 'id');
-
-        $this->assertEquals($roles->toArray(), $this->repo->lists()->toArray());
-    }
-}
diff --git a/tests/functional/Repositories/Session/DbSessionTest.php b/tests/functional/Repositories/Session/DbSessionTest.php
deleted file mode 100644
index 07f3508..0000000
--- a/tests/functional/Repositories/Session/DbSessionTest.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-use Carbon\Carbon;
-use Mockery as m;
-use Portal\Repositories\Session\DbSession;
-use Portal\User;
-
-class DbSessionTest extends FunctionalTestCase
-{
-    /**
-     * @var DbSession
-     */
-    protected $repo;
-
-    protected $seed = false;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(DbSession::class);
-    }
-
-    public function test_getUserSessions()
-    {
-        $user = factory(User::class)->create();
-
-        Carbon::setTestNow(Carbon::now());
-
-        $data1 = $this->getSessionStubData($user);
-        $data2 = $this->getSessionStubData($user);
-
-        DB::table('sessions')->insert($data1);
-        DB::table('sessions')->insert($data2);
-
-        $expected = collect([
-            (object) array_except($data1, ['payload', 'user_id']),
-            (object) array_except($data2, ['payload', 'user_id']),
-        ]);
-        $expected = $expected->sortBy('id')->keyBy('id')->toArray();
-
-        $actual = collect($this->repo->getUserSessions($user->id))
-            ->sortBy('id')
-            ->keyBy('id')
-            ->toArray();
-
-
-        $this->assertEquals($expected, $actual);
-    }
-
-    public function test_invalidateUserSession()
-    {
-        $user = factory(User::class)->create([
-            'remember_token' => str_random(60)
-        ]);
-
-        $data = $this->getSessionStubData($user);
-        DB::table('sessions')->insert($data);
-
-        $this->repo->invalidateUserSession($user->id, $data['id']);
-
-        $this->dontSeeInDatabase('sessions', $data)
-            ->seeInDatabase('users', ['remember_token' => null]);
-    }
-
-    private function getSessionStubData($user)
-    {
-        $faker = app(Faker\Generator::class);
-
-        return [
-            'id' => str_random(),
-            'user_id' => $user->id,
-            'ip_address' => $faker->ipv4,
-            'user_agent' => $faker->userAgent,
-            'payload' => 'foo',
-            'last_activity' => Carbon::now()->timestamp
-        ];
-    }
-}
diff --git a/tests/functional/Repositories/User/EloquentUserTest.php b/tests/functional/Repositories/User/EloquentUserTest.php
deleted file mode 100644
index 32edecf..0000000
--- a/tests/functional/Repositories/User/EloquentUserTest.php
+++ /dev/null
@@ -1,326 +0,0 @@
-<?php
-
-use Portal\Repositories\User\EloquentUser;
-use Portal\Role;
-use Portal\Support\Enum\UserStatus;
-use Portal\User;
-use Carbon\Carbon;
-use Mockery as m;
-
-class EloquentUserTest extends FunctionalTestCase
-{
-    /**
-     * @var EloquentUser
-     */
-    protected $repo;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->repo = app(EloquentUser::class);
-    }
-
-    public function test_find()
-    {
-        $user = factory(User::class)->create();
-
-        $this->assertArraySubset(
-            $user->toArray(),
-            $this->repo->find($user->id)->toArray()
-        );
-
-        $this->assertNull($this->repo->find(123));
-    }
-
-    public function test_findByEmail()
-    {
-        $user = factory(User::class)->create();
-
-        $this->assertArraySubset(
-            $user->toArray(),
-            $this->repo->findByEmail($user->email)->toArray()
-        );
-
-        $this->assertNull($this->repo->findByEmail('foo@bar.com'));
-    }
-
-    public function test_findBySocialId()
-    {
-        $user = factory(User::class)->create();
-
-        DB::table('social_logins')->insert([
-            'user_id' => $user->id,
-            'provider' => 'foo',
-            'provider_id' => '123',
-            'avatar' => '',
-            'created_at' => Carbon::now()
-        ]);
-
-        $this->assertArraySubset(
-            $user->toArray(),
-            $this->repo->findBySocialId('foo', '123')->toArray()
-        );
-
-        $this->assertNull($this->repo->findBySocialId('bar', '111'));
-    }
-
-    public function test_create()
-    {
-        $data = factory(User::class)->make()->toArray();
-
-        $this->repo->create($data + ['password' => 'foo']);
-
-        $this->seeInDatabase('users', $data);
-    }
-
-    public function test_associateSocialAccountForUser()
-    {
-        $user = factory(User::class)->create();
-
-        Carbon::setTestNow(Carbon::now());
-
-        $socialUser = new \Laravel\Socialite\One\User();
-        $socialUser->map(['id' => '123', 'avatar' => 'foo']);
-
-        $this->repo->associateSocialAccountForUser($user->id, 'facebook', $socialUser);
-
-        $this->seeInDatabase('social_logins', [
-            'user_id' => $user->id,
-            'provider' => 'facebook',
-            'provider_id' => '123',
-            'avatar' => 'foo',
-            'created_at' => Carbon::now()
-        ]);
-
-        Carbon::setTestNow(null);
-    }
-
-    public function test_paginate()
-    {
-        $users = factory(User::class)->times(5)->create();
-
-        $result = $this->repo->paginate(2)->toArray();
-
-        $this->assertEquals(2, count($result['data']));
-        $this->assertEquals(5, $result['total']);
-        $this->assertArraySubset($users[0]->toArray(), $result['data'][0]);
-        $this->assertArraySubset($users[1]->toArray(), $result['data'][1]);
-    }
-
-    public function test_paginate_with_status()
-    {
-        factory(User::class)->times(3)->create();
-        factory(User::class)->create(['status' => UserStatus::BANNED]);
-
-        $active = $this->repo->paginate(2, null, UserStatus::ACTIVE)->toArray();
-        $banned = $this->repo->paginate(2, null, UserStatus::BANNED)->toArray();
-
-        $this->assertEquals(2, count($active['data']));
-        $this->assertEquals(3, $active['total']);
-
-        $this->assertEquals(1, count($banned['data']));
-        $this->assertEquals(1, $banned['total']);
-    }
-
-    public function test_paginate_with_search()
-    {
-        factory(User::class)->create(['first_name' => 'John', 'last_name' => 'Doe', 'username' => 'jdoe', 'email' => 'joe@test.com']);
-        factory(User::class)->create(['first_name' => 'Jane', 'last_name' => 'Doe', 'username' => 'janedoe', 'email' => 'jane@doe.com']);
-        factory(User::class)->create(['first_name' => 'Milos', 'last_name' => 'Stojanovic', 'email' => 'test@test.com']);
-
-        $this->assertEquals(2, $this->repo->paginate(25, 'doe')->total());
-        $this->assertEquals(1, $this->repo->paginate(25, 'Milos')->total());
-        $this->assertEquals(2, $this->repo->paginate(25, 'test')->total());
-        $this->assertEquals(2, $this->repo->paginate(25, 'an')->total());
-    }
-
-    public function test_update()
-    {
-        $user = factory(User::class)->create();
-
-        $data = [
-            'first_name' => 'John',
-            'last_name' => 'Doe',
-            'username' => 'foo',
-            'email' => 'test@test.com'
-        ];
-
-        $this->repo->update($user->id, $data);
-
-        $this->seeInDatabase('users', $data + ['id' => $user->id]);
-    }
-
-    public function test_updateSocialNetworks()
-    {
-        $user = factory(User::class)->create();
-
-        $data = [
-            'facebook' => 'foo',
-            'twitter' => 'bar',
-            'dribbble' => 'bazz',
-            'skype' => 'skyyyype',
-            'linked_in' => 'li',
-            'google_plus' => 'g+'
-        ];
-
-        $this->repo->updateSocialNetworks($user->id, $data);
-
-        $this->seeInDatabase('user_social_networks', $data + ['user_id' => $user->id]);
-    }
-
-    public function test_delete()
-    {
-        $user = factory(User::class)->create();
-
-        $this->repo->delete($user->id);
-
-        $this->notSeeInDatabase('users', ['id' => $user->id]);
-    }
-
-    public function test_count()
-    {
-        factory(User::class)->times(7)->create();
-
-        $this->assertEquals(7, $this->repo->count());
-    }
-
-    public function test_newUsersCount()
-    {
-        Carbon::setTestNow(Carbon::now()->subMonth());
-        factory(User::class)->times(3)->create();
-
-        Carbon::setTestNow(null);
-        factory(User::class)->times(5)->create();
-
-        $this->assertEquals(5, $this->repo->newUsersCount());
-    }
-
-    public function test_countByStatus()
-    {
-        factory(User::class)->times(3)->create();
-        factory(User::class)->create(['status' => UserStatus::BANNED]);
-        factory(User::class)->times(2)->create(['status' => UserStatus::UNCONFIRMED]);
-
-        $this->assertEquals(3, $this->repo->countByStatus(UserStatus::ACTIVE));
-        $this->assertEquals(1, $this->repo->countByStatus(UserStatus::BANNED));
-        $this->assertEquals(2, $this->repo->countByStatus(UserStatus::UNCONFIRMED));
-    }
-
-    public function test_latest()
-    {
-        Carbon::setTestNow(Carbon::now()->subDay());
-        $user1 = factory(User::class)->create();
-
-        Carbon::setTestNow(null);
-        $users = factory(User::class)->times(3)->create();
-
-        $latestTwo = $this->repo->latest(2);
-        $latestFour = $this->repo->latest(4);
-
-        $this->assertEquals(2, count($latestTwo));
-        $this->assertEquals(4, count($latestFour));
-
-        $this->assertArraySubset($users[0]->toArray(), $latestTwo[0]->toArray());
-        $this->assertArraySubset($users[1]->toArray(), $latestTwo[1]->toArray());
-        $this->assertArraySubset($user1->toArray(), $latestFour[3]->toArray());
-    }
-
-    public function test_countOfNewUsersPerMonth()
-    {
-        Carbon::setTestNow(Carbon::now()->startOfYear());
-        factory(User::class)->times(2)->create();
-
-        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(2));
-        factory(User::class)->times(4)->create();
-
-        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(6));
-        factory(User::class)->times(2)->create();
-
-        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(7));
-        factory(User::class)->times(1)->create();
-
-        Carbon::setTestNow(Carbon::now()->startOfYear()->addMonths(10));
-        factory(User::class)->times(4)->create();
-
-        Carbon::setTestNow(null);
-
-        $expected = [
-            'January' => 2,
-            'February' => 0,
-            'March' => 4,
-            'April' => 0,
-            'May' => 0,
-            'June' => 0,
-            'July' => 2,
-            'August' => 1,
-            'September' => 0,
-            'October' => 0,
-            'November' => 4,
-            'December' => 0
-        ];
-
-        $usersPerMonth = $this->repo->countOfNewUsersPerMonth(
-            Carbon::now()->startOfYear(),
-            Carbon::now()->endOfYear()
-        );
-
-        $this->assertEquals($expected, $usersPerMonth);
-    }
-
-    public function test_getUsersWithRole()
-    {
-        $admins = factory(User::class)->times(2)->create();
-        $role = Role::where('name', 'Admin')->first();
-        $role->users()->attach($admins->pluck('id')->toArray());
-
-        $user = factory(User::class)->create();
-        $role = Role::where('name', 'User')->first();
-        $role->users()->attach($user->id);
-
-        $result = $this->repo->getUsersWithRole('Admin');
-        $this->assertEquals(2, $result->count());
-        $this->assertArraySubset($admins[0]->toArray(), $result[0]->toArray());
-        $this->assertArraySubset($admins[1]->toArray(), $result[1]->toArray());
-
-        $result = $this->repo->getUsersWithRole('User');
-        $this->assertEquals(1, $result->count());
-        $this->assertArraySubset($user->toArray(), $result[0]->toArray());
-    }
-
-    public function test_setRole()
-    {
-        $user = factory(User::class)->create();
-        $role = Role::where('name', 'Admin')->first();
-
-        $this->repo->setRole($user->id, $role->id);
-
-        $this->seeInDatabase('role_user', [
-           'role_id' => $role->id,
-            'user_id' => $user->id
-        ]);
-    }
-
-    public function test_switchRolesForUsers()
-    {
-        $role = Role::where('name', 'User')->first();
-        $roleAdmin = Role::where('name', 'Admin')->first();
-
-        $user1 = factory(User::class)->create();
-        $user2 = factory(User::class)->create();
-
-        $this->setRoleForUser($user1, 'User');
-        $this->setRoleForUser($user2, 'User');
-
-        $this->repo->switchRolesForUsers($role->id, $roleAdmin->id);
-
-        $this->seeInDatabase('role_user', [
-            'role_id' => $roleAdmin->id,
-            'user_id' => $user1->id
-        ]);
-
-        $this->seeInDatabase('role_user', [
-            'role_id' => $roleAdmin->id,
-            'user_id' => $user2->id
-        ]);
-    }
-}
diff --git a/tests/unit/Presenters/UserPresenterTest.php b/tests/unit/Presenters/UserPresenterTest.php
index 4b8c53f..c2089c2 100644
--- a/tests/unit/Presenters/UserPresenterTest.php
+++ b/tests/unit/Presenters/UserPresenterTest.php
@@ -1,5 +1,8 @@
 <?php
 
+namespace Tests\Unit\Presenters;
+
+use Tests\TestCase;
 use Portal\Presenters\UserPresenter;
 use Portal\Support\Enum\UserStatus;
 use Carbon\Carbon;
diff --git a/webpack.mix.js b/webpack.mix.js
new file mode 100644
index 0000000..bfa7da0
--- /dev/null
+++ b/webpack.mix.js
@@ -0,0 +1,15 @@
+const { mix } = require('laravel-mix');
+
+/*
+ |--------------------------------------------------------------------------
+ | Mix Asset Management
+ |--------------------------------------------------------------------------
+ |
+ | Mix provides a clean, fluent API for defining some Webpack build steps
+ | for your Laravel application. By default, we are compiling the Sass
+ | file for the application as well as bundling up all the JS files.
+ |
+ */
+
+// mix.js('resources/assets/js/app.js', 'public/js')
+//     .sass('resources/assets/sass/app.scss', 'public/css');
\ No newline at end of file
