diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index 8e60f00..1e7bad0 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -604,15 +604,54 @@ function hook_entity_field_info_alter(&$info, $entity_type) {
 }
 
 /**
- * Alter entity operations.
+ * Declares operations for an entity.
  *
+ * @see \Drupal\Core\Entity\EntityDefaultOperationsController
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *
+ * @return array
+ *   The structure is identical to that of the return value of
+ *   \Drupal\Core\Entity\EntityOperationsControllerInterface::getOperations().
+ */
+function hook_entity_operations(\Drupal\Core\Entity\EntityInterface $entity) {
+  $uri = $entity->uri();
+  $operations['translate'] = array(
+    'title' => t('Translate'),
+    'href' => $uri['path'] . '/translate',
+    'weight' => 50,
+  );
+
+  return $operations;
+}
+
+/**
+ * Declares operations for an entity of a specific type.
+ *
+ * @see \Drupal\Core\Entity\EntityDefaultOperationsController
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *
+ * @return array
+ *   The structure is identical to that of the return value of
+ *   \Drupal\Core\Entity\EntityOperationsControllerInterface::getOperations().
+ */
+function hook_ENTITY_TYPE_operations(\Drupal\Core\Entity\EntityInterface $entity) {
+  return array();
+}
+
+/**
+ * Alters entity operations.
+ *
+ * @see \Drupal\Core\Entity\EntityDefaultOperationsController
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity on which the linked operations will be performed.
  * @param array $operations
  *   Operations array as returned by
  *   \Drupal\Core\Entity\EntityStorageControllerInterface::getOperations().
- * @param \Drupal\Core\Entity\EntityInterface $entity
- *   The entity on which the linked operations will be performed.
  */
-function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) {
+function hook_entity_operations_alter(\Drupal\Core\Entity\EntityInterface $entity, array &$operations) {
   $uri = $entity->uri();
   $operations['translate'] = array(
     'title' => t('Translate'),
@@ -622,6 +661,20 @@ function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\Ent
 }
 
 /**
+ * Alters entity operations for a specific entity type.
+ *
+ * @see \Drupal\Core\Entity\EntityDefaultOperationsController
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity on which the linked operations will be performed.
+ * @param array $operations
+ *   Operations array as returned by
+ *   \Drupal\Core\Entity\EntityStorageControllerInterface::getOperations().
+ */
+function hook_ENTITY_TYPE_operations_alter(\Drupal\Core\Entity\EntityInterface $entity, array &$operations) {
+}
+
+/**
  * Control access to fields.
  *
  * This hook is invoked from \Drupal\Core\Entity\Field\Field::access() to
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php
index 0eb187a..54d62a8 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php
@@ -24,40 +24,4 @@ public function load() {
     return $entities;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    $uri = $entity->uri();
-
-    // Ensure the edit operation exists since it is access controlled.
-    if (isset($operations['edit'])) {
-      // For configuration entities edit path is the MENU_DEFAULT_LOCAL_TASK and
-      // therefore should be accessed by the short route.
-      $operations['edit']['href'] = $uri['path'];
-    }
-
-    if (isset($this->entityInfo['entity_keys']['status'])) {
-      if (!$entity->status()) {
-        $operations['enable'] = array(
-          'title' => t('Enable'),
-          'href' => $uri['path'] . '/enable',
-          'options' => $uri['options'],
-          'weight' => -10,
-        );
-      }
-      else {
-        $operations['disable'] = array(
-          'title' => t('Disable'),
-          'href' => $uri['path'] . '/disable',
-          'options' => $uri['options'],
-          'weight' => 40,
-        );
-      }
-    }
-
-    return $operations;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsController.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsController.php
new file mode 100644
index 0000000..00431f4
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityOperationsController.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\Entity\ConfigEntityOperationsController.
+ */
+
+namespace Drupal\Core\Config\Entity;
+
+use Drupal\Core\Entity\EntityDefaultsOperationsController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Defines a entity operations controller for config entities.
+ */
+class ConfigEntityOperationsController extends EntityDefaultsOperationsController {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwnOperations(EntityInterface $entity) {
+    $operations = parent::getOwnOperations($entity);
+
+    $uri = $entity->uri();
+    if ($entity instanceof ConfigEntityInterface) {
+      if (!$entity->status()) {
+        $operations['enable'] = array(
+          'title' => t('Enable'),
+          'href' => $uri['path'] . '/enable',
+          'options' => $uri['options'],
+          'weight' => -10,
+        );
+      }
+      else {
+        $operations['disable'] = array(
+          'title' => t('Disable'),
+          'href' => $uri['path'] . '/disable',
+          'options' => $uri['options'],
+          'weight' => 20,
+        );
+      }
+    }
+
+    return $operations;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityDefaultOperationsController.php b/core/lib/Drupal/Core/Entity/EntityDefaultOperationsController.php
new file mode 100644
index 0000000..82559c8
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityDefaultOperationsController.php
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\EntityDefaultOperationsController.
+ */
+
+namespace Drupal\Core\Entity;
+
+use Drupal\Core\Entity\EntityControllerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines a default entity operations controller.
+ */
+class EntityDefaultsOperationsController implements EntityOperationsControllerInterface, EntityControllerInterface {
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Creates a EntityDefaultsOperationsController object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
+    return new static($container->get('module_handler'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwnOperations(EntityInterface $entity) {
+    $uri = $entity->uri();
+    $operations = array();
+    $operations['edit'] = array(
+      'title' => t('Edit'),
+      'href' => $uri['path'] . '/edit',
+      'options' => $uri['options'],
+      'weight' => 10,
+    );
+    $operations['delete'] = array(
+      'title' => t('Delete'),
+      'href' => $uri['path'] . '/delete',
+      'options' => $uri['options'],
+      'weight' => 100,
+    );
+    return $operations;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOperations(EntityInterface $entity) {
+    // Collect all operations.
+    $operations = $this->getOwnOperations($entity);
+    $hooks = array($entity->entityType() . '_operations' , 'entity_operations');
+    foreach ($hooks as $hook) {
+      $operations = array_merge($operations, $this->moduleHandler->invokeAll($hook, $entity));
+    }
+
+    // Check whether the operations are accessible.
+    foreach ($operations as $key => $operation) {
+      if (!$entity->access($key)) {
+        unset($operations[$key]);
+      }
+    }
+
+    $this->moduleHandler->alter(array('entity_operations', $entity->entityType() . '_operations'), $entity, $operations);
+
+    return $operations;
+  }
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityListController.php b/core/lib/Drupal/Core/Entity/EntityListController.php
index 3b1b580..b6e3da4 100644
--- a/core/lib/Drupal/Core/Entity/EntityListController.php
+++ b/core/lib/Drupal/Core/Entity/EntityListController.php
@@ -32,6 +32,13 @@ class EntityListController implements EntityListControllerInterface, EntityContr
   protected $moduleHandler;
 
   /**
+   * The entity operations controller class.
+   *
+   * @var \Drupal\Core\Entity\EntityOperationsControllerInterface
+   */
+  protected $operations;
+
+  /**
    * The entity type name.
    *
    * @var string
@@ -62,6 +69,7 @@ public static function createInstance(ContainerInterface $container, $entity_typ
       $entity_type,
       $entity_info,
       $container->get('entity.manager')->getStorageController($entity_type),
+      $container->get('entity.manager')->getOperationsController($entity_type),
       $container->get('module_handler')
     );
   }
@@ -77,10 +85,14 @@ public static function createInstance(ContainerInterface $container, $entity_typ
    *   The entity storage controller class.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler to invoke hooks on.
+   * @param \Drupal\Core\Entity\EntityOperationsControllerInterface $operations
+   *   The entity operations controller class.
+
    */
-  public function __construct($entity_type, array $entity_info, EntityStorageControllerInterface $storage, ModuleHandlerInterface $module_handler) {
+  public function __construct($entity_type, array $entity_info, EntityStorageControllerInterface $storage, EntityOperationsControllerInterface $operations, ModuleHandlerInterface $module_handler) {
     $this->entityType = $entity_type;
     $this->storage = $storage;
+    $this->operations = $operations;
     $this->entityInfo = $entity_info;
     $this->moduleHandler = $module_handler;
   }
@@ -116,27 +128,7 @@ protected function getLabel(EntityInterface $entity) {
    * {@inheritdoc}
    */
   public function getOperations(EntityInterface $entity) {
-    $uri = $entity->uri();
-
-    $operations = array();
-    if ($entity->access('update')) {
-      $operations['edit'] = array(
-        'title' => t('Edit'),
-        'href' => $uri['path'] . '/edit',
-        'options' => $uri['options'],
-        'weight' => 10,
-      );
-    }
-    if ($entity->access('delete')) {
-      $operations['delete'] = array(
-        'title' => t('Delete'),
-        'href' => $uri['path'] . '/delete',
-        'options' => $uri['options'],
-        'weight' => 100,
-      );
-    }
-
-    return $operations;
+    return $this->operations->getOperations($entity);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 3060909..6861606 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -319,6 +319,18 @@ public function getAccessController($entity_type) {
   }
 
   /**
+   * Gets an entity type's operations controller.
+   *
+   * @return \Drupal\Core\Entity\EntityOperationsControllerInterface.
+   */
+  public function getOperationsController($entity_type) {
+    return $this->getController($entity_type, 'operations');
+  }
+
+  /**
+
+
+  /**
    * Creates a new controller instance.
    *
    * @param string $entity_type
diff --git a/core/lib/Drupal/Core/Entity/EntityOperationsControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityOperationsControllerInterface.php
new file mode 100644
index 0000000..9c95c29
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityOperationsControllerInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\EntityOperationsControllerInterface.
+ */
+
+namespace Drupal\Core\Entity;
+
+/**
+ * Defines an interface to list all operations of an entity.
+ */
+interface EntityOperationsControllerInterface {
+
+  /**
+   * Get all operations of a certain entity without alter/access checking.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to get it's operations.
+   *
+   * @return array
+   *   An array of operations.
+   */
+  public function getOwnOperations(EntityInterface $entity);
+
+  /**
+   * Get all operations of a certain entity with altering and access checking.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to get it's operations.
+   *
+   * @return array
+   *   An array of operations.
+   */
+  public function getOperations(EntityInterface $entity);
+
+}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
index b74c1d7..5613b7f 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
@@ -29,7 +29,8 @@
  *       "edit" = "Drupal\custom_block\CustomBlockTypeFormController",
  *       "delete" = "Drupal\custom_block\Form\CustomBlockTypeDeleteForm"
  *     },
- *     "list" = "Drupal\custom_block\CustomBlockTypeListController"
+ *     "list" = "Drupal\custom_block\CustomBlockTypeListController",
+ *     "operations" = "Drupal\Core\Config\Entity\ConfigEntityOperationsController"
  *   },
  *   config_prefix = "custom_block.type",
  *   bundle_of = "custom_block",
diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php
index e465455..7382403 100644
--- a/core/modules/block/lib/Drupal/block/Entity/Block.php
+++ b/core/modules/block/lib/Drupal/block/Entity/Block.php
@@ -29,7 +29,8 @@
  *     "form" = {
  *       "default" = "Drupal\block\BlockFormController",
  *       "delete" = "Drupal\block\Form\BlockDeleteForm"
- *     }
+ *     },
+ *     "operations" = "Drupal\Core\Config\Entity\ConfigEntityOperationsController"
  *   },
  *   config_prefix = "block.block",
  *   fieldable = FALSE,
diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Category.php b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
index 7f633fc..b58c826 100644
--- a/core/modules/contact/lib/Drupal/contact/Entity/Category.php
+++ b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
@@ -28,7 +28,8 @@
  *       "add" = "Drupal\contact\CategoryFormController",
  *       "edit" = "Drupal\contact\CategoryFormController",
  *       "delete" = "Drupal\contact\Form\CategoryDeleteForm"
- *     }
+ *     },
+ *     "operations" = "Drupal\Core\Config\Entity\ConfigEntityOperationsController"
  *   },
  *   uri_callback = "contact_category_uri",
  *   config_prefix = "contact.category",
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index dabe6e7..d170740 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -246,6 +246,31 @@ function field_entity_field_info($entity_type) {
 }
 
 /**
+ * Implements hook_entity_operations().
+ */
+function field_entity_operations(EntityInterface $entity) {
+  $operations = array();
+  $info = Drupal::entityManager()->getDefinition($entity->entityType());
+  if ($info['fieldable']) {
+    $uri = $entity->uri();
+    $operations['manage-fields'] = array(
+      'title' => t('Manage fields'),
+      'href' => $uri['path'] . '/fields',
+      'options' => $uri['options'],
+      'weight' => 15,
+    );
+    $operations['manage-display'] = array(
+      'title' => t('Manage display'),
+      'href' => $uri['path'] . '/display',
+      'options' => $uri['options'],
+      'weight' => 20,
+    );
+  }
+
+  return $operations;
+}
+
+/**
  * Generates an entity field definition for a configurable field.
  *
  * @param \Drupal\field\FieldInterface $field
diff --git a/core/modules/menu/lib/Drupal/menu/MenuListController.php b/core/modules/menu/lib/Drupal/menu/MenuListController.php
index 4c5a408..6b3da33 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuListController.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuListController.php
@@ -39,28 +39,6 @@ public function buildRow(EntityInterface $entity) {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    $uri = $entity->uri();
-
-    if (isset($operations['edit'])) {
-      $operations['edit']['title'] = t('Edit menu');
-      $operations['add'] = array(
-        'title' => t('Add link'),
-        'href' => $uri['path'] . '/add',
-        'options' => $uri['options'],
-        'weight' => 20,
-      );
-    }
-    if (isset($operations['delete'])) {
-      $operations['delete']['title'] = t('Delete menu');
-    }
-    return $operations;
-  }
-
-  /**
    * Overrides \Drupal\Core\Entity\EntityListController::render();
    */
   public function render() {
diff --git a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
index fb266fa..af4953d 100644
--- a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
+++ b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php
@@ -28,7 +28,8 @@
  *       "add" = "Drupal\picture\PictureMappingFormController",
  *       "delete" = "Drupal\picture\Form\PictureMappingDeleteForm",
  *       "duplicate" = "Drupal\picture\PictureMappingFormController"
- *     }
+ *     },
+ *    "operations" = "Drupal\picture\PictureMappingOperationsController"
  *   },
  *   list_path = "admin/config/media/picturemapping",
  *   config_prefix = "picture.mappings",
diff --git a/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php b/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php
index ffe4c0c..5594053 100644
--- a/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php
+++ b/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php
@@ -33,19 +33,4 @@ public function buildRow(EntityInterface $entity) {
     return $row + parent::buildRow($entity);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    $uri = $entity->uri();
-    $operations['duplicate'] = array(
-      'title' => t('Duplicate'),
-      'href' => $uri['path'] . '/duplicate',
-      'options' => $uri['options'],
-      'weight' => 15,
-    );
-    return $operations;
-  }
-
 }
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
index 392c3d8..ccac5ce 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
@@ -29,7 +29,8 @@
  *       "edit" = "Drupal\shortcut\ShortcutSetFormController",
  *       "customize" = "Drupal\shortcut\Form\SetCustomize",
  *       "delete" = "Drupal\shortcut\Form\ShortcutSetDeleteForm"
- *     }
+ *     },
+ *     "operations" = "Drupal\shortcut\ShortcutSetOperationsController"
  *   },
  *   config_prefix = "shortcut.set",
  *   entity_keys = {
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php
index 6215a87..ca66977 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php
@@ -24,25 +24,6 @@ public function buildHeader() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    $uri = $entity->uri();
-
-    if (isset($operations['edit'])) {
-      $operations['edit']['title'] = t('Edit menu');
-      $operations['edit']['href'] = $uri['path'] . '/edit';
-    }
-
-    $operations['list'] = array(
-      'title' => t('List links'),
-      'href' => $uri['path'],
-    );
-    return $operations;
-  }
-
-  /**
    * Overrides \Drupal\Core\Entity\EntityListController::buildRow().
    */
   public function buildRow(EntityInterface $entity) {
diff --git a/core/modules/system/lib/Drupal/system/Entity/Menu.php b/core/modules/system/lib/Drupal/system/Entity/Menu.php
index 7b2be7b..cd2d742 100644
--- a/core/modules/system/lib/Drupal/system/Entity/Menu.php
+++ b/core/modules/system/lib/Drupal/system/Entity/Menu.php
@@ -21,7 +21,8 @@
  *   module = "system",
  *   controllers = {
  *     "storage" = "Drupal\Core\Config\Entity\ConfigStorageController",
- *     "access" = "Drupal\system\MenuAccessController"
+ *     "access" = "Drupal\system\MenuAccessController",
+ *     "operations" = "Drupal\menu\MenuOperationsController"
  *   },
  *   config_prefix = "menu.menu",
  *   entity_keys = {
diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php
index 8529e87..6d6e593 100644
--- a/core/modules/user/lib/Drupal/user/Entity/Role.php
+++ b/core/modules/user/lib/Drupal/user/Entity/Role.php
@@ -27,7 +27,8 @@
  *     "form" = {
  *       "default" = "Drupal\user\RoleFormController",
  *       "delete" = "Drupal\user\Form\UserRoleDelete"
- *     }
+ *     },
+ *     "operations" = "Drupal\user\RoleOperationsController"
  *   },
  *   config_prefix = "user.role",
  *   entity_keys = {
diff --git a/core/modules/user/lib/Drupal/user/RoleListController.php b/core/modules/user/lib/Drupal/user/RoleListController.php
index 3e95aae..216ac6a 100644
--- a/core/modules/user/lib/Drupal/user/RoleListController.php
+++ b/core/modules/user/lib/Drupal/user/RoleListController.php
@@ -41,24 +41,6 @@ public function buildRow(EntityInterface $entity) {
   /**
    * {@inheritdoc}
    */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-
-    $operations['permissions'] = array(
-      'title' => t('Edit permissions'),
-      'href' => 'admin/people/permissions/' . $entity->id(),
-      'weight' => 20,
-    );
-    // Built-in roles could not be deleted or disabled.
-    if (in_array($entity->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
-      unset($operations['delete']);
-    }
-    return $operations;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php
index 33ac4de..a583664 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php
@@ -135,31 +135,6 @@ public function buildHeader() {
   /**
    * {@inheritdoc}
    */
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    $uri = $entity->uri();
-
-    $operations['clone'] = array(
-      'title' => t('Clone'),
-      'href' => $uri['path'] . '/clone',
-      'options' => $uri['options'],
-      'weight' => 15,
-    );
-
-    // Add AJAX functionality to enable/disable operations.
-    foreach (array('enable', 'disable') as $op) {
-      if (isset($operations[$op])) {
-        $operations[$op]['ajax'] = TRUE;
-        $operations[$op]['query']['token'] = drupal_get_token($op);
-      }
-    }
-
-    return $operations;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function buildOperations(EntityInterface $entity) {
     $build = parent::buildOperations($entity);
 
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index 7c41565..4efbcc0 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -105,6 +105,7 @@ function views_ui_entity_info(&$entity_info) {
       'delete' => 'Drupal\views_ui\ViewDeleteFormController',
       'break_lock' => 'Drupal\views_ui\Form\BreakLockForm',
     ),
+    'operations' => 'Drupal\views_ui\ViewOperationsController',
   );
 }
 
