diff --git a/core/core.services.yml b/core/core.services.yml
index 2f04124..900acdb 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -764,7 +764,8 @@ services:
       - { name: event_subscriber }
   image.toolkit.manager:
     class: Drupal\Core\ImageToolkit\ImageToolkitManager
-    arguments: ['@container.namespaces', '@cache.discovery', '@config.factory', '@module_handler', '@image.toolkit.operation.manager', '@logger.channel.image']
+    arguments: ['@config.factory']
+    parent: default_plugin_manager
   image.toolkit.operation.manager:
     class: Drupal\Core\ImageToolkit\ImageToolkitOperationManager
     arguments: ['@logger.channel.image']
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
index 1a5c19b..d56a560 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
@@ -8,6 +8,8 @@
 namespace Drupal\Core\ImageToolkit;
 
 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Image\ImageInterface;
 use Drupal\Core\Plugin\PluginBase;
 use Psr\Log\LoggerInterface;
@@ -15,6 +17,13 @@
 abstract class ImageToolkitBase extends PluginBase implements ImageToolkitInterface {
 
   /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
    * Image object this toolkit instance is tied to.
    *
    * @var \Drupal\Core\Image\ImageInterface
@@ -49,16 +58,36 @@
    *   The toolkit operation manager.
    * @param \Psr\Log\LoggerInterface $logger
    *   A logger instance.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImageToolkitOperationManagerInterface $operation_manager, LoggerInterface $logger) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImageToolkitOperationManagerInterface $operation_manager, LoggerInterface $logger, ConfigFactoryInterface $config_factory) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->operationManager = $operation_manager;
     $this->logger = $logger;
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    return array();
   }
 
   /**
    * {@inheritdoc}
    */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function setImage(ImageInterface $image) {
     if ($this->image) {
       throw new \BadMethodCallException(__METHOD__ . '() may only be called once');
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
index b50331a..c20da37 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\Core\ImageToolkit;
 
-use Drupal\Component\Plugin\PluginInspectionInterface;
-use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Image\ImageInterface;
 
 /**
@@ -44,21 +44,7 @@
  * An image toolkit provides common image file manipulations like scaling,
  * cropping, and rotating.
  */
-interface ImageToolkitInterface extends PluginInspectionInterface {
-
-  /**
-   * Retrieves the toolkit's settings form.
-   *
-   * @see system_image_toolkit_settings()
-   */
-  public function settingsForm();
-
-  /**
-   * Handles submissions for toolkit's settings form.
-   *
-   * @see system_image_toolkit_settings_submit()
-   */
-  public function settingsFormSubmit($form, FormStateInterface $form_state);
+interface ImageToolkitInterface extends ContainerFactoryPluginInterface, PluginFormInterface {
 
   /**
    * Sets the image object that this toolkit instance is tied to.
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
index 270f870..0c9db14 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
@@ -11,8 +11,6 @@
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\Component\Plugin\Factory\DefaultFactory;
-use Psr\Log\LoggerInterface;
 
 /**
  * Manages toolkit plugins.
@@ -27,20 +25,6 @@ class ImageToolkitManager extends DefaultPluginManager {
   protected $configFactory;
 
   /**
-   * The image toolkit operation manager.
-   *
-   * @var \Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface
-   */
-  protected $operationManager;
-
-  /**
-   * A logger instance.
-   *
-   * @var \Psr\Log\LoggerInterface
-   */
-  protected $logger;
-
-  /**
    * Constructs the ImageToolkitManager object.
    *
    * @param \Traversable $namespaces
@@ -48,22 +32,16 @@ class ImageToolkitManager extends DefaultPluginManager {
    *   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\Config\ConfigFactoryInterface $config_factory
-   *   The config factory.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
-   * @param \Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface $operation_manager
-   *   The toolkit operation manager.
-   * @param \Psr\Log\LoggerInterface $logger
-   *   A logger instance.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, ImageToolkitOperationManagerInterface $operation_manager, LoggerInterface $logger) {
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory) {
     parent::__construct('Plugin/ImageToolkit', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\Annotation\ImageToolkit');
 
     $this->setCacheBackend($cache_backend, 'image_toolkit_plugins');
     $this->configFactory = $config_factory;
-    $this->operationManager = $operation_manager;
-    $this->logger = $logger;
   }
 
   /**
@@ -120,13 +98,4 @@ public function getAvailableToolkits() {
     return $output;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function createInstance($plugin_id, array $configuration = array()) {
-    $plugin_definition = $this->getDefinition($plugin_id);
-    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
-    return new $plugin_class($configuration, $plugin_id, $plugin_definition, $this->operationManager, $this->logger);
-  }
-
 }
diff --git a/core/modules/system/src/Form/ImageToolkitForm.php b/core/modules/system/src/Form/ImageToolkitForm.php
index 69032f6..20aa615 100644
--- a/core/modules/system/src/Form/ImageToolkitForm.php
+++ b/core/modules/system/src/Form/ImageToolkitForm.php
@@ -87,7 +87,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
           ),
         ),
       );
-      $form['image_toolkit_settings'][$id] += $toolkit->settingsForm();
+      $form['image_toolkit_settings'][$id] += $toolkit->buildConfigurationForm($form, $form_state);
     }
 
     return parent::buildForm($form, $form_state);
@@ -96,6 +96,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   /**
    * {@inheritdoc}
    */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    parent::validateForm($form, $form_state);
+
+    // Call the form validation handler for each of the toolkits.
+    foreach ($this->availableToolkits as $toolkit) {
+      $toolkit->validateConfigurationForm($form, $form_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->config('system.image')
       ->set('toolkit', $form_state->getValue('image_toolkit'))
@@ -103,7 +115,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // Call the form submit handler for each of the toolkits.
     foreach ($this->availableToolkits as $toolkit) {
-      $toolkit->settingsFormSubmit($form, $form_state);
+      $toolkit->submitConfigurationForm($form, $form_state);
     }
 
     parent::submitForm($form, $form_state);
diff --git a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
index 1fd0c77..863a1a4 100644
--- a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\ImageToolkit\ImageToolkitBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines the GD2 toolkit for image manipulation within Drupal.
@@ -36,6 +37,20 @@ class GDToolkit extends ImageToolkitBase {
   protected $type;
 
   /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('image.toolkit.operation.manager'),
+      $container->get('logger.channel.image'),
+      $container->get('config.factory')
+    );
+  }
+
+  /**
    * Sets the GD image resource.
    *
    * @param resource $resource
@@ -61,14 +76,15 @@ public function getResource() {
   /**
    * {@inheritdoc}
    */
-  public function settingsForm() {
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
     $form['image_jpeg_quality'] = array(
       '#type' => 'number',
       '#title' => t('JPEG quality'),
       '#description' => t('Define the image quality for JPEG manipulations. Ranges from 0 to 100. Higher values mean better image quality but bigger files.'),
       '#min' => 0,
       '#max' => 100,
-      '#default_value' => \Drupal::config('system.image.gd')->get('jpeg_quality'),
+      '#default_value' => $this->configFactory->get('system.image.gd')->get('jpeg_quality'),
       '#field_suffix' => t('%'),
     );
     return $form;
@@ -77,8 +93,9 @@ public function settingsForm() {
   /**
    * {@inheritdoc}
    */
-  public function settingsFormSubmit($form, FormStateInterface $form_state) {
-    \Drupal::config('system.image.gd')
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::submitConfigurationForm($form, $form_state);
+    $this->configFactory->get('system.image.gd')
       ->set('jpeg_quality', $form_state->getValue(array('gd', 'image_jpeg_quality')))
       ->save();
   }
@@ -128,7 +145,7 @@ public function save($destination) {
       return FALSE;
     }
     if ($this->getType() == IMAGETYPE_JPEG) {
-      $success = $function($this->getResource(), $destination, \Drupal::config('system.image.gd')->get('jpeg_quality'));
+      $success = $function($this->getResource(), $destination, $this->configFactory->get('system.image.gd')->get('jpeg_quality'));
     }
     else {
       // Always save PNG images with full transparency.
diff --git a/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php b/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php
index a57c756..7d549b7 100644
--- a/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php
+++ b/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php
@@ -63,6 +63,9 @@ function testToolkitSetupForm() {
     $this->assertFieldByName('test[test_parameter]', '10');
 
     // Test changing the test toolkit parameter.
+    $edit = array('test[test_parameter]' => '0');
+    $this->drupalPostForm(NULL, $edit, 'Save configuration');
+    $this->assertText(t('Test parameter should be different from 0.'), 'Validation error displayed.');
     $edit = array('test[test_parameter]' => '20');
     $this->drupalPostForm(NULL, $edit, 'Save configuration');
     $this->assertEqual(\Drupal::config('system.image.test_toolkit')->get('test_parameter'), '20');
diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
index 3c1ceec..8fccaea 100644
--- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
@@ -8,8 +8,13 @@
 namespace Drupal\image_test\Plugin\ImageToolkit;
 
 use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\ImageToolkit\ImageToolkitBase;
+use Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface;
+use Drupal\Core\State\StateInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines a Test toolkit for image manipulation within Drupal.
@@ -22,6 +27,13 @@
 class TestToolkit extends ImageToolkitBase {
 
   /**
+   * The state service.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
    * Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
    *
    * @var int
@@ -43,9 +55,46 @@ class TestToolkit extends ImageToolkitBase {
   protected $height;
 
   /**
+   * Constructs a TestToolkit object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface $operation_manager
+   *   The toolkit operation manager.
+   * @param \Psr\Log\LoggerInterface $logger
+   *   A logger instance.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImageToolkitOperationManagerInterface $operation_manager, LoggerInterface $logger, ConfigFactoryInterface $config_factory, StateInterface $state) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $operation_manager, $logger, $config_factory);
+    $this->state = $state;
+  }
+
+  /**
    * {@inheritdoc}
    */
-  public function settingsForm() {
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('image.toolkit.operation.manager'),
+      $container->get('logger.channel.image'),
+      $container->get('config.factory'),
+      $container->get('state')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
     $this->logCall('settings', func_get_args());
     $form['test_parameter'] = array(
       '#type' => 'number',
@@ -53,7 +102,7 @@ public function settingsForm() {
       '#description' => $this->t('A toolkit parameter for testing purposes.'),
       '#min' => 0,
       '#max' => 100,
-      '#default_value' => \Drupal::config('system.image.test_toolkit')->get('test_parameter'),
+      '#default_value' => $this->configFactory->get('system.image.test_toolkit')->get('test_parameter'),
     );
     return $form;
   }
@@ -61,8 +110,18 @@ public function settingsForm() {
   /**
    * {@inheritdoc}
    */
-  public function settingsFormSubmit($form, FormStateInterface $form_state) {
-    \Drupal::config('system.image.test_toolkit')
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    if ($form_state['values']['test']['test_parameter'] == 0) {
+      $form_state->setErrorByName('test][test_parameter', $this->t('Test parameter should be different from 0.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::submitConfigurationForm($form, $form_state);
+    $this->configFactory->get('system.image.test_toolkit')
       ->set('test_parameter', $form_state->getValue(array('test', 'test_parameter')))
       ->save();
   }
@@ -104,7 +163,7 @@ public function save($destination) {
    * @see \Drupal\system\Tests\Image\ToolkitTestBase::imageTestGetAllCalls()
    */
   protected function logCall($op, $args) {
-    $results = \Drupal::state()->get('image_test.results') ?: array();
+    $results = $this->state->get('image_test.results') ?: array();
     $results[$op][] = $args;
     // A call to apply is also logged under its operation name whereby the
     // array of arguments are logged as separate arguments, this because at the
@@ -113,7 +172,7 @@ protected function logCall($op, $args) {
       $operation = array_shift($args);
       $results[$operation][] = array_values(reset($args));
     }
-    \Drupal::state()->set('image_test.results', $results);
+    $this->state->set('image_test.results', $results);
   }
 
   /**
