From ad44c6bf8f2eca9751ddccd2d4a3717b29039183 Mon Sep 17 00:00:00 2001
From: Claudiu Cristea <clau.cristea@gmail.com>
Date: Tue, 24 Sep 2013 23:52:19 +0300
Subject: [PATCH] Issue #2048827 by tim.plunkett, claudiu.cristea: Move Image
 toolkit API from system.module to Drupal\Core.

---
 core/core.services.yml                             |  10 +-
 core/lib/Drupal/Core/Image/Image.php               |   8 +-
 core/lib/Drupal/Core/Image/ImageFactory.php        |   8 +-
 core/lib/Drupal/Core/Image/ImageInterface.php      |  10 +-
 .../Core/ImageToolkit/ImageToolkitInterface.php    | 183 +++++++++++++++++++++
 .../Core/ImageToolkit/ImageToolkitManager.php      |  94 +++++++++++
 .../lib/Drupal/system/Annotation/ImageToolkit.php  |   4 +-
 .../lib/Drupal/system/Form/ImageToolkitForm.php    |   6 +-
 .../system/Plugin/ImageToolkit/GDToolkit.php       |   2 +-
 .../Drupal/system/Plugin/ImageToolkitInterface.php | 183 ---------------------
 .../Drupal/system/Plugin/ImageToolkitManager.php   |  86 ----------
 .../Drupal/system/Tests/Image/ToolkitGdTest.php    |   2 +-
 .../lib/Drupal/system/Tests/Image/ToolkitTest.php  |   4 +-
 .../Drupal/system/Tests/Image/ToolkitTestBase.php  |   5 +-
 .../Plugin/ImageToolkit/BrokenToolkit.php          |   2 +-
 .../image_test/Plugin/ImageToolkit/TestToolkit.php |   2 +-
 core/tests/Drupal/Tests/Core/Image/ImageTest.php   |   2 +-
 17 files changed, 308 insertions(+), 303 deletions(-)
 create mode 100644 core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
 create mode 100644 core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
 delete mode 100644 core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
 delete mode 100644 core/modules/system/lib/Drupal/system/Plugin/ImageToolkitManager.php

diff --git a/core/core.services.yml b/core/core.services.yml
index cd3ac50..8622bb3 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -518,13 +518,13 @@ services:
     class: Drupal\Core\Ajax\AjaxSubscriber
     tags:
       - { name: event_subscriber }
-  image.toolkit.manager:
-    class: Drupal\system\Plugin\ImageToolkitManager
-    arguments: ['@container.namespaces', '@cache.cache', '@language_manager']
+  plugin.manager.image_toolkit:
+    class: Drupal\Core\ImageToolkit\ImageToolkitManager
+    arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@config.factory']
   image.toolkit:
-    class: Drupal\system\Plugin\ImageToolkitInterface
+    class: Drupal\Core\ImageToolkit\ImageToolkitInterface
     factory_method: getDefaultToolkit
-    factory_service: image.toolkit.manager
+    factory_service: plugin.manager.image_toolkit
   image.factory:
     class: Drupal\Core\Image\ImageFactory
     arguments: ['@image.toolkit']
diff --git a/core/lib/Drupal/Core/Image/Image.php b/core/lib/Drupal/Core/Image/Image.php
index a515fe4..046fb0f 100644
--- a/core/lib/Drupal/Core/Image/Image.php
+++ b/core/lib/Drupal/Core/Image/Image.php
@@ -7,13 +7,13 @@
 
 namespace Drupal\Core\Image;
 
-use Drupal\system\Plugin\ImageToolkitInterface;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 use Drupal\Component\Utility\Image as ImageUtility;
 
 /**
  * Defines an image object to represent an image file.
  *
- * @see \Drupal\system\Plugin\ImageToolkitInterface
+ * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface
  * @see \Drupal\image\ImageEffectInterface
  *
  * @ingroup image
@@ -30,7 +30,7 @@ class Image implements ImageInterface {
   /**
    * An image toolkit object.
    *
-   * @var \Drupal\system\Plugin\ImageToolkitInterface
+   * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
    */
   protected $toolkit;
 
