diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc
index d09ee6964e2019d19bf8096ed195a6b99c9ccef8..e78ce67dacc03a9caf6201810330f1581a9a2abe 100644
--- a/core/modules/filter/filter.admin.inc
+++ b/core/modules/filter/filter.admin.inc
@@ -355,35 +355,3 @@ function filter_admin_format_form_submit($form, &$form_state) {
 
   $form_state['redirect'] = 'admin/config/content/formats';
 }
-
-/**
- * Page callback: Form constructor to confirm the text format deletion.
- *
- * @param $format
- *   An object representing a text format.
- *
- * @see filter_menu()
- * @see filter_admin_disable_submit()
- * @ingroup forms
- */
-function filter_admin_disable($form, &$form_state, $format) {
-  $form['#format'] = $format;
-
-  return confirm_form($form,
-    t('Are you sure you want to disable the text format %format?', array('%format' => $format->name)),
-    'admin/config/content/formats',
-    t('Disabled text formats are completely removed from the administrative interface, and any content stored with that format will not be displayed. This action cannot be undone.'),
-    t('Disable')
-  );
-}
-
-/**
- * Form submission handler for filter_admin_disable().
- */
-function filter_admin_disable_submit($form, &$form_state) {
-  $format = $form['#format'];
-  filter_format_disable($format);
-  drupal_set_message(t('Disabled text format %format.', array('%format' => $format->name)));
-
-  $form_state['redirect'] = 'admin/config/content/formats';
-}
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index c08555d5fa4e1d12b997770f2fb88f1cd3112c45..57ff8c2c33c0554fe98da008087a720998e7b089 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -149,32 +149,11 @@ function filter_menu() {
   );
   $items['admin/config/content/formats/%filter_format/disable'] = array(
     'title' => 'Disable text format',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('filter_admin_disable', 4),
-    'access callback' => '_filter_disable_format_access',
-    'access arguments' => array(4),
-    'file' => 'filter.admin.inc',
+    'route_name' => 'filter_admin_disable',
   );
   return $items;
 }
 
-/**
- * Access callback: Checks access for disabling text formats.
- *
- * @param $format
- *   A text format object.
- *
- * @return
- *   TRUE if the text format can be disabled by the current user, FALSE
- *   otherwise.
- *
- * @see filter_menu()
- */
-function _filter_disable_format_access($format) {
-  // The fallback format can never be disabled.
-  return user_access('administer filters') && ($format->format != filter_fallback_format());
-}
-
 /**
  * Loads a text format object from the database.
  *
@@ -193,28 +172,6 @@ function filter_format_load($format_id) {
   return isset($formats[$format_id]) ? $formats[$format_id] : FALSE;
 }
 
-/**
- * Disables a text format.
- *
- * There is no core facility to re-enable a disabled format. It is not deleted
- * to keep information for contrib and to make sure the format ID is never
- * reused. As there might be content using the disabled format, this would lead
- * to data corruption.
- *
- * @param $format
- *   The text format object to be disabled.
- */
-function filter_format_disable($format) {
-  $format->disable()->save();
-
-  // Allow modules to react on text format deletion.
-  module_invoke_all('filter_format_disable', $format);
-
-  // Clear the filter cache whenever a text format is disabled.
-  filter_formats_reset();
-  cache('filter')->deleteTags(array('filter_format' => $format->format));
-}
-
 /**
  * Determines if a text format exists.
  *
diff --git a/core/modules/filter/filter.routing.yml b/core/modules/filter/filter.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..de9e9cb75e5554d123d8357d63b2665ce43decfe
--- /dev/null
+++ b/core/modules/filter/filter.routing.yml
@@ -0,0 +1,6 @@
+filter_admin_disable:
+  pattern: '/admin/config/content/formats/{filter_format}/disable'
+  defaults:
+    _form: '\Drupal\filter\Form\DisableForm'
+  requirements:
+    _filter_disable_format_access: 'TRUE'
diff --git a/core/modules/filter/lib/Drupal/filter/Access/FormatDisableCheck.php b/core/modules/filter/lib/Drupal/filter/Access/FormatDisableCheck.php
new file mode 100644
index 0000000000000000000000000000000000000000..de5acea0a89c93f8224d430c4a2eba4985c2fc71
--- /dev/null
+++ b/core/modules/filter/lib/Drupal/filter/Access/FormatDisableCheck.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\filter\Access\FormatDisableCheck.
+ */
+
+namespace Drupal\filter\Access;
+
+use Drupal\Core\Access\AccessCheckInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Checks access for disabling text formats.
+ */
+class FormatDisableCheck implements AccessCheckInterface {
+
+  /**
+   * Implements \Drupal\Core\Access\AccessCheckInterface::applies().
+   */
+  public function applies(Route $route) {
+    return array_key_exists('_filter_disable_format_access', $route->getRequirements());
+  }
+
+  /**
+   * Implements \Drupal\Core\Access\AccessCheckInterface::access().
+   */
+  public function access(Route $route, Request $request) {
+    if ($format = $request->attributes->get('filter_format')) {
+      return user_access('administer filters') && ($format->format != filter_fallback_format());
+    }
+
+    return FALSE;
+  }
+
+}
diff --git a/core/modules/filter/lib/Drupal/filter/FilterBundle.php b/core/modules/filter/lib/Drupal/filter/FilterBundle.php
index 2c0a460cd2bf9727296a4db6a746b8ba81a8ee7a..b531e6a39d96294ee0a2dc897a3edc5cf4264860 100644
--- a/core/modules/filter/lib/Drupal/filter/FilterBundle.php
+++ b/core/modules/filter/lib/Drupal/filter/FilterBundle.php
@@ -21,6 +21,9 @@ class FilterBundle extends Bundle {
    */
   public function build(ContainerBuilder $container) {
     CacheFactory::registerBin($container, 'filter');
+
+    $container->register('access_check.filter_disable', 'Drupal\filter\Access\FormatDisableCheck')
+      ->addTag('access_check');
   }
 
 }
