 ckeditor.module                                    |  373 +-------------------
 ckeditor.theme.inc                                 |  173 +++++++++
 .../ckeditor/Plugin/editor/editor/CKEditor.php     |  218 ++++++++++++
 3 files changed, 393 insertions(+), 371 deletions(-)

diff --git a/ckeditor.module b/ckeditor.module
index 93ad56e..8f4542c 100644
--- a/ckeditor.module
+++ b/ckeditor.module
@@ -5,37 +5,9 @@
  * Provides integration with the CKEditor WYSIWYG editor.
  */
 
-use Drupal\Core\Template\Attribute;
-
 define('CKEDITOR_VERSION', '4.0-dev');
 
 /**
- * Implements hook_editor_info().
- */
-function ckeditor_editor_info() {
-  $editors['ckeditor'] = array(
-    'label' => t('CKEditor'),
-    'library' => array('ckeditor', 'drupal.ckeditor'),
-    'default settings' => array(
-      'toolbar' => array(
-        array(
-          'Source', '|', 'Bold', 'Italic', '|',
-          'NumberedList', 'BulletedList', 'Blockquote', '|',
-          'JustifyLeft', 'JustifyCenter', 'JustifyRight', '|',
-          'Link', 'Unlink', '|', 'Image', 'Maximize',
-        ),
-      ),
-      'format_list' => array('p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'),
-      'style_list' => array(),
-    ),
-    'settings callback' => 'ckeditor_settings_form',
-    'js settings callback' => 'ckeditor_add_settings',
-  );
-
-  return $editors;
-}
-
-/**
  * Implements hook_library_info().
  */
 function ckeditor_library_info() {
@@ -101,6 +73,7 @@ function ckeditor_library_info() {
 function ckeditor_theme() {
   return array(
     'ckeditor_settings_toolbar' => array(
+      'file' => 'ckeditor.theme.inc',
       'variables' => array('editor' => NULL, 'plugins' => NULL),
     ),
   );
@@ -352,7 +325,7 @@ function ckeditor_ckeditor_plugins() {
  * Checks if our Caption plugin should be enabled based on the configuration of
  * a text format and editor.
  */
-function ckeditor_image_plugin_check($editor, $format) {
+function ckeditor_image_plugin_check($editor) {
   // Automatically enable caption support if the DrupalImage button is enabled.
   foreach ($editor->settings['toolbar'] as $row) {
     if (in_array('DrupalImage', $row)) {
@@ -361,348 +334,6 @@ function ckeditor_image_plugin_check($editor, $format) {
   }
 }
 
-
-/**
- * Preprocess variables for theme_ckeditor_settings_toolbar().
- */
-function template_preprocess_ckeditor_settings_toolbar(&$variables) {
-  // Simplify the language direction information for toolbar buttons.
-  global $language;
-  $variables['language_direction'] = isset($language->direction) && $language->direction === LANGUAGE_RTL ? 'rtl' : 'ltr';
-
-  // Create lists of active and disabled buttons.
-  $editor = $variables['editor'];
-  $plugins = $variables['plugins'];
-  $buttons = array();
-  $variables['multiple_buttons'] = array();
-  foreach ($plugins as $plugin) {
-    if (isset($plugin['buttons'])) {
-      foreach ($plugin['buttons'] as $button_name => $button) {
-        if (!empty($button['multiple'])) {
-          $variables['multiple_buttons'][$button_name] = $button;
-        }
-        $button['name'] = $button_name;
-        $buttons[$button_name] = $button;
-      }
-    }
-  }
-  $variables['active_buttons'] = array();
-  foreach ($editor->settings['toolbar'] as $row_number => $row) {
-    foreach ($row as $button_name) {
-      if (isset($buttons[$button_name])) {
-        $variables['active_buttons'][$row_number][] = $buttons[$button_name];
-        if (empty($buttons[$button_name]['multiple'])) {
-          unset($buttons[$button_name]);
-        }
-      }
-    }
-  }
-  $variables['disabled_buttons'] = array_diff_key($buttons, $variables['multiple_buttons']);
-}
-
-/**
- * Displays the toolbar configuration for CKEditor.
- */
-function theme_ckeditor_settings_toolbar($variables) {
-  $editor = $variables['editor'];
-  $plugins = $variables['plugins'];
-  $rtl = $variables['language_direction'] === 'rtl' ? '_rtl' : '';
-
-  // Assemble items to be added to active button rows.
-  foreach ($variables['active_buttons'] as $row_number => $row_buttons) {
-    foreach ($row_buttons as $button) {
-      $button_name = $button['name'];
-      if (isset($button['image_alternative'])) {
-        $data = $button['image_alternative'];
-      }
-      elseif (isset($button['image'])) {
-        $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
-      }
-      else {
-        $data = '?';
-      }
-      $button_item = array(
-        'data' => $data,
-        'data-button-name' => $button_name,
-      );
-      if (!empty($button['multiple'])) {
-         $button['attributes']['class'][] = 'ckeditor-multiple-button';
-      }
-      if (!empty($button['attributes'])) {
-        $button_item = array_merge($button_item, $button['attributes']);
-      }
-      $active_buttons[$row_number][] = $button_item;
-    }
-  }
-  // Assemble list of disabled buttons (which are always a single row).
-  foreach ($variables['disabled_buttons'] as $button_name => $button) {
-    if (isset($button['image_alternative'])) {
-      $data = $button['image_alternative'];
-    }
-    elseif (isset($button['image'])) {
-      $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
-    }
-    else {
-      $data = '?';
-    }
-    $button_item = array(
-      'data' => $data,
-      'data-button-name' => $button_name,
-    );
-    if (isset($button['attributes'])) {
-      $button_item = array_merge($button_item, $button['attributes']);
-    }
-    $disabled_buttons[] = $button_item;
-  }
-  // Assemble list of multiple buttons that may be added multiple times.
-  foreach ($variables['multiple_buttons'] as $button_name => $button) {
-    if (isset($button['image_alternative'])) {
-      $data = $button['image_alternative'];
-    }
-    elseif (isset($button['image'])) {
-      $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
-    }
-    else {
-      $data = '?';
-    }
-    $button_item = array(
-      'data' => $data,
-      'data-button-name' => $button_name,
-    );
-    $button['attributes']['class'][] = 'ckeditor-multiple-button';
-    if (isset($button['attributes'])) {
-      $button_item = array_merge($button_item, $button['attributes']);
-    }
-    $multiple_buttons[] = $button_item;
-  }
-
-  // We don't use theme_item_list() below in case there are no buttons in the
-  // active or disabled list, as theme_item_list() will not print an empty UL.
-  $output = '';
-  $output .= '<strong>' . t('Active toolbar') . '</strong>';
-  $output .= '<div class="ckeditor-toolbar-active clearfix">';
-  foreach ($active_buttons as $button_row) {
-    $output .= '<ul class="ckeditor-buttons">';
-    foreach ($button_row as $button) {
-      $contents = $button['data'];
-      unset($button['data']);
-      $attributes = (string) new Attribute($button);
-      $output .= '<li' . $attributes . '>' . $contents . '</li>';
-    }
-    $output .= '</ul>';
-  }
-  if (empty($active_buttons)) {
-    $output .= '<ul class="ckeditor-buttons">';
-    $output .= '</ul>';
-  }
-
-  $output .= '<div class="ckeditor-row-controls">';
-  $output .= '<a href="#" class="ckeditor-row-remove" title="' . t('Remove row') . '">-</a>';
-  $output .= '<a href="#" class="ckeditor-row-add" title="' . t('Add row') . '">+</a>';
-  $output .= '</div>';
-
-  $output .= '</div>';
-
-  $output .= '<strong>' . t('Available buttons') . '</strong>';
-  $output .= '<div class="ckeditor-toolbar-disabled clearfix">';
-  $output .= '<ul class="ckeditor-buttons">';
-  foreach ($disabled_buttons as $button) {
-    $contents = $button['data'];
-    unset($button['data']);
-    $attributes = (string) new Attribute($button);
-    $output .= '<li' . $attributes . '>' . $contents . '</li>';
-  }
-  $output .= '</ul>';
-  $output .= '<strong class="ckeditor-multiple-label">' . t('Dividers') . ': </strong>';
-  $output .= '<ul class="ckeditor-multiple-buttons">';
-  foreach ($multiple_buttons as $button) {
-    $contents = $button['data'];
-    unset($button['data']);
-    $attributes = (string) new Attribute($button);
-    $output .= '<li' . $attributes . '>' . $contents . '</li>';
-  }
-  $output .= '</ul>';
-  $output .= '</div>';
-
-  return $output;
-}
-
-/**
- * Editor settings callback; Provide options for CKEditor module.
- */
-function ckeditor_settings_form(&$form, $form_state, $editor, $format) {
-  $module_path = drupal_get_path('module', 'ckeditor');
-  $plugins = ckeditor_plugins();
-
-  $elements['toolbar'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Toolbar'),
-    '#parents' => array('editor_settings'),
-    '#attached' => array(
-      'library' => array(array('ckeditor', 'drupal.ckeditor.admin')),
-      'js' => array(
-        array('data' => array('ckeditor' => array('toolbarAdmin' => theme('ckeditor_settings_toolbar', array('editor' => $editor, 'plugins' => $plugins)))), 'type' => 'setting')
-      ),
-    ),
-    '#attributes' => array('class' => array('ckeditor-toolbar-configuration')),
-  );
-  $elements['toolbar']['toolbar'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Toolbar configuration'),
-    '#default_value' => json_encode($editor->settings['toolbar']),
-    '#attributes' => array('class' => array('ckeditor-toolbar-textarea')),
-  );
-  $elements['toolbar']['format_list'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Format list'),
-    '#default_value' => implode(', ', $editor->settings['format_list']),
-    '#description' => t('A list of tags that will be provided in the "Format" dropdown, separated by commas.')
-  );
-  $elements['toolbar']['style_list'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Style list'),
-    '#rows' => 4,
-    '#default_value' => implode("\n", $editor->settings['style_list']),
-    '#description' => t('A list of classes that will be provided in the "Styles" dropdown, each on a separate line. These styles should be available in your theme\'s editor.css as well as in your theme\'s main CSS file.')
-  );
-
-  array_unshift($form['#submit'], 'ckeditor_settings_form_submit');
-  return $elements;
-}
-
-/**
- * Additional submit handler for filter_admin_format_form().
- */
-function ckeditor_settings_form_submit($form, &$form_state) {
-  $settings = $form_state['values']['editor_settings'];
-  form_set_value($form['editor_settings']['toolbar']['toolbar'], json_decode($settings['toolbar'], FALSE), $form_state);
-
-  $format_list = array();
-  foreach (explode(',', $settings['format_list']) as $format) {
-    $format_list[] = trim($format);
-  }
-  form_set_value($form['editor_settings']['toolbar']['format_list'], $format_list, $form_state);
-
-  $styles = array();
-  foreach (explode("\n", $settings['style_list']) as $style) {
-    $styles[] = trim($style);
-  }
-  form_set_value($form['editor_settings']['toolbar']['style_list'], $styles, $form_state);
-}
-
-/**
- * Editor JS settings callback; Add Aloha settings to the page for a format.
- *
- * @param $editor
- *   The editor object for which Aloha is adding its settings.
- * @param $format
- *   The filter format object for which Aloha is adding its settings.
- * @param $existing_settings
- *   Settings that have already been added to the page by filters.
- */
-function ckeditor_add_settings($editor, $format, $existing_settings) {
-  global $language;
-
-  // Loop through all available plugins and check to see if it has been
-  // explicitly enabled. At the same time, associate each plugin with its
-  // buttons (if any) so we can check if the plugin should be enabled implicitly
-  // based on the toolbar.
-  $plugin_info = ckeditor_plugins();
-  $external_plugins = array();
-  $external_css = array();
-  $all_buttons = array();
-  foreach ($plugin_info as $plugin_name => $plugin) {
-    // Check if this plugin should be enabled.
-    if (isset($plugin['enabled callback'])) {
-      if ($plugin['enabled callback'] === TRUE || $plugin['enabled callback']($editor, $format) && !empty($plugin['path'])) {
-        $external_plugins[$plugin_name]['file'] = $plugin['file'];
-        $external_plugins[$plugin_name]['path'] = $plugin['path'];
-        if (isset($plugin['css'])) {
-          $external_css = array_merge($external_css, $plugin['css']);
-        }
-      }
-    }
-    // Associate each plugin with its button.
-    if (isset($plugin['buttons'])) {
-      if (empty($plugin['internal'])) {
-        foreach ($plugin['buttons'] as $button_name => &$button) {
-          $button['plugin'] = $plugin;
-          $button['plugin']['name'] = $plugin_name;
-          unset($button['plugin']['buttons']);
-        }
-      }
-      $all_buttons = array_merge($all_buttons, $plugin['buttons']);
-    }
-  }
-
-  // Change the toolbar separators into groups and record needed plugins based
-  // on use in the toolbar.
-  $toolbar = array();
-  foreach ($editor->settings['toolbar'] as $row_number => $row) {
-    $button_group = array();
-    foreach ($row as $button_name) {
-      if ($button_name === '|') {
-        $toolbar[] = $button_group;
-        $button_group = array();
-      }
-      else {
-        // Sanity check that the button exists in our installation.
-        if (isset($all_buttons[$button_name])) {
-          $button_group['items'][] = $button_name;
-
-          // Keep track of the needed plugin for this button, if any.
-          if (isset($all_buttons[$button_name]['plugin']['path'])) {
-            $plugin_name = $all_buttons[$button_name]['plugin']['name'];
-            $external_plugin = $all_buttons[$button_name]['plugin'];
-            $external_plugins[$plugin_name]['file'] = $external_plugin['file'];
-            $external_plugins[$plugin_name]['path'] = $external_plugin['path'];
-            if (isset($external_plugin['css'])) {
-              $external_css = array_merge($external_css, $external_plugin['css']);
-            }
-          }
-        }
-      }
-    }
-    $toolbar[] = $button_group;
-    $toolbar[] = '/';
-  }
-
-  // Collect a list of CSS files to be added to the editor instance.
-  $css = array(
-    drupal_get_path('module', 'ckeditor') . '/css/ckeditor.css',
-    drupal_get_path('module', 'ckeditor') . '/css/ckeditor-iframe.css',
-  );
-  $css = array_merge($css, $external_css, _ckeditor_theme_css());
-  drupal_alter('ckeditor_css', $css, $editor, $format);
-
-  // Convert all paths to be relative to root.
-  foreach ($css as $key => $css_path) {
-    $css[$key] = base_path() . $css_path;
-  }
-
-  // Initialize reasonable defaults that provide expected basic bahvior.
-  $settings = array(
-    'toolbar' => $toolbar,
-    'extraPlugins' => implode(',', array_keys($external_plugins)),
-    'removePlugins' => 'image',
-    //'forcePasteAsPlainText' => TRUE,
-    'contentsCss' => array_values($css),
-    'pasteFromWordPromptCleanup' => TRUE,
-    'indentClasses' => array('indent1', 'indent2', 'indent3'),
-    'justifyClasses' => array('align-left', 'align-center', 'align-right', 'align-justify'),
-    'coreStyles_underline' => array('element' => 'span', 'attributes' => array('class' => 'underline')),
-    'format_tags' => implode(';', $editor->settings['format_list']),
-    'removeDialogTabs' => 'image:Link;image:advanced;link:advanced',
-    'language' => isset($language->language) ? $language->language : '',
-    'resize_dir' => 'vertical',
-  );
-
-  // These settings are used specifically by Drupal.
-  $settings['externalPlugins'] = $external_plugins;
-
-  return $settings;
-}
-
 /**
  * Retrieves the default theme's CKEditor stylesheets defined in the .info file.
  *
diff --git a/ckeditor.theme.inc b/ckeditor.theme.inc
new file mode 100644
index 0000000..897d908
--- /dev/null
+++ b/ckeditor.theme.inc
@@ -0,0 +1,173 @@
+<?php
+
+/**
+ * @file
+ * Preprocessors and theme functions for the CKEditor toolbar configuration UI.
+ */
+
+use Drupal\Core\Template\Attribute;
+
+/**
+ * Preprocess variables for theme_ckeditor_settings_toolbar().
+ */
+function template_preprocess_ckeditor_settings_toolbar(&$variables) {
+  // Simplify the language direction information for toolbar buttons.
+  global $language;
+  $variables['language_direction'] = isset($language->direction) && $language->direction === LANGUAGE_RTL ? 'rtl' : 'ltr';
+
+  // Create lists of active and disabled buttons.
+  $editor = $variables['editor'];
+  $plugins = $variables['plugins'];
+  $buttons = array();
+  $variables['multiple_buttons'] = array();
+  foreach ($plugins as $plugin) {
+    if (isset($plugin['buttons'])) {
+      foreach ($plugin['buttons'] as $button_name => $button) {
+        if (!empty($button['multiple'])) {
+          $variables['multiple_buttons'][$button_name] = $button;
+        }
+        $button['name'] = $button_name;
+        $buttons[$button_name] = $button;
+      }
+    }
+  }
+  $variables['active_buttons'] = array();
+  foreach ($editor->settings['toolbar'] as $row_number => $row) {
+    foreach ($row as $button_name) {
+      if (isset($buttons[$button_name])) {
+        $variables['active_buttons'][$row_number][] = $buttons[$button_name];
+        if (empty($buttons[$button_name]['multiple'])) {
+          unset($buttons[$button_name]);
+        }
+      }
+    }
+  }
+  $variables['disabled_buttons'] = array_diff_key($buttons, $variables['multiple_buttons']);
+}
+
+/**
+ * Displays the toolbar configuration for CKEditor.
+ */
+function theme_ckeditor_settings_toolbar($variables) {
+  $editor = $variables['editor'];
+  $plugins = $variables['plugins'];
+  $rtl = $variables['language_direction'] === 'rtl' ? '_rtl' : '';
+
+  // Assemble items to be added to active button rows.
+  foreach ($variables['active_buttons'] as $row_number => $row_buttons) {
+    foreach ($row_buttons as $button) {
+      $button_name = $button['name'];
+      if (isset($button['image_alternative'])) {
+        $data = $button['image_alternative'];
+      }
+      elseif (isset($button['image'])) {
+        $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
+      }
+      else {
+        $data = '?';
+      }
+      $button_item = array(
+        'data' => $data,
+        'data-button-name' => $button_name,
+      );
+      if (!empty($button['multiple'])) {
+         $button['attributes']['class'][] = 'ckeditor-multiple-button';
+      }
+      if (!empty($button['attributes'])) {
+        $button_item = array_merge($button_item, $button['attributes']);
+      }
+      $active_buttons[$row_number][] = $button_item;
+    }
+  }
+  // Assemble list of disabled buttons (which are always a single row).
+  foreach ($variables['disabled_buttons'] as $button_name => $button) {
+    if (isset($button['image_alternative'])) {
+      $data = $button['image_alternative'];
+    }
+    elseif (isset($button['image'])) {
+      $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
+    }
+    else {
+      $data = '?';
+    }
+    $button_item = array(
+      'data' => $data,
+      'data-button-name' => $button_name,
+    );
+    if (isset($button['attributes'])) {
+      $button_item = array_merge($button_item, $button['attributes']);
+    }
+    $disabled_buttons[] = $button_item;
+  }
+  // Assemble list of multiple buttons that may be added multiple times.
+  foreach ($variables['multiple_buttons'] as $button_name => $button) {
+    if (isset($button['image_alternative'])) {
+      $data = $button['image_alternative'];
+    }
+    elseif (isset($button['image'])) {
+      $data = theme('image', array('uri' => $button['image' . $rtl], 'title' => $button['label']));
+    }
+    else {
+      $data = '?';
+    }
+    $button_item = array(
+      'data' => $data,
+      'data-button-name' => $button_name,
+    );
+    $button['attributes']['class'][] = 'ckeditor-multiple-button';
+    if (isset($button['attributes'])) {
+      $button_item = array_merge($button_item, $button['attributes']);
+    }
+    $multiple_buttons[] = $button_item;
+  }
+
+  // We don't use theme_item_list() below in case there are no buttons in the
+  // active or disabled list, as theme_item_list() will not print an empty UL.
+  $output = '';
+  $output .= '<strong>' . t('Active toolbar') . '</strong>';
+  $output .= '<div class="ckeditor-toolbar-active clearfix">';
+  foreach ($active_buttons as $button_row) {
+    $output .= '<ul class="ckeditor-buttons">';
+    foreach ($button_row as $button) {
+      $contents = $button['data'];
+      unset($button['data']);
+      $attributes = (string) new Attribute($button);
+      $output .= '<li' . $attributes . '>' . $contents . '</li>';
+    }
+    $output .= '</ul>';
+  }
+  if (empty($active_buttons)) {
+    $output .= '<ul class="ckeditor-buttons">';
+    $output .= '</ul>';
+  }
+
+  $output .= '<div class="ckeditor-row-controls">';
+  $output .= '<a href="#" class="ckeditor-row-remove" title="' . t('Remove row') . '">-</a>';
+  $output .= '<a href="#" class="ckeditor-row-add" title="' . t('Add row') . '">+</a>';
+  $output .= '</div>';
+
+  $output .= '</div>';
+
+  $output .= '<strong>' . t('Available buttons') . '</strong>';
+  $output .= '<div class="ckeditor-toolbar-disabled clearfix">';
+  $output .= '<ul class="ckeditor-buttons">';
+  foreach ($disabled_buttons as $button) {
+    $contents = $button['data'];
+    unset($button['data']);
+    $attributes = (string) new Attribute($button);
+    $output .= '<li' . $attributes . '>' . $contents . '</li>';
+  }
+  $output .= '</ul>';
+  $output .= '<strong class="ckeditor-multiple-label">' . t('Dividers') . ': </strong>';
+  $output .= '<ul class="ckeditor-multiple-buttons">';
+  foreach ($multiple_buttons as $button) {
+    $contents = $button['data'];
+    unset($button['data']);
+    $attributes = (string) new Attribute($button);
+    $output .= '<li' . $attributes . '>' . $contents . '</li>';
+  }
+  $output .= '</ul>';
+  $output .= '</div>';
+
+  return $output;
+}
diff --git a/lib/Drupal/ckeditor/Plugin/editor/editor/CKEditor.php b/lib/Drupal/ckeditor/Plugin/editor/editor/CKEditor.php
new file mode 100644
index 0000000..d28cd0b
--- /dev/null
+++ b/lib/Drupal/ckeditor/Plugin/editor/editor/CKEditor.php
@@ -0,0 +1,218 @@
+<?php
+
+/**
+ * @file
+ * Definition of \Drupal\ckeditor\Plugin\editor\editor\CKEditor.
+ */
+
+namespace Drupal\ckeditor\Plugin\editor\editor;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+use Drupal\editor\Plugin\Core\Entity\Editor;
+use Drupal\editor\Plugin\EditorInterface;
+
+
+
+/**
+ * Defines a CKEditor-based text editor for Drupal.
+ *
+ * @Plugin(
+ *   id = "ckeditor",
+ *   title = @Translation("CKEditor"),
+  *  library = {
+ *     "module" = "ckeditor",
+ *     "name" = "drupal.ckeditor"
+ *   }
+ * )
+ */
+class CKEditor extends PluginBase implements EditorInterface {
+
+  /**
+   * Implements \Drupal\editor\Plugin\EditorInterface::defaultSettings().
+   */
+  function defaultSettings() {
+    return array(
+      'toolbar' => array(
+        array(
+          'Source', '|', 'Bold', 'Italic', '|',
+          'NumberedList', 'BulletedList', 'Blockquote', '|',
+          'JustifyLeft', 'JustifyCenter', 'JustifyRight', '|',
+          'Link', 'Unlink', '|', 'Image', 'Maximize',
+        ),
+      ),
+      'format_list' => array('p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'),
+      'style_list' => array(),
+    );
+  }
+
+  /**
+   * Implements \Drupal\editor\Plugin\EditorInterface::settingsForm().
+   */
+  function settingsForm(array &$form, array &$form_state, Editor $editor) {
+    $module_path = drupal_get_path('module', 'ckeditor');
+    $plugins = ckeditor_plugins();
+
+    $elements['toolbar'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Toolbar'),
+      '#parents' => array('editor_settings'),
+      '#attached' => array(
+        'library' => array(array('ckeditor', 'drupal.ckeditor.admin')),
+        'js' => array(
+          array('data' => array('ckeditor' => array('toolbarAdmin' => theme('ckeditor_settings_toolbar', array('editor' => $editor, 'plugins' => $plugins)))), 'type' => 'setting')
+        ),
+      ),
+      '#attributes' => array('class' => array('ckeditor-toolbar-configuration')),
+    );
+    $elements['toolbar']['toolbar'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Toolbar configuration'),
+      '#default_value' => json_encode($editor->settings['toolbar']),
+      '#attributes' => array('class' => array('ckeditor-toolbar-textarea')),
+    );
+    $elements['toolbar']['format_list'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Format list'),
+      '#default_value' => implode(', ', $editor->settings['format_list']),
+      '#description' => t('A list of tags that will be provided in the "Format" dropdown, separated by commas.')
+    );
+    $elements['toolbar']['style_list'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Style list'),
+      '#rows' => 4,
+      '#default_value' => implode("\n", $editor->settings['style_list']),
+      '#description' => t('A list of classes that will be provided in the "Styles" dropdown, each on a separate line. These styles should be available in your theme\'s editor.css as well as in your theme\'s main CSS file.')
+    );
+
+    return $elements;
+  }
+
+  /**
+   * Implements \Drupal\editor\Plugin\EditorInterface::settingsFormValidate().
+   */
+  function settingsFormValidate(array $form, array &$form_state) {
+    $settings = $form_state['values']['editor_settings'];
+    form_set_value($form['editor_settings']['toolbar']['toolbar'], json_decode($settings['toolbar'], FALSE), $form_state);
+
+    $format_list = array();
+    foreach (explode(',', $settings['format_list']) as $format) {
+      $format_list[] = trim($format);
+    }
+    form_set_value($form['editor_settings']['toolbar']['format_list'], $format_list, $form_state);
+
+    $styles = array();
+    foreach (explode("\n", $settings['style_list']) as $style) {
+      $styles[] = trim($style);
+    }
+    form_set_value($form['editor_settings']['toolbar']['style_list'], $styles, $form_state);
+  }
+
+  /**
+   * Implements \Drupal\editor\Plugin\EditorInterface::generateJsSettings().
+   */
+  function generateJsSettings(Editor $editor) {
+    global $language;
+
+    // Loop through all available plugins and check to see if it has been
+    // explicitly enabled. At the same time, associate each plugin with its
+    // buttons (if any) so we can check if the plugin should be enabled implicitly
+    // based on the toolbar.
+    $plugin_info = ckeditor_plugins();
+    $external_plugins = array();
+    $external_css = array();
+    $all_buttons = array();
+    foreach ($plugin_info as $plugin_name => $plugin) {
+      // Check if this plugin should be enabled.
+      if (isset($plugin['enabled callback'])) {
+        if ($plugin['enabled callback'] === TRUE || $plugin['enabled callback']($editor) && !empty($plugin['path'])) {
+          $external_plugins[$plugin_name]['file'] = $plugin['file'];
+          $external_plugins[$plugin_name]['path'] = $plugin['path'];
+          if (isset($plugin['css'])) {
+            $external_css = array_merge($external_css, $plugin['css']);
+          }
+        }
+      }
+      // Associate each plugin with its button.
+      if (isset($plugin['buttons'])) {
+        if (empty($plugin['internal'])) {
+          foreach ($plugin['buttons'] as $button_name => &$button) {
+            $button['plugin'] = $plugin;
+            $button['plugin']['name'] = $plugin_name;
+            unset($button['plugin']['buttons']);
+          }
+        }
+        $all_buttons = array_merge($all_buttons, $plugin['buttons']);
+      }
+    }
+
+    // Change the toolbar separators into groups and record needed plugins based
+    // on use in the toolbar.
+    $toolbar = array();
+    foreach ($editor->settings['toolbar'] as $row_number => $row) {
+      $button_group = array();
+      foreach ($row as $button_name) {
+        if ($button_name === '|') {
+          $toolbar[] = $button_group;
+          $button_group = array();
+        }
+        else {
+          // Sanity check that the button exists in our installation.
+          if (isset($all_buttons[$button_name])) {
+            $button_group['items'][] = $button_name;
+
+            // Keep track of the needed plugin for this button, if any.
+            if (isset($all_buttons[$button_name]['plugin']['path'])) {
+              $plugin_name = $all_buttons[$button_name]['plugin']['name'];
+              $external_plugin = $all_buttons[$button_name]['plugin'];
+              $external_plugins[$plugin_name]['file'] = $external_plugin['file'];
+              $external_plugins[$plugin_name]['path'] = $external_plugin['path'];
+              if (isset($external_plugin['css'])) {
+                $external_css = array_merge($external_css, $external_plugin['css']);
+              }
+            }
+          }
+        }
+      }
+      $toolbar[] = $button_group;
+      $toolbar[] = '/';
+    }
+
+    // Collect a list of CSS files to be added to the editor instance.
+    $css = array(
+      drupal_get_path('module', 'ckeditor') . '/css/ckeditor.css',
+      drupal_get_path('module', 'ckeditor') . '/css/ckeditor-iframe.css',
+    );
+    $css = array_merge($css, $external_css, _ckeditor_theme_css());
+    drupal_alter('ckeditor_css', $css, $editor, $format);
+
+    // Convert all paths to be relative to root.
+    foreach ($css as $key => $css_path) {
+      $css[$key] = base_path() . $css_path;
+    }
+
+    // Initialize reasonable defaults that provide expected basic bahvior.
+    $settings = array(
+      'toolbar' => $toolbar,
+      'extraPlugins' => implode(',', array_keys($external_plugins)),
+      'removePlugins' => 'image',
+      //'forcePasteAsPlainText' => TRUE,
+      'contentsCss' => array_values($css),
+      'pasteFromWordPromptCleanup' => TRUE,
+      'indentClasses' => array('indent1', 'indent2', 'indent3'),
+      'justifyClasses' => array('align-left', 'align-center', 'align-right', 'align-justify'),
+      'coreStyles_underline' => array('element' => 'span', 'attributes' => array('class' => 'underline')),
+      'format_tags' => implode(';', $editor->settings['format_list']),
+      'removeDialogTabs' => 'image:Link;image:advanced;link:advanced',
+      'language' => isset($language->language) ? $language->language : '',
+      'resize_dir' => 'vertical',
+    );
+
+    // These settings are used specifically by Drupal.
+    $settings['externalPlugins'] = $external_plugins;
+
+    return $settings;
+  }
+
+}