@@ -88,7 +88,7 @@ class Image implements ImageInterface {
    *
    * @param string $source
    *   The path to an image file.
-   * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
+   * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
    *   The image toolkit.
    */
   public function __construct($source, ImageToolkitInterface $toolkit) {
diff --git a/core/lib/Drupal/Core/Image/ImageFactory.php b/core/lib/Drupal/Core/Image/ImageFactory.php
index 0ffc9a2..27773d8 100644
--- a/core/lib/Drupal/Core/Image/ImageFactory.php
+++ b/core/lib/Drupal/Core/Image/ImageFactory.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\Image;
 
-use Drupal\system\Plugin\ImageToolkitInterface;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 
 /**
  * Provides a factory for image objects.
@@ -17,14 +17,14 @@ class ImageFactory {
   /**
    * The image toolkit to use for this factory.
    *
-   * @var \Drupal\system\Plugin\ImageToolkitInterface
+   * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
    */
   protected $toolkit;
 
   /**
    * Constructs a new ImageFactory object.
    *
-   * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
+   * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
    *   The image toolkit to use for this image factory.
    */
   public function __construct(ImageToolkitInterface $toolkit) {
@@ -34,7 +34,7 @@ public function __construct(ImageToolkitInterface $toolkit) {
   /**
    * Sets a custom image toolkit.
    *
-   * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
+   * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
    *   The image toolkit to use for this image factory.
    *
    * @return self
diff --git a/core/lib/Drupal/Core/Image/ImageInterface.php b/core/lib/Drupal/Core/Image/ImageInterface.php
index b83c578..25e5b27 100644
--- a/core/lib/Drupal/Core/Image/ImageInterface.php
+++ b/core/lib/Drupal/Core/Image/ImageInterface.php
@@ -136,7 +136,7 @@ public function getToolkitId();
    * @return bool
    *   TRUE on success, FALSE on failure.
    *
-   * @see \Drupal\system\Plugin\ImageToolkitInterface::save()
+   * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::save()
    */
   public function save($destination = NULL);
 
@@ -194,7 +194,7 @@ public function scaleAndCrop($width, $height);
    * @return bool
    *   TRUE on success, FALSE on failure.
    *
-   * @see \Drupal\system\Plugin\ImageToolkitInterface::crop()
+   * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::crop()
    */
   public function crop($x, $y, $width, $height);
 
@@ -209,7 +209,7 @@ public function crop($x, $y, $width, $height);
    * @return bool
    *   TRUE on success, FALSE on failure.
    *
-   * @see \Drupal\system\Plugin\ImageToolkitInterface::resize()
+   * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::resize()
    */
   public function resize($width, $height);
 
@@ -219,7 +219,7 @@ public function resize($width, $height);
    * @return bool
    *   TRUE on success, FALSE on failure.
    *
-   * @see \Drupal\system\Plugin\ImageToolkitInterface::desaturate()
+   * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::desaturate()
    */
   public function desaturate();
 
@@ -238,7 +238,7 @@ public function desaturate();
    * @return bool
    *   TRUE on success, FALSE on failure.
    *
-   * @see \Drupal\system\Plugin\ImageToolkitInterface::rotate()
+   * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::rotate()
    */
   public function rotate($degrees, $background = NULL);
 
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
new file mode 100644
index 0000000..a2aab7d
--- /dev/null
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\ImageToolkit\ImageToolkitInterface.
+ */
+
+namespace Drupal\Core\ImageToolkit;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Image\ImageInterface;
+
+/**
+ * @defgroup image Image toolkits
+ * @{
+ * Functions for image file manipulations.
+ *
+ * Drupal's image toolkits provide an abstraction layer for common image file
+ * manipulations like scaling, cropping, and rotating. The abstraction frees
+ * module authors from the need to support multiple image libraries, and it
+ * allows site administrators to choose the library that's best for them.
+ *
+ * PHP includes the GD library by default so a GD toolkit is installed with
+ * Drupal. Other toolkits like ImageMagick are available from contrib modules.
+ * GD works well for small images, but using it with larger files may cause PHP
+ * to run out of memory. In contrast the ImageMagick library does not suffer
+ * from this problem, but it requires the ISP to have installed additional
+ * software.
+ *
+ * Image toolkits are discovered using the Plugin system using
+ * \Drupal\Core\ImageToolkit\ImageToolkitManager. The toolkit must then be
+ * enabled using the admin/config/media/image-toolkit form.
+ *
+ * Only one toolkit may be selected at a time. If a module author wishes to call
+ * a specific toolkit they can check that it is installed by calling
+ * \Drupal\Core\ImageToolkit\ImageToolkitManager::getAvailableToolkits(), and
+ * then calling its functions directly.
+ */
+
+/**
+ * Defines an interface for image toolkits.
+ *
+ * An image toolkit provides common image file manipulations like scaling,
+ * cropping, and rotating.
+ */
+interface ImageToolkitInterface extends PluginInspectionInterface {
+
+  /**
+   * Retrieves toolkit's settings form.
+   *
+   * @see system_image_toolkit_settings()
+   */
+  function settingsForm();
+
+  /**
+   * Handles submissions for toolkit's settings form.
+   *
+   * @see system_image_toolkit_settings_submit()
+   */
+  function settingsFormSubmit($form, &$form_state);
+
+  /**
+   * Scales an image to the specified size.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object. The $image->resource, $image->info['width'], and
+   *   $image->info['height'] values will be modified by this call.
+   * @param int $width
+   *   The new width of the resized image, in pixels.
+   * @param int $height
+   *   The new height of the resized image, in pixels.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   */
+  function resize(ImageInterface $image, $width, $height);
+
+  /**
+   * Rotates an image the given number of degrees.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object. The $image->resource, $image->info['width'], and
+   *   $image->info['height'] values will be modified by this call.
+   * @param int $degrees
+   *   The number of (clockwise) degrees to rotate the image.
+   * @param string $background
+   *   (optional) An hexadecimal integer specifying the background color to use
+   *   for the uncovered area of the image after the rotation. E.g. 0x000000 for
+   *   black, 0xff00ff for magenta, and 0xffffff for white. For images that
+   *   support transparency, this will default to transparent. Otherwise it will
+   *   be white.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   */
+  function rotate(ImageInterface $image, $degrees, $background = NULL);
+
+  /**
+   * Crops an image.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object. The $image->resource, $image->info['width'], and
+   *   $image->info['height'] values will be modified by this call.
+   * @param int $x
+   *   The starting x offset at which to start the crop, in pixels.
+   * @param int $y
+   *   The starting y offset at which to start the crop, in pixels.
+   * @param int $width
+   *   The width of the cropped area, in pixels.
+   * @param int $height
+   *   The height of the cropped area, in pixels.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   *
+   * @see image_crop()
+   */
+  function crop(ImageInterface $image, $x, $y, $width, $height);
+
+  /**
+   * Converts an image resource to grayscale.
+   *
+   * Note that transparent GIFs loose transparency when desaturated.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object. The $image->resource value will be modified by this
+   *   call.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   */
+  function desaturate(ImageInterface $image);
+
+  /**
+   * Creates an image resource from a file.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object. The $image->resource value will populated by this call.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   */
+  function load(ImageInterface $image);
+
+  /**
+   * Writes an image resource to a destination file.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object.
+   * @param string $destination
+   *   A string file URI or path where the image should be saved.
+   *
+   * @return bool
+   *   TRUE or FALSE, based on success.
+   */
+  function save(ImageInterface $image, $destination);
+
+  /**
+   * Gets details about an image.
+   *
+   * @param \Drupal\Core\Image\ImageInterface $image
+   *   An image object.
+   *
+   * @return array
+   *   FALSE, if the file could not be found or is not an image. Otherwise, a
+   *   keyed array containing information about the image:
+   *   - "width": Width, in pixels.
+   *   - "height": Height, in pixels.
+   *   - "extension": Commonly used file extension for the image.
+   *   - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png').
+   *
+   * @see \Drupal\Core\Image\ImageInterface::processInfo()
+   */
+  function getInfo(ImageInterface $image);
+
+  /**
+   * Verifies Image Toolkit is set up correctly.
+   *
+   * @return bool
+   *   True if the GD toolkit is available on this machine.
+   */
+  static function isAvailable();
+}
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
new file mode 100644
index 0000000..9dd46d4
--- /dev/null
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\ImageToolkit\ImageToolkitManager.
+ */
+
+namespace Drupal\Core\ImageToolkit;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\Language\LanguageManager;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manages toolkit plugins.
+ */
+class ImageToolkitManager extends DefaultPluginManager {
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactory
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs the ImageToolkitManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Config\ConfigFactory $config_factory
+   *   The config factory.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ConfigFactory $config_factory) {
+    parent::__construct('Plugin/ImageToolkit', $namespaces, 'Drupal\system\Annotation\ImageToolkit');
+
+    $this->setCacheBackend($cache_backend, $language_manager, 'image_toolkit');
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * Gets the default image toolkit.
+   *
+   * @return \Drupal\Core\ImageToolkit\ImageToolkitInterface
+   *   Object of the default toolkit, or FALSE on error.
+   */
+  public function getDefaultToolkit() {
+    $toolkit_id = $this->configFactory->get('system.image')->get('toolkit');
+    $toolkits = $this->getAvailableToolkits();
+
+    if (!isset($toolkits[$toolkit_id]) || !class_exists($toolkits[$toolkit_id]['class'])) {
+      // The selected toolkit isn't available so return the first one found. If
+      // none are available this will return FALSE.
+      reset($toolkits);
+      $toolkit_id = key($toolkits);
+    }
+
+    if ($toolkit_id) {
+      $toolkit = $this->createInstance($toolkit_id);
+    }
+    else {
+      $toolkit = FALSE;
+    }
+
+    return $toolkit;
+  }
+
+  /**
+   * Gets a list of available toolkits.
+   *
+   * @return array
+   *   An array with the toolkit names as keys and the descriptions as values.
+   */
+  public function getAvailableToolkits() {
+    // Use plugin system to get list of available toolkits.
+    $toolkits = $this->getDefinitions();
+
+    $output = array();
+    foreach ($toolkits as $id => $definition) {
+      // Only allow modules that aren't marked as unavailable.
+      if (call_user_func($definition['class'] . '::isAvailable')) {
+        $output[$id] = $definition;
+      }
+    }
+
+    return $output;
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Annotation/ImageToolkit.php b/core/modules/system/lib/Drupal/system/Annotation/ImageToolkit.php
index 0fd89da..0a75e97 100644
--- a/core/modules/system/lib/Drupal/system/Annotation/ImageToolkit.php
+++ b/core/modules/system/lib/Drupal/system/Annotation/ImageToolkit.php
@@ -14,8 +14,8 @@
  *
  * @Annotation
  *
- * @see \Drupal\system\Plugin\ImageToolkitInterface
- * @see \Drupal\system\Plugin\ImageToolkitManager
+ * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface
+ * @see \Drupal\Core\ImageToolkit\ImageToolkitManager
  */
 class ImageToolkit extends Plugin {
 
diff --git a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
index dcdb2cc..ed31f08 100644
--- a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Config\Context\ContextInterface;
 use Drupal\Core\Form\ConfigFormBase;
-use Drupal\system\Plugin\ImageToolkitManager;
+use Drupal\Core\ImageToolkit\ImageToolkitManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -32,7 +32,7 @@ class ImageToolkitForm extends ConfigFormBase {
    *   The factory for configuration objects.
    * @param \Drupal\Core\Config\Context\ContextInterface $context
    *   The configuration context used for this configuration object.
-   * @param \Drupal\system\Plugin\ImageToolkitManager $manager
+   * @param \Drupal\Core\ImageToolkit\ImageToolkitManager $manager
    *   The image toolkit plugin manager.
    */
   public function __construct(ConfigFactory $config_factory, ContextInterface $context, ImageToolkitManager $manager) {
@@ -50,7 +50,7 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('config.factory'),
       $container->get('config.context.free'),
-      $container->get('image.toolkit.manager')
+      $container->get('plugin.manager.image_toolkit')
     );
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
index 486afa1..382f64b 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
@@ -11,7 +11,7 @@
 use Drupal\system\Annotation\ImageToolkit;
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Image\ImageInterface;
-use Drupal\system\Plugin\ImageToolkitInterface;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 
 /**
  * Defines the GD2 toolkit for image manipulation within Drupal.
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
deleted file mode 100644
index 774f050..0000000
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\system\Plugin\ImageToolkitInterface.
- */
-
-namespace Drupal\system\Plugin;
-
-use Drupal\Component\Plugin\PluginInspectionInterface;
-use Drupal\Core\Image\ImageInterface;
-
-/**
- * @defgroup image Image toolkits
- * @{
- * Functions for image file manipulations.
- *
- * Drupal's image toolkits provide an abstraction layer for common image file
- * manipulations like scaling, cropping, and rotating. The abstraction frees
- * module authors from the need to support multiple image libraries, and it
- * allows site administrators to choose the library that's best for them.
- *
- * PHP includes the GD library by default so a GD toolkit is installed with
- * Drupal. Other toolkits like ImageMagick are available from contrib modules.
- * GD works well for small images, but using it with larger files may cause PHP
- * to run out of memory. In contrast the ImageMagick library does not suffer
- * from this problem, but it requires the ISP to have installed additional
- * software.
- *
- * Image toolkits are discovered using the Plugin system using
- * \Drupal\system\Plugin\ImageToolkitManager. The toolkit must then be enabled
- * using the admin/config/media/image-toolkit form.
- *
- * Only one toolkit may be selected at a time. If a module author wishes to call
- * a specific toolkit they can check that it is installed by calling
- * \Drupal\system\Plugin\ImageToolkitManager::getAvailableToolkits(), and then
- * calling its functions directly.
- */
-
-/**
- * Defines an interface for image toolkits.
- *
- * An image toolkit provides common image file manipulations like scaling,
- * cropping, and rotating.
- */
-interface ImageToolkitInterface extends PluginInspectionInterface {
-
-  /**
-   * Retrieves toolkit's settings form.
-   *
-   * @see system_image_toolkit_settings()
-   */
-  function settingsForm();
-
-  /**
-   * Handles submissions for toolkit's settings form.
-   *
-   * @see system_image_toolkit_settings_submit()
-   */
-  function settingsFormSubmit($form, &$form_state);
-
-  /**
-   * Scales an image to the specified size.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object. The $image->resource, $image->info['width'], and
-   *   $image->info['height'] values will be modified by this call.
-   * @param int $width
-   *   The new width of the resized image, in pixels.
-   * @param int $height
-   *   The new height of the resized image, in pixels.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   */
-  function resize(ImageInterface $image, $width, $height);
-
-  /**
-   * Rotates an image the given number of degrees.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object. The $image->resource, $image->info['width'], and
-   *   $image->info['height'] values will be modified by this call.
-   * @param int $degrees
-   *   The number of (clockwise) degrees to rotate the image.
-   * @param string $background
-   *   (optional) An hexadecimal integer specifying the background color to use
-   *   for the uncovered area of the image after the rotation. E.g. 0x000000 for
-   *   black, 0xff00ff for magenta, and 0xffffff for white. For images that
-   *   support transparency, this will default to transparent. Otherwise it will
-   *   be white.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   */
-  function rotate(ImageInterface $image, $degrees, $background = NULL);
-
-  /**
-   * Crops an image.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object. The $image->resource, $image->info['width'], and
-   *   $image->info['height'] values will be modified by this call.
-   * @param int $x
-   *   The starting x offset at which to start the crop, in pixels.
-   * @param int $y
-   *   The starting y offset at which to start the crop, in pixels.
-   * @param int $width
-   *   The width of the cropped area, in pixels.
-   * @param int $height
-   *   The height of the cropped area, in pixels.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   *
-   * @see image_crop()
-   */
-  function crop(ImageInterface $image, $x, $y, $width, $height);
-
-  /**
-   * Converts an image resource to grayscale.
-   *
-   * Note that transparent GIFs loose transparency when desaturated.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object. The $image->resource value will be modified by this
-   *   call.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   */
-  function desaturate(ImageInterface $image);
-
-  /**
-   * Creates an image resource from a file.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object. The $image->resource value will populated by this call.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   */
-  function load(ImageInterface $image);
-
-  /**
-   * Writes an image resource to a destination file.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object.
-   * @param string $destination
-   *   A string file URI or path where the image should be saved.
-   *
-   * @return bool
-   *   TRUE or FALSE, based on success.
-   */
-  function save(ImageInterface $image, $destination);
-
-  /**
-   * Gets details about an image.
-   *
-   * @param \Drupal\Core\Image\ImageInterface $image
-   *   An image object.
-   *
-   * @return array
-   *   FALSE, if the file could not be found or is not an image. Otherwise, a
-   *   keyed array containing information about the image:
-   *   - "width": Width, in pixels.
-   *   - "height": Height, in pixels.
-   *   - "extension": Commonly used file extension for the image.
-   *   - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png').
-   *
-   * @see \Drupal\Core\Image\ImageInterface::processInfo()
-   */
-  function getInfo(ImageInterface $image);
-
-  /**
-   * Verifies Image Toolkit is set up correctly.
-   *
-   * @return bool
-   *   True if the GD toolkit is available on this machine.
-   */
-  static function isAvailable();
-}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitManager.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitManager.php
deleted file mode 100644
index 77e90c1..0000000
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitManager.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\system\Plugin\ImageToolkitManager.
- */
-
-namespace Drupal\system\Plugin;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Language\LanguageManager;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Manages toolkit plugins.
- */
-class ImageToolkitManager extends DefaultPluginManager {
-
-  /**
-   * Constructs the ImageToolkitManager object.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Language\LanguageManager $language_manager
-   *   The language manager.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager) {
-    parent::__construct('Plugin/ImageToolkit', $namespaces, 'Drupal\system\Annotation\ImageToolkit');
-    $this->setCacheBackend($cache_backend, $language_manager, 'image_toolkit');
-  }
-
-  /**
-   * Gets the default image toolkit.
-   *
-   * @param string $toolkit_id
-   *   (optional) String specifying toolkit to load. NULL will load the default
-   *   toolkit.
-   *
-   * @return \Drupal\system\Plugin\ImageToolkitInterface
-   *   Object of the default toolkit, or FALSE on error.
-   */
-  public function getDefaultToolkit() {
-    $toolkit_id = \Drupal::config('system.image')->get('toolkit');
-    $toolkits = $this->getAvailableToolkits();
-
-    if (!isset($toolkits[$toolkit_id]) || !class_exists($toolkits[$toolkit_id]['class'])) {
-      // The selected toolkit isn't available so return the first one found. If
-      // none are available this will return FALSE.
-      reset($toolkits);
-      $toolkit_id = key($toolkits);
-    }
-
-    if ($toolkit_id) {
-      $toolkit = $this->createInstance($toolkit_id);
-    }
-    else {
-      $toolkit = FALSE;
-    }
-
-    return $toolkit;
-  }
-
-  /**
-   * Gets a list of available toolkits.
-   *
-   * @return array
-   *   An array with the toolkit names as keys and the descriptions as values.
-   */
-  public function getAvailableToolkits() {
-    // Use plugin system to get list of available toolkits.
-    $toolkits = $this->getDefinitions();
-
-    $output = array();
-    foreach ($toolkits as $id => $definition) {
-      // Only allow modules that aren't marked as unavailable.
-      if (call_user_func($definition['class'] . '::isAvailable')) {
-        $output[$id] = $definition;
-      }
-    }
-
-    return $output;
-  }
-}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
index 1797b78..aff496a 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
@@ -215,7 +215,7 @@ function testManipulations() {
       );
     }
 
-    $toolkit = $this->container->get('image.toolkit.manager')->createInstance('gd');
+    $toolkit = $this->container->get('plugin.manager.image_toolkit')->createInstance('gd');
     $image_factory = $this->container->get('image.factory')->setToolkit($toolkit);
     foreach ($files as $file) {
       foreach ($operations as $op => $values) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
index 5f6c4dc..c93b79b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\system\Tests\Image;
 
-use Drupal\system\Plugin\ImageToolkitManager;
-
 /**
  * Tests that the methods in Image correctly pass data to the toolkit.
  */
@@ -26,7 +24,7 @@ public static function getInfo() {
    * available toolkits.
    */
   function testGetAvailableToolkits() {
-    $manager = new ImageToolkitManager($this->container->get('container.namespaces'), $this->container->get('cache.cache'), $this->container->get('language_manager'));
+    $manager = $this->container->get('plugin.manager.image_toolkit');
     $toolkits = $manager->getAvailableToolkits();
     $this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.');
     $this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
index a7d097b..55519e9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
@@ -8,7 +8,6 @@
 namespace Drupal\system\Tests\Image;
 
 use Drupal\simpletest\WebTestBase;
-use Drupal\system\Plugin\ImageToolkitManager;
 
 /**
  * Base class for image manipulation testing.
@@ -25,7 +24,7 @@
   /**
    * The image toolkit.
    *
-   * @var \Drupal\system\Plugin\ImageToolkitInterface
+   * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
    */
   protected $toolkit;
 
@@ -47,7 +46,7 @@ function setUp() {
     parent::setUp();
 
     // Use the image_test.module's test toolkit.
-    $manager = new ImageToolkitManager($this->container->get('container.namespaces'), $this->container->get('cache.cache'), $this->container->get('language_manager'));
+    $manager = $this->container->get('plugin.manager.image_toolkit');
     $this->toolkit = $manager->createInstance('test');
 
     // Pick a file for testing.
diff --git a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/BrokenToolkit.php b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/BrokenToolkit.php
index b7aeef5..ff63957 100644
--- a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/BrokenToolkit.php
+++ b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/BrokenToolkit.php
@@ -21,7 +21,7 @@
 class BrokenToolkit extends TestToolkit {
 
   /**
-   * Implements \Drupal\system\Plugin\ImageToolkitInterface::isAvailable().
+   * {@inheritdoc}
    */
   public static function isAvailable() {
     return FALSE;
diff --git a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
index d8ae884..3340ff9 100644
--- a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
@@ -11,7 +11,7 @@
 use Drupal\system\Annotation\ImageToolkit;
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Image\ImageInterface;
-use Drupal\system\Plugin\ImageToolkitInterface;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 
 /**
  * Defines a Test toolkit for image manipulation within Drupal.
diff --git a/core/tests/Drupal/Tests/Core/Image/ImageTest.php b/core/tests/Drupal/Tests/Core/Image/ImageTest.php
index c96f4c9..ba0033a 100644
--- a/core/tests/Drupal/Tests/Core/Image/ImageTest.php
+++ b/core/tests/Drupal/Tests/Core/Image/ImageTest.php
@@ -25,7 +25,7 @@ class ImageTest extends UnitTestCase {
   /**
    * Image toolkit.
    *
-   * @var \Drupal\system\Plugin\ImageToolkitInterface
+   * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
    */
   protected $toolkit;
 
-- 
1.8.3.1