diff --git a/core/modules/filter/lib/Drupal/filter/Form/DisableForm.php b/core/modules/filter/lib/Drupal/filter/Form/DisableForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..49b71c874ca48d115f7ef0ba04a1181f95498c95
--- /dev/null
+++ b/core/modules/filter/lib/Drupal/filter/Form/DisableForm.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\filter\Form\DisableForm.
+ */
+
+namespace Drupal\filter\Form;
+
+use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\filter\Plugin\Core\Entity\FilterFormat;
+
+/**
+ * Provides the filter format disable form.
+ */
+class DisableForm extends ConfirmFormBase {
+
+  /**
+   * The format being disabled.
+   *
+   * @var \Drupal\filter\Plugin\Core\Entity\FilterFormat
+   */
+  protected $format;
+
+  /**
+   * Implements \Drupal\Core\Form\FormInterface::getFormID().
+   */
+  public function getFormID() {
+    return 'filter_admin_disable';
+  }
+
+  /**
+   * Implements \Drupal\Core\Form\ConfirmFormBase::getQuestion().
+   */
+  protected function getQuestion() {
+    return t('Are you sure you want to disable the text format %format?', array('%format' => $this->format->name));
+  }
+
+  /**
+   * Implements \Drupal\Core\Form\ConfirmFormBase::getCancelPath().
+   */
+  protected function getCancelPath() {
+    return 'admin/config/content/formats';
+  }
+
+  /**
+   * Overrides \Drupal\Core\Form\ConfirmFormBase::getConfirmText().
+   */
+  public function getConfirmText() {
+    return t('Disable');
+  }
+
+  /**
+   * Overrides \Drupal\Core\Form\ConfirmFormBase::getDescription().
+   */
+  public function getDescription() {
+    return t('Disabled text formats are completely removed from the administrative interface, and any content stored with that format will not be displayed. This action cannot be undone.');
+  }
+
+  /**
+   * Overrides \Drupal\Core\Form\FormInterface::buildForm().
+   */
+  public function buildForm(array $form, array &$form_state, FilterFormat $filter_format = NULL) {
+    $this->format = $filter_format;
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * Implements \Drupal\Core\Form\FormInterface::submitForm().
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    $this->format->disable()->save();
+    drupal_set_message(t('Disabled text format %format.', array('%format' => $this->format->name)));
+
+    $form_state['redirect'] = 'admin/config/content/formats';
+  }
+
+}
diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php
index 6dd76f9e67b7ce24fbf817f92c5cc4dfe0bc646a..13c26b5b33d48ea0adcd8a6503de6389f3597142 100644
--- a/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php
+++ b/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php
@@ -137,4 +137,20 @@ public static function sortFilters($a, $b) {
     return strnatcasecmp($a['name'], $b['name']);
   }
 
+  /**
+   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::disable().
+   */
+  public function disable() {
+    parent::disable();
+
+    // Allow modules to react on text format deletion.
+    module_invoke_all('filter_format_disable', $this);
+
+    // Clear the filter cache whenever a text format is disabled.
+    filter_formats_reset();
+    cache('filter')->deleteTags(array('filter_format' => $this->format));
+
+    return $this;
+  }
+
 }
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterCrudTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterCrudTest.php
index f516b0c4731abc63e1d32f9b37112c5ec4dec869..21dcbf091ec4dd2b50292561dd41f88f89ec1308 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterCrudTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterCrudTest.php
@@ -73,7 +73,7 @@ function testTextFormatCrud() {
     $this->verifyFilters($format);
 
     // Disable the text format.
-    filter_format_disable($format);
+    $format->disable()->save();
 
     $formats = filter_formats();
     $this->assertTrue(!isset($formats[$format->format]), 'filter_formats: Disabled text format no longer exists.');
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
index 969fac0c05c5ab721746d34e73bee6c4415b97a9..8667a5bef91fc5c868ec7f437bd22548781f5384 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
@@ -250,7 +250,7 @@ function testFormatWidgetPermissions() {
     $this->assertFieldByXPath("//textarea[@name='$body_value_key' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.');
 
     // Disable the text format used above.
-    filter_format_disable($this->disallowed_format);
+    $this->disallowed_format->disable()->save();
     $this->resetFilterCaches();
 
     // Log back in as the less privileged user and verify that the body field
@@ -293,7 +293,7 @@ function testFormatWidgetPermissions() {
     $this->assertUrl('node/' . $node->nid);
     foreach (filter_formats() as $format) {
       if ($format->format != filter_fallback_format()) {
-        filter_format_disable($format);
+        $format->disable()->save();
       }
     }