diff --git a/core/composer.json b/core/composer.json
index 1eabf49..3e4ea8d 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -53,6 +53,7 @@
     "drupal/breakpoint": "self.version",
     "drupal/ckeditor": "self.version",
     "drupal/classy": "self.version",
+    "drupal/coffee": "self.version",
     "drupal/color": "self.version",
     "drupal/comment": "self.version",
     "drupal/config": "self.version",
diff --git a/core/modules/coffee/coffee.api.php b/core/modules/coffee/coffee.api.php
new file mode 100644
index 0000000..21cb1e4
--- /dev/null
+++ b/core/modules/coffee/coffee.api.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Hooks provided by Coffee module.
+ */
+
+use Drupal\Core\Url;
+use Drupal\views\Views;
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Extend the Coffee functionality with your own commands and items.
+ *
+ * Here's an example of how to add content to Coffee.
+ */
+function hook_coffee_commands() {
+  $commands = array();
+
+  // Basic example, for 1 result.
+  $commands[] = array(
+    'value' => Url::fromRoute('my.simple.route')->toString(),
+    'label' => 'Simple',
+    // Every result should include a command.
+    'command' => ':simple',
+  );
+
+  // More advanced example to include view results.
+  if ($view = Views::getView('frontpage')) {
+    $view->setDisplay();
+    $view->preExecute();
+    $view->execute();
+
+    foreach ($view->result as $row) {
+      $entity = $row->_entity;
+      $commands[] = array(
+        'value' => $entity->toUrl()->toString(),
+        'label' => 'Pub: ' . $entity->label(),
+        // You can also specify commands that if the user enters, this command
+        // should show.
+        'command' => ':x' . ' ' . $entity->label(),
+      );
+    }
+  }
+
+  return $commands;
+}
+
+/**
+ * @} End of "addtogroup hooks"
+ */
diff --git a/core/modules/coffee/coffee.coffee.inc b/core/modules/coffee/coffee.coffee.inc
new file mode 100644
index 0000000..388dd8a
--- /dev/null
+++ b/core/modules/coffee/coffee.coffee.inc
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * The hooks that are used by Coffee
+ * includes an example of hook_coffee_commands().
+ */
+
+use Drupal\Core\Url;
+
+/**
+ * Implements hook_coffee_commands().
+ */
+function coffee_coffee_commands() {
+  $commands = array();
+
+  // Add in a link for the front page.
+  $commands[] = array(
+    'value' => Url::fromRoute('<front>')->toString(),
+    'label' => t('Go to front page'),
+    'command' => ':front',
+  );
+
+  // The command is ":add" and includes the link_title to empower the
+  // autocompletion.
+  $command = ':add';
+  $entity_manager = \Drupal::entityTypeManager();
+  // Only use node types the user has access to.
+  foreach ($entity_manager->getStorage('node_type')->loadMultiple() as $type) {
+    $node_type = $type->id();
+    if ($entity_manager->getAccessControlHandler('node')->createAccess($node_type)) {
+      $commands[] = array(
+        'value' => Url::fromRoute('node.add', ['node_type' => $node_type])->toString(),
+        'label' => $type->label(),
+        'command' => $command . ' ' . $type->label(),
+      );
+    }
+  }
+
+  return $commands;
+}
diff --git a/core/modules/coffee/coffee.info.yml b/core/modules/coffee/coffee.info.yml
new file mode 100644
index 0000000..320e0b8
--- /dev/null
+++ b/core/modules/coffee/coffee.info.yml
@@ -0,0 +1,7 @@
+name: Coffee
+description: 'Provides an Alfred like search box to navigate within your site.'
+package: Core
+version: VERSION
+core: 8.x
+type: module
+configure: coffee.configuration
diff --git a/core/modules/coffee/coffee.libraries.yml b/core/modules/coffee/coffee.libraries.yml
new file mode 100644
index 0000000..54fa00c
--- /dev/null
+++ b/core/modules/coffee/coffee.libraries.yml
@@ -0,0 +1,17 @@
+drupal.coffee:
+  version: VERSION
+  js:
+    js/coffee.js: {}
+  css:
+    component:
+      css/coffee.css: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupalSettings
+    - core/jquery.once
+    - core/jquery.ui
+    - core/jquery.ui.autocomplete
+  jquery.ui.autocomplete:
+    version: 1.8.11
+    
\ No newline at end of file
diff --git a/core/modules/coffee/coffee.links.menu.yml b/core/modules/coffee/coffee.links.menu.yml
new file mode 100644
index 0000000..1f71c77
--- /dev/null
+++ b/core/modules/coffee/coffee.links.menu.yml
@@ -0,0 +1,5 @@
+coffee.configuration:
+  title: Coffee
+  description: 'Select what menus coffee should search.'
+  route_name: coffee.configuration
+  parent: system.admin_config_ui
diff --git a/core/modules/coffee/coffee.module b/core/modules/coffee/coffee.module
new file mode 100644
index 0000000..edfc52c
--- /dev/null
+++ b/core/modules/coffee/coffee.module
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Coffee primary module file.
+ */
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Url;
+
+/**
+ * Implements hook_page_attachments().
+ */
+function coffee_page_attachments(array &$attachments) {
+  if (\Drupal::currentUser()->hasPermission('access coffee')) {
+    $config = \Drupal::config('coffee.configuration');
+    $cache_tags = isset($attachments['#cache']['tags']) ? $attachments['#cache']['tags'] : [];
+    $attachments['#cache']['tags'] = Cache::mergeTags($cache_tags, $config->getCacheTags());
+
+    $attachments['#attached']['library'][] = 'coffee/drupal.coffee';
+    $attachments['#attached']['drupalSettings']['coffee'] = [
+      'maxResults' => $config->get('max_results'),
+    ];
+  }
+}
+
+
+/**
+ * Implements hook_hook_info().
+ */
+function coffee_hook_info() {
+  $hooks = array(
+    'coffee_commands' => array(
+      'group' => 'coffee',
+    ),
+  );
+
+  return $hooks;
+}
+
+/**
+ * Implements hook_toolbar().
+ */
+function coffee_toolbar() {
+  $items['coffee'] = [
+    '#cache' => [
+      'contexts' => ['user.permissions'],
+    ],
+  ];
+
+  if (\Drupal::currentUser()->hasPermission('access coffee')) {
+    $items['coffee'] += [
+      '#weight' => 999,
+      '#type' => 'toolbar_item',
+      'tab' => [
+        '#type' => 'link',
+        '#title' => t('Go to'),
+        '#url' => Url::fromRoute('<none>'),
+        '#attributes' => [
+          'title' => t('Use alt+d to start Coffee and search for a page to go to '),
+          'class' => ['toolbar-icon', 'toolbar-icon-coffee'],
+        ],
+      ],
+      '#attached' => [
+        'library' => ['coffee/drupal.coffee'],
+      ],
+    ];
+  }
+
+  return $items;
+}
diff --git a/core/modules/coffee/coffee.permissions.yml b/core/modules/coffee/coffee.permissions.yml
new file mode 100644
index 0000000..98a7d2f
--- /dev/null
+++ b/core/modules/coffee/coffee.permissions.yml
@@ -0,0 +1,7 @@
+access coffee:
+  title: 'Access Coffee'
+  description: 'Access the Coffee search box to navigate fast between admin pages'
+
+administer coffee:
+  title: 'Administer Coffee'
+  description: 'Administer the Coffee search module'
diff --git a/core/modules/coffee/coffee.routing.yml b/core/modules/coffee/coffee.routing.yml
new file mode 100644
index 0000000..368b8f9
--- /dev/null
+++ b/core/modules/coffee/coffee.routing.yml
@@ -0,0 +1,14 @@
+coffee.configuration:
+  path: '/admin/config/user-interface/coffee'
+  defaults: 
+    _form: 'Drupal\coffee\Form\CoffeeConfigurationForm'
+    _title: 'Coffee configuration'
+  requirements:
+    _permission: 'administer coffee'
+    
+coffee.get_data:
+  path: '/admin/coffee/get-data'
+  defaults:
+    _controller: 'Drupal\coffee\Controller\CoffeeController::coffeeData'
+  requirements:
+    _permission: 'access coffee'
diff --git a/core/modules/coffee/config/install/coffee.configuration.yml b/core/modules/coffee/config/install/coffee.configuration.yml
new file mode 100644
index 0000000..af6e3d6
--- /dev/null
+++ b/core/modules/coffee/config/install/coffee.configuration.yml
@@ -0,0 +1,3 @@
+coffee_menus:
+  admin: admin
+max_results: 7
diff --git a/core/modules/coffee/config/schema/coffee.schema.yml b/core/modules/coffee/config/schema/coffee.schema.yml
new file mode 100644
index 0000000..b8664dd
--- /dev/null
+++ b/core/modules/coffee/config/schema/coffee.schema.yml
@@ -0,0 +1,15 @@
+# Schema for the configuration files of the Coffee module.
+
+coffee.configuration:
+  type: config_object
+  label: 'Coffee settings'
+  mapping:
+    coffee_menus:
+      type: sequence
+      label: 'Coffee menus'
+      sequence:
+        - type: string
+          label: 'Menu'
+    max_results:
+      type: integer
+      label: 'Number of items to show in the search result'
diff --git a/core/modules/coffee/css/coffee.css b/core/modules/coffee/css/coffee.css
new file mode 100644
index 0000000..1842292
--- /dev/null
+++ b/core/modules/coffee/css/coffee.css
@@ -0,0 +1,177 @@
+/**
+ * @file
+ * Stylesheet for the Coffee module.
+ */
+[id^="coffee"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+#coffee-bg {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 999;
+}
+
+.coffee-form-wrapper{
+  pointer-events: none;
+  left: 0;
+  width: 100%;
+  position: fixed;
+  top: 20%;
+  z-index: 9999;
+}
+#coffee-form {
+  pointer-events: auto;
+  position:relative;
+  margin: 0 auto;
+  max-width: 500px;
+  width: 100%;
+  padding: 10px;
+  font: 16px/1.5 sans-serif;
+  background: black;
+  background: rgba(0, 0, 0, 0.4);
+  -webkit-border-radius: 15px;
+  -moz-border-radius: 15px;
+  -ms-border-radius: 15px;
+  -o-border-radius: 15px;
+  border-radius: 15px;
+  opacity: 1;
+  -webkit-transition: opacity 0.35s;
+  -moz-transition: opacity 0.35s;
+  -ms-transition: opacity 0.35s;
+  -o-transition: opacity 0.35s;
+  transition: opacity 0.35s false;
+}
+
+#coffee-form,
+#coffee-form input,
+#coffee-form a{
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.coffee-form-wrapper.hide-form {
+  position: absolute;
+  left: -100%;
+  opacity: 0;
+}
+
+#coffee-form-inner {
+  background: #fff;
+  color: #444;
+  padding: 10px 10px 1px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -ms-border-radius: 5px;
+  -o-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+  -moz-box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+  box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+}
+
+#coffee-q {
+  background: #d1d1d1;
+  color: #000;
+  border: 0;
+  font: 36px sans-serif;
+  line-height: 52px;
+  padding: 5px 10px;
+  width: 100%;
+  height: 52px;
+  outline: none;
+  display: block;
+  margin: 0 0 10px;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  -ms-border-radius: 0px;
+  -o-border-radius: 0px;
+  border-radius: 0px;
+}
+
+#coffee-q:focus {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+}
+
+#coffee-results ul {
+  position: static;
+  float: none;
+  list-style: none;
+  margin: 0;
+  padding: 10px 0 0;
+  border: 0;
+}
+
+#coffee-results li {
+  margin: 0;
+  padding: 0;
+  float: none;
+  clear: none;
+  width: auto;
+}
+
+#coffee-results a {
+  display: block;
+  border: 0;
+  outline: none;
+  color: #444;
+  padding: 6px 10px 4px;
+  line-height: normal;
+  font-size: 16px;
+  text-decoration: none;
+  height: auto;
+  -webkit-transition: none;
+  -moz-transition: none;
+  -ms-transition: none;
+  -o-transition: none;
+  transition: none;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  -ms-border-radius: 0px;
+  -o-border-radius: 0px;
+  border-radius: 0px;
+}
+
+#coffee-results a.ui-state-hover,
+#coffee-results a:focus,
+#coffee-results a:hover,
+#coffee-results .ui-state-focus {
+  background: #d1d1d1;
+  color: #000;
+  margin: 0;
+  cursor: pointer;
+}
+
+#coffee-results .description {
+  display: block;
+  font-size: 11px;
+  color: #888;
+}
+
+#coffee-results a.ui-state-hover .description {
+  color: #666;
+}
+
+#coffee-results .ui-widget {
+  font-family: sans-serif;
+}
+
+.toolbar .toolbar-bar .toolbar-icon-coffee:before,
+.toolbar .toolbar-bar .toolbar-icon-coffee.active:before {
+    background-image: url("../images/icons/bebebe/coffee.svg");
+}
+
+#coffee-q{
+    background-image: url("../images/icons/bebebe/coffee.svg");
+    background-position: right 10px center;
+    background-repeat: no-repeat;
+    background-size: 40px 40px;
+}
\ No newline at end of file
diff --git a/core/modules/coffee/images/icons/bebebe/coffee.svg b/core/modules/coffee/images/icons/bebebe/coffee.svg
new file mode 100644
index 0000000..4fdc71b
--- /dev/null
+++ b/core/modules/coffee/images/icons/bebebe/coffee.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   width="100%"
+   height="100%"
+   viewBox="1032.521 383.365 19.587 15.987"
+   id="svg3771"
+   xml:space="preserve"><metadata
+   id="metadata2992"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs2990" />
+
+<path
+   d="m 1051.478,395.161 -3.239,-1.769 c 0.911,-3.47 -0.606,-7.258 -3.892,-9.052 -3.866,-2.111 -8.74,-0.681 -10.851,3.185 -2.111,3.866 -0.68,8.74 3.187,10.851 3.286,1.794 7.292,1.022 9.719,-1.621 l 3.239,1.769 c 0.587,0.32 1.322,0.104 1.642,-0.482 l 0.677,-1.239 c 0.32,-0.586 0.104,-1.321 -0.482,-1.642 z m -13.898,1.573 c -2.979,-1.626 -4.067,-5.332 -2.44,-8.31 1.626,-2.978 5.332,-4.066 8.31,-2.44 2.978,1.626 4.066,5.332 2.44,8.31 -1.626,2.978 -5.332,4.066 -8.31,2.44 z"
+   id="path2987"
+   style="fill:#bebebe;fill-opacity:1" />
+<path
+   d="m 1041.145,395.407 c -0.845,0.341 -1.682,0.414 -2.246,0.23 -0.555,-0.154 -0.652,-0.321 -0.695,-0.521 -0.056,-0.327 0.314,-0.875 1.385,-2.052 0.507,-0.557 1.52,-1.916 2.252,-3.019 1.469,-2.215 1.633,-2.334 2.17,-1.581 0.649,0.91 0.536,3.189 -0.355,4.619 -0.574,0.921 -1.617,1.963 -2.511,2.324 l 0,0 z m -3.722,-0.634 c -0.156,-0.056 -0.335,-0.283 -0.465,-0.59 -0.743,-1.749 0.101,-4.585 1.777,-5.977 1.236,-1.027 3.202,-1.461 3.912,-0.865 0.48,0.403 0.285,0.817 -1.186,2.512 -0.736,0.848 -1.794,2.267 -2.352,3.152 -1.067,1.696 -1.276,1.915 -1.686,1.768 l 0,0 z"
+   id="path4161-1-1-4-3-5-7-53-4-4-1-5_1_"
+   style="fill:#bebebe;fill-opacity:1" />
+</svg>
\ No newline at end of file
diff --git a/core/modules/coffee/images/icons/ffffff/coffee.svg b/core/modules/coffee/images/icons/ffffff/coffee.svg
new file mode 100644
index 0000000..5971457
--- /dev/null
+++ b/core/modules/coffee/images/icons/ffffff/coffee.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   width="100%"
+   height="100%"
+   viewBox="1032.521 383.365 19.587 15.987"
+   id="svg3771"
+   xml:space="preserve"><metadata
+   id="metadata2992"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs2990" />
+
+<path
+   d="m 1051.478,395.161 -3.239,-1.769 c 0.911,-3.47 -0.606,-7.258 -3.892,-9.052 -3.866,-2.111 -8.74,-0.681 -10.851,3.185 -2.111,3.866 -0.68,8.74 3.187,10.851 3.286,1.794 7.292,1.022 9.719,-1.621 l 3.239,1.769 c 0.587,0.32 1.322,0.104 1.642,-0.482 l 0.677,-1.239 c 0.32,-0.586 0.104,-1.321 -0.482,-1.642 z m -13.898,1.573 c -2.979,-1.626 -4.067,-5.332 -2.44,-8.31 1.626,-2.978 5.332,-4.066 8.31,-2.44 2.978,1.626 4.066,5.332 2.44,8.31 -1.626,2.978 -5.332,4.066 -8.31,2.44 z"
+   id="path2987"
+   style="fill:#ffffff;fill-opacity:1" />
+<path
+   d="m 1041.145,395.407 c -0.845,0.341 -1.682,0.414 -2.246,0.23 -0.555,-0.154 -0.652,-0.321 -0.695,-0.521 -0.056,-0.327 0.314,-0.875 1.385,-2.052 0.507,-0.557 1.52,-1.916 2.252,-3.019 1.469,-2.215 1.633,-2.334 2.17,-1.581 0.649,0.91 0.536,3.189 -0.355,4.619 -0.574,0.921 -1.617,1.963 -2.511,2.324 l 0,0 z m -3.722,-0.634 c -0.156,-0.056 -0.335,-0.283 -0.465,-0.59 -0.743,-1.749 0.101,-4.585 1.777,-5.977 1.236,-1.027 3.202,-1.461 3.912,-0.865 0.48,0.403 0.285,0.817 -1.186,2.512 -0.736,0.848 -1.794,2.267 -2.352,3.152 -1.067,1.696 -1.276,1.915 -1.686,1.768 l 0,0 z"
+   id="path4161-1-1-4-3-5-7-53-4-4-1-5_1_"
+   style="fill:#ffffff;fill-opacity:1" />
+</svg>
\ No newline at end of file
diff --git a/core/modules/coffee/js/coffee.js b/core/modules/coffee/js/coffee.js
new file mode 100644
index 0000000..2d59d2b
--- /dev/null
+++ b/core/modules/coffee/js/coffee.js
@@ -0,0 +1,202 @@
+/**
+ * @file
+ * JavaScript file for the Coffee module.
+ */
+
+(function ($, Drupal, drupalSettings, DrupalCoffee) {
+  // Remap the filter functions for autocomplete to recognise the
+  // extra value "command".
+  var proto = $.ui.autocomplete.prototype,
+    initSource = proto._initSource;
+
+  function filter(array, term) {
+    var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), 'i');
+    return $.grep(array, function (value) {
+      return matcher.test(value.command) || matcher.test(value.label) || matcher.test(value.value);
+    });
+  }
+
+  $.extend(proto, {
+    _initSource: function () {
+      if ($.isArray(this.options.source)) {
+        this.source = function (request, response) {
+          response(filter(this.options.source, request.term));
+        };
+      }
+      else {
+        initSource.call(this);
+      }
+    }
+  });
+
+  DrupalCoffee = DrupalCoffee || {};
+
+  Drupal.behaviors.coffee = {
+    attach: function () {
+      $('body').once('coffee').each(function () {
+        var body = $(this);
+        DrupalCoffee.bg.appendTo(body).hide();
+        DrupalCoffee.wrapper.appendTo('body').addClass('hide-form');
+        DrupalCoffee.form
+          .append(DrupalCoffee.label)
+          .append(DrupalCoffee.field)
+          .append(DrupalCoffee.results)
+          .wrapInner('<div id="coffee-form-inner" />')
+          .appendTo(DrupalCoffee.wrapper);
+
+        // Load autocomplete data set, consider implementing
+        // caching with local storage.
+        DrupalCoffee.dataset = [];
+        DrupalCoffee.isItemSelected = false;
+
+        var autocomplete_data_element = 'ui-autocomplete';
+
+        $.ajax({
+          url: Drupal.url('admin/coffee/get-data'),
+          dataType: 'json',
+          success: function (data) {
+            DrupalCoffee.dataset = data;
+
+            // Apply autocomplete plugin on show
+            var $autocomplete = $(DrupalCoffee.field).autocomplete({
+              source: DrupalCoffee.dataset,
+              focus: function (event, ui) {
+                // Prevents replacing the value of the input field
+                DrupalCoffee.isItemSelected = true;
+                event.preventDefault();
+              },
+              'change': function(event, ui) {
+                DrupalCoffee.isItemSelected = false;
+              },
+              select: function (event, ui) {
+                DrupalCoffee.redirect(ui.item.value, event.metaKey);
+                event.preventDefault();
+                return false;
+              },
+              delay: 0,
+              appendTo: DrupalCoffee.results
+            });
+
+            $autocomplete.data(autocomplete_data_element)._renderItem = function (ul, item) {
+              // strip the basePath when displaying the link description
+              var description = item.value;
+              if(item.value.indexOf(drupalSettings.path.basePath) === 0){
+                  description = item.value.substring(drupalSettings.path.basePath.length);
+              }
+              return  $('<li></li>')
+                .data('item.autocomplete', item)
+                .append('<a>' + item.label + '<small class="description">' + description + '</small></a>')
+                .appendTo(ul);
+            };
+
+            // We want to limit the number of results.
+            $(DrupalCoffee.field).data(autocomplete_data_element)._renderMenu = function (ul, items) {
+              var self = this;
+              items = items.slice(0, drupalSettings.coffee.maxResults);
+              $.each(items, function (index, item) {
+                self._renderItemData(ul, item);
+              });
+            };
+
+            DrupalCoffee.form.keydown(function(event) {
+              if (event.keyCode == 13) {
+                var openInNewWindow = false;
+
+                if (event.metaKey) {
+                  openInNewWindow = true;
+                }
+
+                if (!DrupalCoffee.isItemSelected) {
+                    var $firstItem = $(DrupalCoffee.results).find('li:first').data('item.autocomplete');
+                    if (typeof $firstItem === 'object') {
+                        DrupalCoffee.redirect($firstItem.value, openInNewWindow);
+                        event.preventDefault();
+                    }
+                }
+              }
+            });
+          },
+          error: function () {
+            DrupalCoffee.field.val('Could not load data, please refresh the page');
+          }
+        });
+
+        $('.toolbar-icon-coffee').click(function(event) {
+            event.preventDefault();
+            DrupalCoffee.coffee_show();
+        });
+        // Key events
+        $(document).keydown(function (event) {
+
+          // Show the form with alt + D. Use 2 keycodes as 'D' can be uppercase or lowercase.
+          if (DrupalCoffee.wrapper.hasClass('hide-form') &&
+            event.altKey === true &&
+              // 68/206 = d/D, 75 = k.
+            (event.keyCode === 68 || event.keyCode === 206 || event.keyCode === 75)) {
+            DrupalCoffee.coffee_show();
+            event.preventDefault();
+          }
+          // Close the form with esc or alt + D.
+          else {
+            if (!DrupalCoffee.wrapper.hasClass('hide-form') && (event.keyCode === 27 || (event.altKey === true && (event.keyCode === 68 || event.keyCode === 206)))) {
+              DrupalCoffee.coffee_close();
+              event.preventDefault();
+            }
+          }
+        });
+      });
+    }
+  };
+
+  // Prefix the open and close functions to avoid
+  // conflicts with autocomplete plugin.
+
+  /**
+   * Open the form and focus on the search field.
+   */
+  DrupalCoffee.coffee_show = function () {
+    DrupalCoffee.wrapper.removeClass('hide-form');
+    DrupalCoffee.bg.show();
+    DrupalCoffee.field.focus();
+    $(DrupalCoffee.field).autocomplete({enable: true});
+  };
+
+  /**
+   * Close the form and destroy all data.
+   */
+  DrupalCoffee.coffee_close = function () {
+    DrupalCoffee.field.val('');
+    //DrupalCoffee.results.empty();
+    DrupalCoffee.wrapper.addClass('hide-form');
+    DrupalCoffee.bg.hide();
+    $(DrupalCoffee.field).autocomplete({enable: false});
+  };
+
+  /**
+   * Close the Coffee form and redirect.
+   */
+  DrupalCoffee.redirect = function (path, openInNewWindow) {
+    DrupalCoffee.coffee_close();
+
+    if (openInNewWindow) {
+      window.open(path);
+    }
+    else {
+      document.location = path;
+    }
+  };
+
+  /**
+   * The HTML elements.
+   */
+  DrupalCoffee.label = $('<label for="coffee-q" class="hidden" />').text(Drupal.t('Query', '', ''));
+  DrupalCoffee.results = $('<div id="coffee-results" />');
+  DrupalCoffee.wrapper = $('<div class="coffee-form-wrapper" />');
+  DrupalCoffee.form = $('<form id="coffee-form" action="#" />');
+  DrupalCoffee.bg = $('<div id="coffee-bg" />').click(function () {
+    DrupalCoffee.coffee_close();
+  });
+
+  DrupalCoffee.field = $('<input id="coffee-q" type="text" autocomplete="off" />');
+
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/coffee/src/Controller/CoffeeController.php b/core/modules/coffee/src/Controller/CoffeeController.php
new file mode 100644
index 0000000..7bf7029
--- /dev/null
+++ b/core/modules/coffee/src/Controller/CoffeeController.php
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\coffee\Controller\CoffeeController.
+ */
+
+namespace Drupal\coffee\Controller;
+
+use Drupal\Core\Access\AccessManagerInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Menu\LocalTaskManagerInterface;
+use Drupal\Core\Menu\MenuLinkTreeInterface;
+use Drupal\Core\Menu\MenuTreeParameters;
+use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+/**
+ * Provides route responses for coffee.module.
+ */
+class CoffeeController extends ControllerBase {
+
+  /**
+   * The coffee config.
+   *
+   * @var \Drupal\Core\Config\ImmutableConfig
+   */
+  protected $config;
+
+  /**
+   * The menu link tree service.
+   *
+   * @var \Drupal\Core\Menu\MenuLinkTreeInterface
+   */
+  protected $menuLinkTree;
+
+  /**
+   * The local task manager service.
+   *
+   * @var \Drupal\Core\Menu\LocalTaskManagerInterface
+   */
+  protected $localTaskManager;
+
+  /**
+   * The access manager service.
+   *
+   * @var \Drupal\Core\Access\AccessManagerInterface
+   */
+  protected $accessManager;
+
+  /**
+   * Constructs a new CoffeeController object.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_link_tree
+   *   The menu link tree service.
+   * @param \Drupal\Core\Menu\LocalTaskManagerInterface $local_task_manager
+   *   The local task manager service.
+   * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
+   *   The access manager service.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory, MenuLinkTreeInterface $menu_link_tree, LocalTaskManagerInterface $local_task_manager, AccessManagerInterface $access_manager) {
+    $this->config = $config_factory->get('coffee.configuration');
+    $this->menuLinkTree = $menu_link_tree;
+    $this->localTaskManager = $local_task_manager;
+    $this->accessManager = $access_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('config.factory'),
+      $container->get('menu.link_tree'),
+      $container->get('plugin.manager.menu.local_task'),
+      $container->get('access_manager')
+    );
+  }
+
+  /**
+   * Outputs the data that is used for the Coffee autocompletion in JSON.
+   *
+   * @return \Symfony\Component\HttpFoundation\JsonResponse
+   *   The json response.
+   */
+  public function coffeeData() {
+    $output = array();
+
+    foreach ($this->config->get('coffee_menus') as $menu_name) {
+      $tree = $this->getMenuTreeElements($menu_name);
+
+      foreach ($tree as $tree_element) {
+        $link = $tree_element->link;
+
+        $output[$link->getRouteName()] = array(
+          'value' => $link->getUrlObject()->toString(),
+          'label' => $link->getTitle(),
+          'command' => $menu_name == 'user-menu' ? ':user' : NULL,
+        );
+
+        $tasks = $this->getLocalTasksForRoute($link->getRouteName(), $link->getRouteParameters());
+
+        foreach ($tasks as $route_name => $task) {
+          if (empty($output[$route_name])) {
+            $output[$route_name] = array(
+              'value' => $task['url']->toString(),
+              'label' => $link->getTitle() . ' - ' . $task['title'],
+              'command' => NULL,
+            );
+          }
+        }
+      }
+    }
+
+    $commands = $this->moduleHandler()->invokeAll('coffee_commands');
+
+    if (!empty($commands)) {
+      $output = array_merge($output, $commands);
+    }
+
+    // Re-index the array.
+    $output = array_values($output);
+
+    return new JsonResponse($output);
+  }
+
+  /**
+   * Retrieves the menu tree elements for the given menu.
+   *
+   * Every element returned by this method is already access checked.
+   *
+   * @param string $menu_name
+   *   The menu name.
+   *
+   * @return \Drupal\Core\Menu\MenuLinkTreeElement[]
+   *   A flatten array of menu link tree elements for the given menu.
+   */
+  protected function getMenuTreeElements($menu_name) {
+    $parameters = new MenuTreeParameters();
+    $tree = $this->menuLinkTree->load($menu_name, $parameters);
+
+    $manipulators = [
+      ['callable' => 'menu.default_tree_manipulators:checkNodeAccess'],
+      ['callable' => 'menu.default_tree_manipulators:checkAccess'],
+      ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
+      ['callable' => 'menu.default_tree_manipulators:flatten'],
+    ];
+    $tree = $this->menuLinkTree->transform($tree, $manipulators);
+
+    // Top-level inaccessible links are *not* removed; it is up
+    // to the code doing something with the tree to exclude inaccessible links.
+    // @see menu.default_tree_manipulators:checkAccess
+    foreach ($tree as $key => $element) {
+      if (!$element->access->isAllowed()) {
+        unset($tree[$key]);
+      }
+    }
+
+    return $tree;
+  }
+
+  /**
+   * Retrieve all the local tasks for a given route.
+   *
+   * Every element returned by this method is already access checked.
+   *
+   * @param string $route_name
+   *   The route name for which find the local tasks.
+   * @param array $route_parameters
+   *   The route parameters.
+   *
+   * @return array
+   *   A flatten array that contains the local tasks for the given route.
+   *   Each element in the array is keyed by the route name associated with
+   *   the local tasks and contains:
+   *     - title: the title of the local task.
+   *     - url: the url object for the local task.
+   *     - localized_options: the localized options for the local task.
+   */
+  protected function getLocalTasksForRoute($route_name, array $route_parameters) {
+    $links = array();
+
+    $tree = $this->localTaskManager->getLocalTasksForRoute($route_name);
+    $route_match = \Drupal::routeMatch();
+
+    foreach ($tree as $level => $instances) {
+      /** @var $instances \Drupal\Core\Menu\LocalTaskInterface[] */
+      foreach ($instances as $plugin_id => $child) {
+        $child_route_name = $child->getRouteName();
+        // Merges the parent's route parameter with the child ones since you
+        // calculate the local tasks outside of parent route context.
+        $child_route_parameters = $child->getRouteParameters($route_match) + $route_parameters;
+
+        if ($this->accessManager->checkNamedRoute($child_route_name, $child_route_parameters)) {
+          $links[$child_route_name] = [
+            'title' => $child->getTitle(),
+            'url' => Url::fromRoute($child_route_name, $child_route_parameters),
+            'localized_options' => $child->getOptions($route_match),
+          ];
+        }
+      }
+    }
+
+    return $links;
+  }
+
+}
diff --git a/core/modules/coffee/src/Form/CoffeeConfigurationForm.php b/core/modules/coffee/src/Form/CoffeeConfigurationForm.php
new file mode 100644
index 0000000..0950783
--- /dev/null
+++ b/core/modules/coffee/src/Form/CoffeeConfigurationForm.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\coffee\Form\CoffeeConfigurationForm.
+ */
+
+namespace Drupal\coffee\Form;
+
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\system\Entity\Menu;
+
+/**
+ * Configure Coffee for this site.
+ */
+class CoffeeConfigurationForm extends ConfigFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'coffee_configuration_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return [
+      'coffee.configuration',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $config = $this->config('coffee.configuration');
+
+    $form['coffee_menus'] = [
+      '#type' => 'checkboxes',
+      '#title' => $this->t('Menus to include'),
+      '#description' => $this->t('Select the menus that should be used by Coffee to search.'),
+      '#options' => $this->getMenuLabels(),
+      '#default_value' => $config->get('coffee_menus'),
+    ];
+
+    $form['max_results'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Max results'),
+      '#description' => $this->t('Maximum number of items to show in the search results.'),
+      '#default_value' => $config->get('max_results'),
+      '#required' => TRUE,
+      '#min' => 1,
+      '#max' => 50,
+    ];
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $values = $form_state->getValues();
+    $this->config('coffee.configuration')
+      ->set('coffee_menus', array_filter($values['coffee_menus']))
+      ->set('max_results', $values['max_results'])
+      ->save();
+
+    parent::submitForm($form, $form_state);
+  }
+
+  /**
+   * Return an associative array of menus names.
+   *
+   * @return array
+   *   An array with the machine-readable names as the keys, and human-readable
+   *   titles as the values.
+   */
+  protected function getMenuLabels() {
+    $menus = [];
+    foreach (Menu::loadMultiple() as $menu_name => $menu) {
+      $menus[$menu_name] = $menu->label();
+    }
+    asort($menus);
+
+    return $menus;
+  }
+
+}
diff --git a/core/modules/coffee/src/Tests/CoffeeHookCoffeeCommandsTest.php b/core/modules/coffee/src/Tests/CoffeeHookCoffeeCommandsTest.php
new file mode 100644
index 0000000..1d36d5d
--- /dev/null
+++ b/core/modules/coffee/src/Tests/CoffeeHookCoffeeCommandsTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\coffee\Tests\CoffeeHookCoffeeCommandsTest.
+ */
+
+namespace Drupal\coffee\Tests;
+
+use Drupal\Core\Url;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests hook_coffee_commands().
+ *
+ * @group coffee
+ */
+class CoffeeHookCoffeeCommandsTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['coffee', 'coffee_test', 'node'];
+
+  /**
+   * The user for tests.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $coffeeUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->coffeeUser = $this->drupalCreateUser(['access coffee']);
+  }
+
+  /**
+   * Tests hook_coffee_commands().
+   */
+  public function testHookCoffeeCommands() {
+    $expected = [
+      'value' => Url::fromRoute('<front>')->toString(),
+      'label' => t('Coffee hook fired!'),
+      'command' => ':test',
+    ];
+
+    $expected_coffee = [
+      'value' => Url::fromRoute('<front>')->toString(),
+      'label' => t('Go to front page'),
+      'command' => ':front',
+    ];
+
+    $commands = \Drupal::moduleHandler()->invokeAll('coffee_commands');
+    $this->assertTrue(in_array($expected, $commands), 'coffee_test_coffee_commands() was executed properly invoking the hook_coffe_commands() manually.');
+    $this->assertTrue(in_array($expected_coffee, $commands), 'coffee_coffee_commands() was executed properly invoking the hook_coffe_commands() manually.');
+
+    $this->drupalLogin($this->coffeeUser);
+    $commands = $this->drupalGetJSON('admin/coffee/get-data');
+    $this->assertResponse(200);
+    $this->assertTrue(in_array($expected, $commands), 'coffee_test_coffee_commands() was executed invoking hook_coffe_commands() in CoffeeController.');
+    $this->assertTrue(in_array($expected_coffee, $commands), 'coffee_coffee_commands() was executed invoking hook_coffe_commands() in CoffeeController.');
+  }
+
+}
diff --git a/core/modules/coffee/src/Tests/CoffeeTest.php b/core/modules/coffee/src/Tests/CoffeeTest.php
new file mode 100644
index 0000000..c0b3d06
--- /dev/null
+++ b/core/modules/coffee/src/Tests/CoffeeTest.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\coffee\Tests\CoffeeTest.
+ */
+
+namespace Drupal\coffee\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests Coffee module functionality.
+ *
+ * @group coffee
+ */
+class CoffeeTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['coffee'];
+
+  /**
+   * The user for tests.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $webUser;
+
+  /**
+   * The user for tests.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $coffeeUser;
+
+  /**
+   * The user for tests.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $coffeeAdmin;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp(){
+    parent::setUp();
+
+    $this->webUser = $this->drupalCreateUser();
+    $this->coffeeUser = $this->drupalCreateUser(['access coffee']);
+    $this->coffeeAdmin = $this->drupalCreateUser(['administer coffee']);
+  }
+
+  /**
+   * Tests coffee configuration form.
+   */
+  public function testCoffeeConfiguration() {
+    $this->drupalGet('admin/config/user-interface/coffee');
+    $this->assertResponse(403);
+
+    $this->drupalLogin($this->coffeeAdmin);
+    $this->drupalGet('admin/config/user-interface/coffee');
+    $this->assertResponse(200);
+    $this->assertFieldChecked('edit-coffee-menus-admin', 'The admin menu is enabled by default');
+    $this->assertFieldById('edit-max-results', 7, 'The max results is 7 by default');
+
+    $edit = [
+      'coffee_menus[tools]' => 'tools',
+      'coffee_menus[account]' => 'account',
+      'max_results' => 15,
+    ];
+    $this->drupalPostForm('admin/config/user-interface/coffee', $edit, t('Save configuration'));
+    $this->assertText(t('The configuration options have been saved.'));
+
+    $expected = [
+      'admin' => 'admin',
+      'tools' => 'tools',
+      'account' => 'account'
+    ];
+    $config = \Drupal::config('coffee.configuration')->get('coffee_menus');
+    $this->assertEqual($expected, $config, 'The configuration options have been properly saved');
+
+    $config = \Drupal::config('coffee.configuration')->get('max_results');
+    $this->assertEqual(15, $config, 'The configuration options have been properly saved');
+  }
+
+  /**
+   * Tests coffee configuration cache tags invalidation.
+   */
+  public function testCoffeeCacheTagsInvalidation() {
+    // Coffee is not loaded for users without the adequate permission,
+    // so no cache tags for coffee configuration are added.
+    $this->drupalGet('');
+    $this->assertNoCacheTag('config:coffee.configuration');
+
+    // Make sure that the coffee configuration cache tags are present
+    // for users with the adequate permission.
+    $this->drupalLogin($this->coffeeUser);
+    $this->drupalGet('');
+    $this->assertCacheTag('config:coffee.configuration');
+    $settings = $this->getDrupalSettings();
+    $this->assertEqual(7, $settings['coffee']['maxResults']);
+
+    // Trigger a config save which should clear the page cache, so we should get
+    // the fresh configuration settings.
+    $max_results = 10;
+    $this->config('coffee.configuration')
+      ->set('max_results', $max_results)
+      ->save();
+
+    $this->drupalGet('');
+    $this->assertCacheTag('config:coffee.configuration');
+    $settings = $this->getDrupalSettings();
+    $this->assertEqual($max_results, $settings['coffee']['maxResults']);
+  }
+
+  /**
+   * Tests that the coffee assets are loaded properly.
+   */
+  public function testCoffeeAssets() {
+    // Ensure that the coffee assets are not loaded for users without the
+    // adequate permission.
+    $this->drupalGet('');
+    $this->assertNoRaw('modules/coffee/js/coffee.js');
+
+    // Ensure that the coffee assets are loaded properly for users with the
+    // adequate permission.
+    $this->drupalLogin($this->coffeeUser);
+    $this->drupalGet('');
+    $this->assertRaw('modules/coffee/js/coffee.js');
+
+    // Ensure that the coffee assets are not loaded for users without the
+    // adequate permission.
+    $this->drupalLogin($this->webUser);
+    $this->drupalGet('');
+    $this->assertNoRaw('modules/coffee/js/coffee.js');
+  }
+
+  /**
+   * Tests that the toolbar integration works properly.
+   */
+  public function testCoffeeToolbarIntegration() {
+    \Drupal::service('module_installer')->install(['toolbar']);
+    $tab_xpath = '//nav[@id="toolbar-bar"]//div/a[contains(@class, "toolbar-icon-coffee")]';
+
+    $toolbar_user = $this->drupalCreateUser(['access toolbar']);
+    $this->drupalLogin($toolbar_user);
+    $this->assertRaw('id="toolbar-administration"');
+    $this->assertFalse($this->xpath($tab_xpath), 'Not found the Coffee toolbar tab.');
+
+    $coffee_toolbar_user = $this->drupalCreateUser(['access toolbar', 'access coffee']);
+    $this->drupalLogin($coffee_toolbar_user);
+    $this->assertRaw('id="toolbar-administration"');
+    $this->assertEqual(count($this->xpath($tab_xpath)), 1, 'Found the Coffee toolbar tab.');
+  }
+
+}
diff --git a/core/modules/coffee/tests/modules/coffee_test/coffee_test.info.yml b/core/modules/coffee/tests/modules/coffee_test/coffee_test.info.yml
new file mode 100644
index 0000000..b24a00c
--- /dev/null
+++ b/core/modules/coffee/tests/modules/coffee_test/coffee_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Coffee module tests'
+type: module
+description: 'Support module for coffee testing.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/coffee/tests/modules/coffee_test/coffee_test.module b/core/modules/coffee/tests/modules/coffee_test/coffee_test.module
new file mode 100644
index 0000000..e13423c
--- /dev/null
+++ b/core/modules/coffee/tests/modules/coffee_test/coffee_test.module
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * A test module for test the coffee module.
+ */
+
+use Drupal\Core\Url;
+
+/**
+ * Implements hook_coffee_commands().
+ */
+function coffee_test_coffee_commands() {
+  $commands[] = [
+    'value' => Url::fromRoute('<front>')->toString(),
+    'label' => t('Coffee hook fired!'),
+    'command' => ':test',
+  ];
+
+  return $commands;
+}
diff --git a/core/themes/stable/css/coffee/coffee.css b/core/themes/stable/css/coffee/coffee.css
new file mode 100644
index 0000000..1842292
--- /dev/null
+++ b/core/themes/stable/css/coffee/coffee.css
@@ -0,0 +1,177 @@
+/**
+ * @file
+ * Stylesheet for the Coffee module.
+ */
+[id^="coffee"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+#coffee-bg {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 999;
+}
+
+.coffee-form-wrapper{
+  pointer-events: none;
+  left: 0;
+  width: 100%;
+  position: fixed;
+  top: 20%;
+  z-index: 9999;
+}
+#coffee-form {
+  pointer-events: auto;
+  position:relative;
+  margin: 0 auto;
+  max-width: 500px;
+  width: 100%;
+  padding: 10px;
+  font: 16px/1.5 sans-serif;
+  background: black;
+  background: rgba(0, 0, 0, 0.4);
+  -webkit-border-radius: 15px;
+  -moz-border-radius: 15px;
+  -ms-border-radius: 15px;
+  -o-border-radius: 15px;
+  border-radius: 15px;
+  opacity: 1;
+  -webkit-transition: opacity 0.35s;
+  -moz-transition: opacity 0.35s;
+  -ms-transition: opacity 0.35s;
+  -o-transition: opacity 0.35s;
+  transition: opacity 0.35s false;
+}
+
+#coffee-form,
+#coffee-form input,
+#coffee-form a{
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.coffee-form-wrapper.hide-form {
+  position: absolute;
+  left: -100%;
+  opacity: 0;
+}
+
+#coffee-form-inner {
+  background: #fff;
+  color: #444;
+  padding: 10px 10px 1px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -ms-border-radius: 5px;
+  -o-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+  -moz-box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+  box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.6);
+}
+
+#coffee-q {
+  background: #d1d1d1;
+  color: #000;
+  border: 0;
+  font: 36px sans-serif;
+  line-height: 52px;
+  padding: 5px 10px;
+  width: 100%;
+  height: 52px;
+  outline: none;
+  display: block;
+  margin: 0 0 10px;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  -ms-border-radius: 0px;
+  -o-border-radius: 0px;
+  border-radius: 0px;
+}
+
+#coffee-q:focus {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+}
+
+#coffee-results ul {
+  position: static;
+  float: none;
+  list-style: none;
+  margin: 0;
+  padding: 10px 0 0;
+  border: 0;
+}
+
+#coffee-results li {
+  margin: 0;
+  padding: 0;
+  float: none;
+  clear: none;
+  width: auto;
+}
+
+#coffee-results a {
+  display: block;
+  border: 0;
+  outline: none;
+  color: #444;
+  padding: 6px 10px 4px;
+  line-height: normal;
+  font-size: 16px;
+  text-decoration: none;
+  height: auto;
+  -webkit-transition: none;
+  -moz-transition: none;
+  -ms-transition: none;
+  -o-transition: none;
+  transition: none;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  -ms-border-radius: 0px;
+  -o-border-radius: 0px;
+  border-radius: 0px;
+}
+
+#coffee-results a.ui-state-hover,
+#coffee-results a:focus,
+#coffee-results a:hover,
+#coffee-results .ui-state-focus {
+  background: #d1d1d1;
+  color: #000;
+  margin: 0;
+  cursor: pointer;
+}
+
+#coffee-results .description {
+  display: block;
+  font-size: 11px;
+  color: #888;
+}
+
+#coffee-results a.ui-state-hover .description {
+  color: #666;
+}
+
+#coffee-results .ui-widget {
+  font-family: sans-serif;
+}
+
+.toolbar .toolbar-bar .toolbar-icon-coffee:before,
+.toolbar .toolbar-bar .toolbar-icon-coffee.active:before {
+    background-image: url("../images/icons/bebebe/coffee.svg");
+}
+
+#coffee-q{
+    background-image: url("../images/icons/bebebe/coffee.svg");
+    background-position: right 10px center;
+    background-repeat: no-repeat;
+    background-size: 40px 40px;
+}
\ No newline at end of file
diff --git a/core/themes/stable/stable.info.yml b/core/themes/stable/stable.info.yml
index e1981fe..e194050 100644
--- a/core/themes/stable/stable.info.yml
+++ b/core/themes/stable/stable.info.yml
@@ -26,6 +26,11 @@ libraries-override:
       theme:
         css/ckeditor.admin.css: css/ckeditor/ckeditor.admin.css
 
+  coffee/drupal.coffee:
+    css:
+      component:
+        css/coffee.css: css/coffee/coffee.css
+
   color/admin:
     css:
       theme:
