diff --git a/includes/plugins.inc b/includes/plugins.inc
index afb893a..d22a3ac 100644
--- a/includes/plugins.inc
+++ b/includes/plugins.inc
@@ -266,7 +266,8 @@ function views_views_plugins() {
       'views_query' => array(
         'title' => t('SQL Query'),
         'help' => t('Query will be generated and run using the Drupal database API.'),
-        'handler' => 'views_plugin_query_default'
+        'handler' => 'views_plugin_query_default',
+        'class' => 'Drupal\views\Plugin\Query\SqlQuery',
       ),
     ),
     'cache' => array(
diff --git a/lib/Drupal/views/Plugin/Discovery/ViewsDiscovery.php b/lib/Drupal/views/Plugin/Discovery/ViewsDiscovery.php
new file mode 100644
index 0000000..8d5176a
--- /dev/null
+++ b/lib/Drupal/views/Plugin/Discovery/ViewsDiscovery.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Discovery\ViewsDiscovery.
+ */
+
+namespace Drupal\views\Plugin\Discovery;
+use Drupal\Core\Plugin\Discovery\HookDiscovery;
+
+/**
+ * Discovery interface which supports the hook_views_plugins mechanism.
+ */
+class ViewsDiscovery extends HookDiscovery {
+  /**
+   * The plugin type in views which should be discovered, for example query.
+   *
+   * @var string
+   */
+  protected $viewsPluginType;
+
+  /**
+   * Constructs a Drupal\views\Plugin\Discovery\ViewsDiscovery object.
+   *
+   * @param string $hook
+   *   The Drupal hook that a module can implement in order to interface to
+   *   this discovery class.
+   * @param string $plugin_type
+   *   The plugin type in views which should be discovered, for example query.
+   */
+  function __construct($hook, $plugin_type) {
+    $this->viewsPluginType = $plugin_type;
+    parent::__construct($hook);
+  }
+
+  /**
+   * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions().
+   */
+  public function getDefinitions() {
+    $definitions = module_invoke_all($this->hook);
+    drupal_alter($this->hook, $definitions);
+    return $definitions[$this->viewsPluginType];
+  }
+}
diff --git a/lib/Drupal/views/Plugin/Plugin.php b/lib/Drupal/views/Plugin/Plugin.php
new file mode 100644
index 0000000..d292c37
--- /dev/null
+++ b/lib/Drupal/views/Plugin/Plugin.php
@@ -0,0 +1,438 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Plugin.
+ */
+
+namespace Drupal\views\Plugin;
+
+use Drupal\views\ViewsObject;
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\views\Plugin\PluginInterface;
+
+abstract class Plugin extends PluginBase implements PluginInterface {
+  /**
+   * Except for displays, options for the object will be held here.
+   */
+  var $options = array();
+
+  /**
+   * The top object of a view.
+   *
+   * @var view
+   */
+  var $view = NULL;
+
+  /**
+   * Handler's definition
+   *
+   * @var array
+   */
+  var $definition;
+
+  /**
+   * Information about options for all kinds of purposes will be held here.
+   * @code
+   * 'option_name' => array(
+   *  - 'default' => default value,
+   *  - 'translatable' => (optional) TRUE/FALSE (wrap in t() on export if true),
+   *  - 'contains' => (optional) array of items this contains, with its own
+   *      defaults, etc. If contains is set, the default will be ignored and
+   *      assumed to be array().
+   *  - 'bool' => (optional) TRUE/FALSE Is the value a boolean value. This will
+   *      change the export format to TRUE/FALSE instead of 1/0.
+   *  - 'export' => (optional) FALSE or a callback for special export handling
+   *      if necessary.
+   *  - 'unpack_translatable' => (optional) callback for special handling for
+   *      translating data within the option, if necessary.
+   *  ),
+   *
+   * @return array
+   *   Returns the options of this handler/plugin.
+   *
+   * @see Drupal\views\ViewsObject::export_option()
+   * @see Drupal\views\ViewsObject::unpack_translatable()
+   */
+  function option_definition() { return array(); }
+
+  /**
+   * Views handlers use a special construct function so that we can more
+   * easily construct them with variable arguments.
+   */
+  function construct() { $this->set_default_options(); }
+
+  /**
+   * Set default options on this object. Called by the constructor in a
+   * complex chain to deal with backward compatibility.
+   *
+   * @deprecated since views2
+   */
+  function options(&$options) { }
+
+  /**
+   * Set default options.
+   * For backward compatibility, it sends the options array; this is a
+   * feature that will likely disappear at some point.
+   */
+  function set_default_options() {
+    $this->_set_option_defaults($this->options, $this->option_definition());
+
+    // Retained for complex defaults plus backward compatibility.
+    $this->options($this->options);
+  }
+
+  function _set_option_defaults(&$storage, $options, $level = 0) {
+    foreach ($options as $option => $definition) {
+      if (isset($definition['contains']) && is_array($definition['contains'])) {
+        $storage[$option] = array();
+        $this->_set_option_defaults($storage[$option], $definition['contains'], $level++);
+      }
+      elseif (!empty($definition['translatable']) && !empty($definition['default'])) {
+        $storage[$option] = t($definition['default']);
+      }
+      else {
+        $storage[$option] = isset($definition['default']) ? $definition['default'] : NULL;
+      }
+    }
+  }
+
+  /**
+   * Unpack options over our existing defaults, drilling down into arrays
+   * so that defaults don't get totally blown away.
+   */
+  function unpack_options(&$storage, $options, $definition = NULL, $all = TRUE, $check = TRUE, $localization_keys = array()) {
+    if ($check && !is_array($options)) {
+      return;
+    }
+
+    if (!isset($definition)) {
+      $definition = $this->option_definition();
+    }
+
+    if (!empty($this->view)) {
+      // Ensure we have a localization plugin.
+      $this->view->init_localization();
+
+      // Set up default localization keys. Handlers and such set this for us
+      if (empty($localization_keys) && isset($this->localization_keys)) {
+        $localization_keys = $this->localization_keys;
+      }
+      // but plugins don't because there isn't a common init() these days.
+      else if (!empty($this->is_plugin)) {
+        if ($this->plugin_type != 'display') {
+          $localization_keys = array($this->view->current_display);
+          $localization_keys[] = $this->plugin_type;
+        }
+      }
+    }
+
+    foreach ($options as $key => $value) {
+      if (is_array($value)) {
+        // Ignore arrays with no definition.
+        if (!$all && empty($definition[$key])) {
+          continue;
+        }
+
+        if (!isset($storage[$key]) || !is_array($storage[$key])) {
+          $storage[$key] = array();
+        }
+
+        // If we're just unpacking our known options, and we're dropping an
+        // unknown array (as might happen for a dependent plugin fields) go
+        // ahead and drop that in.
+        if (!$all && isset($definition[$key]) && !isset($definition[$key]['contains'])) {
+          $storage[$key] = $value;
+          continue;
+        }
+
+        $this->unpack_options($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE, array_merge($localization_keys, array($key)));
+      }
+      // Don't localize strings during editing. When editing, we need to work with
+      // the original data, not the translated version.
+      else if (empty($this->view->editing) && !empty($definition[$key]['translatable']) && !empty($value) || !empty($definition['contains'][$key]['translatable']) && !empty($value)) {
+        if (!empty($this->view) && $this->view->is_translatable()) {
+          // Allow other modules to make changes to the string before it's
+          // sent for translation.
+          // The $keys array is built from the view name, any localization keys
+          // sent in, and the name of the property being processed.
+          $format = NULL;
+          if (isset($definition[$key]['format_key']) && isset($options[$definition[$key]['format_key']])) {
+            $format = $options[$definition[$key]['format_key']];
+          }
+          $translation_data = array(
+            'value' => $value,
+            'format' => $format,
+            'keys' => array_merge(array($this->view->name), $localization_keys, array($key)),
+          );
+          $storage[$key] = $this->view->localization_plugin->translate($translation_data);
+        }
+        // Otherwise, this is a code-based string, so we can use t().
+        else {
+          $storage[$key] = t($value);
+        }
+      }
+      else if ($all || !empty($definition[$key])) {
+        $storage[$key] = $value;
+      }
+    }
+  }
+
+  /**
+   * Let the handler know what its full definition is.
+   */
+  function set_definition($definition) {
+    $this->definition = $definition;
+    if (isset($definition['field'])) {
+      $this->real_field = $definition['field'];
+    }
+  }
+
+  function destroy() {
+    if (isset($this->view)) {
+      unset($this->view);
+    }
+
+    if (isset($this->display)) {
+      unset($this->display);
+    }
+
+    if (isset($this->query)) {
+      unset($this->query);
+    }
+  }
+
+  function export_options($indent, $prefix) {
+    $output = '';
+    foreach ($this->option_definition() as $option => $definition) {
+      $output .= $this->export_option($indent, $prefix, $this->options, $option, $definition, array());
+    }
+
+    return $output;
+  }
+
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // Do not export options for which we have no settings.
+    if (!isset($storage[$option])) {
+      return;
+    }
+
+    if (isset($definition['export'])) {
+      if ($definition['export'] === FALSE) {
+        return;
+      }
+
+      // Special handling for some items
+      if (method_exists($this, $definition['export'])) {
+        return $this->{$definition['export']}($indent, $prefix, $storage, $option, $definition, $parents);
+      }
+    }
+
+    // Add the current option to the parents tree.
+    $parents[] = $option;
+    $output = '';
+
+    // If it has child items, export those separately.
+    if (isset($definition['contains'])) {
+      foreach ($definition['contains'] as $sub_option => $sub_definition) {
+        $output .= $this->export_option($indent, $prefix, $storage[$option], $sub_option, $sub_definition, $parents);
+      }
+    }
+    // Otherwise export just this item.
+    else {
+      $default = isset($definition['default']) ? $definition['default'] : NULL;
+      $value = $storage[$option];
+      if (isset($definition['bool'])) {
+        $value = (bool) $value;
+      }
+
+      if ($value !== $default) {
+        $output .= $indent . $prefix . "['" . implode("']['", $parents) . "'] = ";
+        if (isset($definition['bool'])) {
+          $output .= empty($storage[$option]) ? 'FALSE' : 'TRUE';
+        }
+        else {
+          $output .= views_var_export($storage[$option], $indent);
+        }
+
+        $output .= ";\n";
+      }
+    }
+    return $output;
+  }
+
+  /**
+   * Unpacks each handler to store translatable texts.
+   */
+  function unpack_translatables(&$translatable, $parents = array()) {
+    foreach ($this->option_definition() as $option => $definition) {
+      $this->unpack_translatable($translatable, $this->options, $option, $definition, $parents, array());
+    }
+  }
+
+  /**
+   * Unpack a single option definition.
+   *
+   * This function run's through all suboptions recursive.
+   *
+   * @param $translatable
+   *   Stores all available translatable items.
+   * @param $storage
+   * @param $option
+   * @param $definition
+   * @param $parents
+   * @param $keys
+   */
+  function unpack_translatable(&$translatable, $storage, $option, $definition, $parents, $keys = array()) {
+    // Do not export options for which we have no settings.
+    if (!isset($storage[$option])) {
+      return;
+    }
+
+    // Special handling for some items
+    if (isset($definition['unpack_translatable']) && method_exists($this, $definition['unpack_translatable'])) {
+      return $this->{$definition['unpack_translatable']}($translatable, $storage, $option, $definition, $parents, $keys);
+    }
+
+    if (isset($definition['translatable'])) {
+      if ($definition['translatable'] === FALSE) {
+        return;
+      }
+    }
+
+    // Add the current option to the parents tree.
+    $parents[] = $option;
+
+    // If it has child items, unpack those separately.
+    if (isset($definition['contains'])) {
+      foreach ($definition['contains'] as $sub_option => $sub_definition) {
+        $translation_keys = array_merge($keys, array($sub_option));
+        $this->unpack_translatable($translatable, $storage[$option], $sub_option, $sub_definition, $parents, $translation_keys);
+      }
+    }
+
+    // @todo Figure out this double definition stuff.
+    $options = $storage[$option];
+    if (is_array($options)) {
+      foreach ($options as $key => $value) {
+        $translation_keys = array_merge($keys, array($key));
+        if (is_array($value)) {
+          $this->unpack_translatable($translatable, $options, $key, $definition, $parents, $translation_keys);
+        }
+        else if (!empty($definition[$key]['translatable']) && !empty($value)) {
+          // Build source data and add to the array
+          $format = NULL;
+          if (isset($definition['format_key']) && isset($options[$definition['format_key']])) {
+            $format = $options[$definition['format_key']];
+          }
+          $translatable[] = array(
+            'value' => $value,
+            'keys' => $translation_keys,
+            'format' => $format,
+          );
+        }
+      }
+    }
+    else if (!empty($definition['translatable']) && !empty($options)) {
+      $value = $options;
+      // Build source data and add to the array
+      $format = NULL;
+      if (isset($definition['format_key']) && isset($options[$definition['format_key']])) {
+        $format = $options[$definition['format_key']];
+      }
+      $translatable[] = array(
+        'value' => $value,
+        'keys' => isset($translation_keys) ? $translation_keys : $parents,
+        'format' => $format,
+      );
+    }
+  }
+
+  /**
+   * The plugin type of this plugin, for example style or query.
+   */
+  var $plugin_type = NULL;
+
+  /**
+   * The plugin name of this plugin, for example table or full.
+   */
+  var $plugin_name = NULL;
+
+  /**
+   * Init will be called after construct, when the plugin is attached to a
+   * view and a display.
+   */
+
+  /**
+   * Provide a form to edit options for this plugin.
+   */
+  function options_form(&$form, &$form_state) {
+    // Some form elements belong in a fieldset for presentation, but can't
+    // be moved into one because of the form_state['values'] hierarchy. Those
+    // elements can add a #fieldset => 'fieldset_name' property, and they'll
+    // be moved to their fieldset during pre_render.
+    $form['#pre_render'][] = 'views_ui_pre_render_add_fieldset_markup';
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Handle any special handling on the validate form.
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  /**
+   * Add anything to the query that we might need to.
+   */
+  function query() { }
+
+  /**
+   * Provide a full list of possible theme templates used by this style.
+   */
+  function theme_functions() {
+    return views_theme_functions($this->definition['theme'], $this->view, $this->display);
+  }
+
+  /**
+   * Provide a list of additional theme functions for the theme information page
+   */
+  function additional_theme_functions() {
+    $funcs = array();
+    if (!empty($this->definition['additional themes'])) {
+      foreach ($this->definition['additional themes'] as $theme => $type) {
+        $funcs[] = views_theme_functions($theme, $this->view, $this->display);
+      }
+    }
+    return $funcs;
+  }
+
+  /**
+   * Validate that the plugin is correct and can be saved.
+   *
+   * @return
+   *   An array of error strings to tell the user what is wrong with this
+   *   plugin.
+   */
+  function validate() { return array(); }
+
+  /**
+   * Returns the summary of the settings in the display.
+   */
+  function summary_title() {
+    return t('Settings');
+  }
+  /**
+   * Return the human readable name of the display.
+   *
+   * This appears on the ui beside each plugin and beside the settings link.
+   */
+  function plugin_title() {
+    if (isset($this->definition['short title'])) {
+      return check_plain($this->definition['short title']);
+    }
+    return check_plain($this->definition['title']);
+  }
+}
diff --git a/lib/Drupal/views/Plugin/PluginInterface.php b/lib/Drupal/views/Plugin/PluginInterface.php
new file mode 100644
index 0000000..df20ac2
--- /dev/null
+++ b/lib/Drupal/views/Plugin/PluginInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\PluginInterface.
+ */
+
+namespace Drupal\views\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+
+interface PluginInterface extends PluginInspectionInterface {
+
+}
diff --git a/lib/Drupal/views/Plugin/Query/QueryInterface.php b/lib/Drupal/views/Plugin/Query/QueryInterface.php
new file mode 100644
index 0000000..3de8c2c
--- /dev/null
+++ b/lib/Drupal/views/Plugin/Query/QueryInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Query\QueryInterface.
+ */
+
+namespace Drupal\views\Plugin\Query;
+
+use Drupal\views\Plugin\PluginInterface;
+
+interface QueryInterface extends PluginInterface {
+
+}
diff --git a/plugins/views_plugin_query.inc b/lib/Drupal/views/Plugin/Query/QueryPlugin.php
similarity index 91%
rename from plugins/views_plugin_query.inc
rename to lib/Drupal/views/Plugin/Query/QueryPlugin.php
index 59982cd..f8c9f8e 100644
--- a/plugins/views_plugin_query.inc
+++ b/lib/Drupal/views/Plugin/Query/QueryPlugin.php
@@ -2,21 +2,15 @@
 
 /**
  * @file
- * Defines the base query class, which is the underlying layer in a View.
+ * Definition of Drupal\views\Plugin\QueryPlugin.
  */
 
-/**
- * @defgroup views_query_plugins Views query plugins
- * @{
- * A Views query plugin builds SQL to execute using the Drupal database API.
- *
- * @see hook_views_plugins()
- */
+namespace Drupal\views\Plugin\Query;
 
-/**
- * Object used to create a SELECT query.
- */
-class views_plugin_query extends views_plugin {
+use Drupal\views\Plugin\Plugin;
+use Drupal\views\Plugin\Query\QueryInterface;
+
+abstract class QueryPlugin extends Plugin implements QueryInterface {
   /**
    * A pager plugin that should be provided by the display.
    *
@@ -178,7 +172,3 @@ class views_plugin_query extends views_plugin {
     return FALSE;
   }
 }
-
-/**
- * @}
- */
diff --git a/lib/Drupal/views/Plugin/Query/QueryPluginManager.php b/lib/Drupal/views/Plugin/Query/QueryPluginManager.php
new file mode 100644
index 0000000..5872412
--- /dev/null
+++ b/lib/Drupal/views/Plugin/Query/QueryPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Query\QueryPluginManager.
+ */
+
+namespace Drupal\views\Plugin\Query;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugin\Discovery\ViewsDiscovery;
+
+class QueryPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'query');
+    $this->factory = new DefaultFactory($this->discovery);
+  }
+}
diff --git a/plugins/views_plugin_query_default.inc b/lib/Drupal/views/Plugin/Query/SqlQuery.php
similarity index 97%
rename from plugins/views_plugin_query_default.inc
rename to lib/Drupal/views/Plugin/Query/SqlQuery.php
index 6a12bef..9830121 100644
--- a/plugins/views_plugin_query_default.inc
+++ b/lib/Drupal/views/Plugin/Query/SqlQuery.php
@@ -2,19 +2,17 @@
 
 /**
  * @file
- * Defines the default query object.
+ * Definition of Drupal\views\Plugin\Query\SqlQuery.
  */
 
+namespace Drupal\views\Plugin\Query;
+
+use Drupal\views\Plugin\Query\QueryPlugin;
 use Drupal\Core\Database\Database;
 use Drupal\views\Join;
+use Exception;
 
-/**
- * Object used to create a SELECT query.
- *
- * @ingroup views_query_plugins
- */
-class views_plugin_query_default extends views_plugin_query {
-
+class SqlQuery extends QueryPlugin {
   /**
    * A list of tables in the order they should be added, keyed by alias.
    */
@@ -89,17 +87,17 @@ class views_plugin_query_default extends views_plugin_query {
    *
    * @var views_plugin_pager
    */
-   var $pager = NULL;
+  var $pager = NULL;
 
-   /**
-    * An array mapping table aliases and field names to field aliases.
-    */
-   var $field_aliases = array();
+  /**
+   * An array mapping table aliases and field names to field aliases.
+   */
+  var $field_aliases = array();
 
-   /**
-    * Query tags which will be passed over to the dbtng query object.
-    */
-   var $tags = array();
+  /**
+   * Query tags which will be passed over to the dbtng query object.
+   */
+  var $tags = array();
 
   /**
    * Is the view marked as not distinct.
@@ -145,16 +143,16 @@ class views_plugin_query_default extends views_plugin_query {
       'alias' => $base_table,
     );
 
-/**
- * -- we no longer want the base field to appear automatigically.
+    /**
+     * -- we no longer want the base field to appear automatigically.
     if ($base_field) {
-      $this->fields[$base_field] = array(
-        'table' => $base_table,
-        'field' => $base_field,
-        'alias' => $base_field,
-      );
+    $this->fields[$base_field] = array(
+    'table' => $base_table,
+    'field' => $base_field,
+    'alias' => $base_field,
+    );
     }
- */
+     */
 
     $this->count_field = array(
       'table' => $base_table,
@@ -286,6 +284,7 @@ class views_plugin_query_default extends views_plugin_query {
       '#default_value' => implode(', ', $this->options['query_tags']),
       '#element_validate' => array('views_element_validate_tags'),
     );
+    $form_state['build_info']['files']['foo'] = drupal_get_path('module', 'views') . '/lib/Drupal/views/Plugin/Query/SqlQuery.php';
   }
 
   /**
@@ -697,8 +696,8 @@ class views_plugin_query_default extends views_plugin_query {
 
       // Do we need to try to ensure a path?
       if ($join->left_table != $this->relationships[$relationship]['table'] &&
-          $join->left_table != $this->relationships[$relationship]['base'] &&
-          !isset($this->tables[$relationship][$join->left_table]['alias'])) {
+        $join->left_table != $this->relationships[$relationship]['base'] &&
+        !isset($this->tables[$relationship][$join->left_table]['alias'])) {
         $this->ensure_table($join->left_table, $relationship);
       }
 
@@ -1044,16 +1043,16 @@ class views_plugin_query_default extends views_plugin_query {
       'direction' => strtoupper($order)
     );
 
-	/**
- 	 * -- removing, this should be taken care of by field adding now.
+    /**
+     * -- removing, this should be taken care of by field adding now.
      * -- leaving commented because I am unsure.
-      // If grouping, all items in the order by must also be in the
-      // group by clause. Check $table to ensure that this is not a
-      // formula.
-      if ($this->groupby && $table) {
-        $this->add_groupby($as);
-      }
-    */
+    // If grouping, all items in the order by must also be in the
+    // group by clause. Check $table to ensure that this is not a
+    // formula.
+    if ($this->groupby && $table) {
+    $this->add_groupby($as);
+    }
+     */
   }
 
   /**
@@ -1641,3 +1640,4 @@ function views_element_validate_tags($element, &$form_state) {
     }
   }
 }
+
diff --git a/lib/Drupal/views/View.php b/lib/Drupal/views/View.php
index 715d730..d358301 100644
--- a/lib/Drupal/views/View.php
+++ b/lib/Drupal/views/View.php
@@ -8,6 +8,7 @@
 namespace Drupal\views;
 
 use Symfony\Component\HttpFoundation\Response;
+use Drupal\views\Plugin\Query\QueryPluginManager;
 
 /**
  * @defgroup views_objects Objects that represent a View or part of a view
@@ -909,7 +910,8 @@ class View extends ViewsDbObject {
 
     // Create and initialize the query object.
     $plugin = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
-    $this->query = views_get_plugin('query', $plugin);
+    $plugin_type = new QueryPluginManager();
+    $this->query = $plugin_type->createInstance($plugin);
 
     if (empty($this->query)) {
       return FALSE;
diff --git a/plugins/views_plugin_display.inc b/plugins/views_plugin_display.inc
index 97e3660..fa93f72 100644
--- a/plugins/views_plugin_display.inc
+++ b/plugins/views_plugin_display.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\views\View;
+use Drupal\views\Plugin\Query\QueryPluginType;
 
 /**
  * @defgroup views_display_plugins Views display plugins
@@ -871,7 +872,14 @@ class views_plugin_display extends views_plugin {
             $options = $options['options'];
           }
       }
-      $plugin = views_get_plugin($type, $name);
+
+      if ($type != 'query') {
+        $plugin = views_get_plugin($type, $name);
+      }
+      else {
+        $plugin_type = new QueryPluginType();
+        $plugin = $plugin_type->createInstance($name);
+      }
 
       if (!$plugin) {
         return;
diff --git a/views.info b/views.info
index 7e18bda..792c67d 100644
--- a/views.info
+++ b/views.info
@@ -225,8 +225,6 @@ files[] = plugins/views_plugin_pager_full.inc
 files[] = plugins/views_plugin_pager_mini.inc
 files[] = plugins/views_plugin_pager_none.inc
 files[] = plugins/views_plugin_pager_some.inc
-files[] = plugins/views_plugin_query.inc
-files[] = plugins/views_plugin_query_default.inc
 files[] = plugins/views_plugin_row.inc
 files[] = plugins/views_plugin_row_fields.inc
 files[] = plugins/views_plugin_row_rss_fields.inc
