diff --git a/includes/plugins.inc b/includes/plugins.inc
index afb893a..b0ae803 100644
--- a/includes/plugins.inc
+++ b/includes/plugins.inc
@@ -19,7 +19,7 @@ function views_views_plugins() {
       'default' => array(
         'title' => t('Master'),
         'help' => t('Default settings for this view.'),
-        'handler' => 'views_plugin_display_default',
+        'handler' => 'Drupal\views\Plugins\views\display\DefaultDisplay',
         'theme' => 'views_view',
         'no ui' => TRUE,
         'no remove' => TRUE,
@@ -35,7 +35,7 @@ function views_views_plugins() {
       'page' => array(
         'title' => t('Page'),
         'help' => t('Display the view as a page, with a URL and menu links.'),
-        'handler' => 'views_plugin_display_page',
+        'handler' => 'Drupal\views\Plugins\views\display\PageDisplay',
         'theme' => 'views_view',
         'uses hook menu' => TRUE,
         'contextual links locations' => array('page'),
@@ -49,7 +49,7 @@ function views_views_plugins() {
       'block' => array(
         'title' => t('Block'),
         'help' => t('Display the view as a block.'),
-        'handler' => 'views_plugin_display_block',
+        'handler' => 'Drupal\views\Plugins\views\display\BlockDisplay',
         'theme' => 'views_view',
         'uses hook block' => TRUE,
         'contextual links locations' => array('block'),
@@ -63,7 +63,7 @@ function views_views_plugins() {
       'attachment' => array(
         'title' => t('Attachment'),
         'help' => t('Attachments added to other displays to achieve multiple views in the same view.'),
-        'handler' => 'views_plugin_display_attachment',
+        'handler' => 'Drupal\views\Plugins\views\display\AttachmentDisplay',
         'theme' => 'views_view',
         'contextual links locations' => array(),
         'use ajax' => TRUE,
@@ -75,7 +75,7 @@ function views_views_plugins() {
       'feed' => array(
         'title' => t('Feed'),
         'help' => t('Display the view as a feed, such as an RSS feed.'),
-        'handler' => 'views_plugin_display_feed',
+        'handler' => 'Drupal\views\Plugins\views\display\FeedDisplay',
         'uses hook menu' => TRUE,
         'use ajax' => FALSE,
         'use pager' => FALSE,
@@ -100,7 +100,7 @@ function views_views_plugins() {
       'default' => array(
         'title' => t('Empty display extender'),
         'help' => t('Default settings for this view.'),
-        'handler' => 'views_plugin_display_extender',
+        'handler' => 'Drupal\views\Plugins\views\display_extender\DisplayExtenderPlugin',
         // You can force the plugin to be enabled
         'enabled' => FALSE,
         'no ui' => TRUE,
@@ -111,7 +111,7 @@ function views_views_plugins() {
       'default' => array(
         'title' => t('Unformatted list'),
         'help' => t('Displays rows one after another.'),
-        'handler' => 'views_plugin_style_default',
+        'handler' => 'Drupal\views\Plugins\views\style\DefaultStyle',
         'theme' => 'views_view_unformatted',
         'uses row plugin' => TRUE,
         'uses row class' => TRUE,
@@ -123,7 +123,7 @@ function views_views_plugins() {
       'list' => array(
         'title' => t('HTML list'),
         'help' => t('Displays rows as an HTML list.'),
-        'handler' => 'views_plugin_style_list',
+        'handler' => 'Drupal\views\Plugins\views\style\ListStyle',
         'theme' => 'views_view_list',
         'uses row plugin' => TRUE,
         'uses row class' => TRUE,
@@ -134,7 +134,7 @@ function views_views_plugins() {
       'grid' => array(
         'title' => t('Grid'),
         'help' => t('Displays rows in a grid.'),
-        'handler' => 'views_plugin_style_grid',
+        'handler' => 'Drupal\views\Plugins\views\style\GridStyle',
         'theme' => 'views_view_grid',
         'uses fields' => FALSE,
         'uses row plugin' => TRUE,
@@ -146,7 +146,7 @@ function views_views_plugins() {
       'table' => array(
         'title' => t('Table'),
         'help' => t('Displays rows in a table.'),
-        'handler' => 'views_plugin_style_table',
+        'handler' => 'Drupal\views\Plugins\views\style\TableStyle',
         'theme' => 'views_view_table',
         'uses row plugin' => FALSE,
         'uses row class' => TRUE,
@@ -158,7 +158,7 @@ function views_views_plugins() {
       'default_summary' => array(
         'title' => t('List'),
         'help' => t('Displays the default summary as a list.'),
-        'handler' => 'views_plugin_style_summary',
+        'handler' => 'Drupal\views\Plugins\views\style\StyleSummaryPlugin',
         'theme' => 'views_view_summary',
         'type' => 'summary', // only shows up as a summary style
         'uses options' => TRUE,
@@ -167,7 +167,7 @@ function views_views_plugins() {
       'unformatted_summary' => array(
         'title' => t('Unformatted'),
         'help' => t('Displays the summary unformatted, with option for one after another or inline.'),
-        'handler' => 'views_plugin_style_summary_unformatted',
+        'handler' => 'Drupal\views\Plugins\views\style\UnformattedStyleSummary',
         'theme' => 'views_view_summary_unformatted',
         'type' => 'summary', // only shows up as a summary style
         'uses options' => TRUE,
@@ -176,7 +176,7 @@ function views_views_plugins() {
       'rss' => array(
         'title' => t('RSS Feed'),
         'help' => t('Generates an RSS feed from a view.'),
-        'handler' => 'views_plugin_style_rss',
+        'handler' => 'Drupal\views\Plugins\views\style\RssStyle',
         'theme' => 'views_view_rss',
         'uses row plugin' => TRUE,
         'uses options' => TRUE,
@@ -188,7 +188,7 @@ function views_views_plugins() {
       'fields' => array(
         'title' => t('Fields'),
         'help' => t('Displays the fields with an optional template.'),
-        'handler' => 'views_plugin_row_fields',
+        'handler' => 'Drupal\views\Plugins\views\row\FieldsRow',
         'theme' => 'views_view_fields',
         'uses fields' => TRUE,
         'uses options' => TRUE,
@@ -198,7 +198,7 @@ function views_views_plugins() {
       'rss_fields' => array(
         'title' => t('Fields'),
         'help' => t('Display fields as RSS items.'),
-        'handler' => 'views_plugin_row_rss_fields',
+        'handler' => 'Drupal\views\Plugins\views\row\RssFieldsRow',
         'theme' => 'views_view_row_rss',
         'uses fields' => TRUE,
         'uses options' => TRUE,
@@ -260,13 +260,14 @@ function views_views_plugins() {
     'query' => array(
       'parent' => array(
         'no ui' => TRUE,
-        'handler' => 'views_plugin_query',
+        'handler' => 'Drupal\views\Plugins\views\query\QueryPlugin',
         'parent' => '',
       ),
       '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\Plugins\views\query\SqlQuery',
       ),
     ),
     'cache' => array(
diff --git a/lib/Drupal/views/Plugins/Discovery/ViewsDiscovery.php b/lib/Drupal/views/Plugins/Discovery/ViewsDiscovery.php
new file mode 100644
index 0000000..bee04e9
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Discovery/ViewsDiscovery.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Discovery\ViewsDiscovery.
+ */
+
+namespace Drupal\views\Plugins\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 = parent::getDefinitions();
+    return $definitions[$this->viewsPluginType];
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/AccessPluginManager.php b/lib/Drupal/views/Plugins/Type/AccessPluginManager.php
new file mode 100644
index 0000000..340e8b1
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/AccessPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\AccessPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class AccessPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'access');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/ArgumentPluginManager.php b/lib/Drupal/views/Plugins/Type/ArgumentPluginManager.php
new file mode 100644
index 0000000..0d7419e
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/ArgumentPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\ArgumentPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class ArgumentPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'argument');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/CachePluginManager.php b/lib/Drupal/views/Plugins/Type/CachePluginManager.php
new file mode 100644
index 0000000..36a83e0
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/CachePluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\CachePluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class CachePluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'cache');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/DisplayExtenderPluginManager.php b/lib/Drupal/views/Plugins/Type/DisplayExtenderPluginManager.php
new file mode 100644
index 0000000..ff0f131
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/DisplayExtenderPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\DisplayExtenderPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class DisplayPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'display_extender');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/DisplayPluginManager.php b/lib/Drupal/views/Plugins/Type/DisplayPluginManager.php
new file mode 100644
index 0000000..f6a510f
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/DisplayPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\DisplayPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class DisplayPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'display');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/ExposedFormPluginManager.php b/lib/Drupal/views/Plugins/Type/ExposedFormPluginManager.php
new file mode 100644
index 0000000..66100a9
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/ExposedFormPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\ExposedFormPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class ExposedFormPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'exposed_form');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/HandlerPluginManager.php b/lib/Drupal/views/Plugins/Type/HandlerPluginManager.php
new file mode 100644
index 0000000..4fa54c8
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/HandlerPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\HandlerPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class HandlerPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'handler');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/LocalizationPluginManager.php b/lib/Drupal/views/Plugins/Type/LocalizationPluginManager.php
new file mode 100644
index 0000000..7cd69c6
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/LocalizationPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\LocalizationPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\views\Discovery\ViewsDiscovery;
+
+class LocalizationPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'localization');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/PagerPluginManager.php b/lib/Drupal/views/Plugins/Type/PagerPluginManager.php
new file mode 100644
index 0000000..053a425
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/PagerPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\PagerPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class PagerPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'pager');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/QueryPluginManager.php b/lib/Drupal/views/Plugins/Type/QueryPluginManager.php
new file mode 100644
index 0000000..1157986
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/QueryPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\QueryPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class QueryPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'query');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/RowPluginManager.php b/lib/Drupal/views/Plugins/Type/RowPluginManager.php
new file mode 100644
index 0000000..e98cadf
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/RowPluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\RowPluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class RowPluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'row');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/Type/StylePluginManager.php b/lib/Drupal/views/Plugins/Type/StylePluginManager.php
new file mode 100644
index 0000000..103b1f9
--- /dev/null
+++ b/lib/Drupal/views/Plugins/Type/StylePluginManager.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\Type\StylePluginManager.
+ */
+
+namespace Drupal\views\Plugins\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\views\Plugins\Discovery\ViewsDiscovery;
+
+class StylePluginManager extends PluginManagerBase {
+  public function __construct() {
+    $this->discovery = new ViewsDiscovery('views_plugins', 'style');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/Plugin.php b/lib/Drupal/views/Plugins/views/Plugin.php
new file mode 100644
index 0000000..bf7ca73
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/Plugin.php
@@ -0,0 +1,438 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\Plugin.
+ */
+
+namespace Drupal\views\Plugins\views;
+
+use Drupal\views\ViewsObject;
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\views\Plugin\PluginInterface;
+
+abstract class Plugin extends PluginBase {
+  /**
+   * 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/Plugins/views/PluginInterface.php b/lib/Drupal/views/Plugins/views/PluginInterface.php
new file mode 100644
index 0000000..177999d
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/PluginInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\PluginInterface.
+ */
+
+namespace Drupal\views\Plugins\views;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+
+interface PluginInterface extends PluginInspectionInterface {
+
+}
diff --git a/lib/Drupal/views/Plugins/views/access/AccessNone.php b/lib/Drupal/views/Plugins/views/access/AccessNone.php
new file mode 100644
index 0000000..3f2d905
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/access/AccessNone.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\access\AccessNone.
+ */
+
+namespace Drupal\views\Plugins\views\access;
+
+/**
+ * Access plugin that provides no access control at all.
+ *
+ * @ingroup views_access_plugins
+ */
+class AccessNone extends AccessPlugin {
+  function summary_title() {
+    return t('Unrestricted');
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/access/AccessPlugin.php b/lib/Drupal/views/Plugins/views/access/AccessPlugin.php
new file mode 100644
index 0000000..d37fbbc
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/access/AccessPlugin.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\access\AccessPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\access;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_access_plugins Views access plugins
+ * @{
+ * @todo.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The base plugin to handle access control.
+ */
+class AccessPlugin extends Plugin {
+  /**
+   * Initialize the plugin.
+   *
+   * @param $view
+   *   The view object.
+   * @param $display
+   *   The display handler.
+   */
+  function init(&$view, &$display) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    if (is_object($display->handler)) {
+      $options = $display->handler->get_option('access');
+      // Overlay incoming options on top of defaults
+      $this->unpack_options($this->options, $options);
+    }
+  }
+
+  /**
+   * Retrieve the options when this is a new access
+   * control plugin
+   */
+  function option_definition() { return array(); }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  /**
+   * Return a string to display as the clickable title for the
+   * access control.
+   */
+  function summary_title() {
+    return t('Unknown');
+  }
+
+  /**
+   * Determine if the current user has access or not.
+   */
+  function access($account) {
+    // default to no access control.
+    return TRUE;
+  }
+
+  /**
+   * Determine the access callback and arguments.
+   *
+   * This information will be embedded in the menu in order to reduce
+   * performance hits during menu item access testing, which happens
+   * a lot.
+   *
+   * @return an array; the first item should be the function to call,
+   *   and the second item should be an array of arguments. The first
+   *   item may also be TRUE (bool only) which will indicate no
+   *   access control.)
+   */
+  function get_access_callback() {
+    // default to no access control.
+    return TRUE;
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/access/PermissionAccess.php b/lib/Drupal/views/Plugins/views/access/PermissionAccess.php
new file mode 100644
index 0000000..ffe3783
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/access/PermissionAccess.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\access\PermissionAccess.
+ */
+
+namespace Drupal\views\Plugins\views\access;
+
+/**
+ * Access plugin that provides permission-based access control.
+ *
+ * @ingroup views_access_plugins
+ */
+class PermissionAccess extends AccessPlugin {
+  function access($account) {
+    return views_check_perm($this->options['perm'], $account);
+  }
+
+  function get_access_callback() {
+    return array('views_check_perm', array($this->options['perm']));
+  }
+
+  function summary_title() {
+    $permissions = module_invoke_all('permission');
+    if (isset($permissions[$this->options['perm']])) {
+      return $permissions[$this->options['perm']]['title'];
+    }
+
+    return t($this->options['perm']);
+  }
+
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['perm'] = array('default' => 'access content');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $perms = array();
+    $module_info = system_get_info('module');
+
+    // Get list of permissions
+    foreach (module_implements('permission') as $module) {
+      $permissions = module_invoke($module, 'permission');
+      foreach ($permissions as $name => $perm) {
+        $perms[$module_info[$module]['name']][$name] = strip_tags($perm['title']);
+      }
+    }
+
+    asort($perms);
+
+    $form['perm'] = array(
+      '#type' => 'select',
+      '#options' => $perms,
+      '#title' => t('Permission'),
+      '#default_value' => $this->options['perm'],
+      '#description' => t('Only users with the selected permission flag will be able to access this display. Note that users with "access all views" can see any view, regardless of other permissions.'),
+    );
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/access/RoleAccess.php b/lib/Drupal/views/Plugins/views/access/RoleAccess.php
new file mode 100644
index 0000000..eb96620
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/access/RoleAccess.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\access\RoleAccess.
+ */
+
+namespace Drupal\views\Plugins\views\access;
+
+/**
+ * Access plugin that provides role-based access control.
+ *
+ * @ingroup views_access_plugins
+ */
+class RoleAccess extends AccessPlugin {
+  function access($account) {
+    return views_check_roles(array_filter($this->options['role']), $account);
+  }
+
+  function get_access_callback() {
+    return array('views_check_roles', array(array_filter($this->options['role'])));
+  }
+
+  function summary_title() {
+    $count = count($this->options['role']);
+    if ($count < 1) {
+      return t('No role(s) selected');
+    }
+    elseif ($count > 1) {
+      return t('Multiple roles');
+    }
+    else {
+      $rids = views_ui_get_roles();
+      $rid = reset($this->options['role']);
+      return check_plain($rids[$rid]);
+    }
+  }
+
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['role'] = array('default' => array());
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['role'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Role'),
+      '#default_value' => $this->options['role'],
+      '#options' => array_map('check_plain', views_ui_get_roles()),
+      '#description' => t('Only the checked roles will be able to access this display. Note that users with "access all views" can see any view, regardless of role.'),
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    if (!array_filter($form_state['values']['access_options']['role'])) {
+      form_error($form['role'], t('You must select at least one role if type is "by role"'));
+    }
+  }
+
+  function options_submit(&$form, &$form_state) {
+    // I hate checkboxes.
+    $form_state['values']['access_options']['role'] = array_filter($form_state['values']['access_options']['role']);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/area/AreaPlugin.php b/lib/Drupal/views/Plugins/views/area/AreaPlugin.php
new file mode 100644
index 0000000..6ee718d
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/area/AreaPlugin.php
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\area\AreaPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\area;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_area_handlers Views area handlers
+ * @{
+ * Handlers to tell Views what can display in header, footer
+ * and empty text in a view.
+ */
+
+/**
+ * Base class for area handlers.
+ *
+ * @ingroup views_area_handlers
+ */
+class AreaPlugin extends Plugin {
+  /**
+   * Get this field's label.
+   */
+  function label() {
+    if (!isset($this->options['label'])) {
+      return $this->ui_name();
+    }
+    return $this->options['label'];
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $this->definition['field'] = !empty($this->definition['field']) ? $this->definition['field'] : '';
+    $label = !empty($this->definition['label']) ? $this->definition['label'] : $this->definition['field'];
+    $options['label'] = array('default' => $label, 'translatable' => TRUE);
+    $options['empty'] = array('default' => 0, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide extra data to the administration form
+   */
+  function admin_summary() {
+    return $this->label();
+  }
+
+  /**
+   * Default options form that provides the label widget that all fields
+   * should have.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label'),
+      '#default_value' => isset($this->options['label']) ? $this->options['label'] : '',
+      '#description' => t('The label for this area that will be displayed only administratively.'),
+    );
+
+    if ($form_state['type'] != 'empty') {
+      $form['empty'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Display even if view has no result'),
+        '#default_value' => isset($this->options['empty']) ? $this->options['empty'] : 0,
+      );
+    }
+  }
+
+  /**
+   * Don't run a query
+   */
+  function query() { }
+
+  /**
+   * Render the area
+   */
+  function render($empty = FALSE) {
+    return '';
+  }
+
+  /**
+   * Area handlers shouldn't have groupby.
+   */
+  function use_group_by() {
+    return FALSE;
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_area_handlers
+ */
+class views_handler_area_broken extends views_handler_area {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query($group_by = FALSE) { /* No query to run */ }
+  function render($empty = FALSE) { return ''; }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#prefix' => '<div class="form-item description">',
+      '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/area/ResultArea.php b/lib/Drupal/views/Plugins/views/area/ResultArea.php
new file mode 100644
index 0000000..bbbc56c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/area/ResultArea.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\area\resultArea.
+ */
+
+namespace Drupal\views\Plugins\views\area;
+
+/**
+ * Views area handler to display some configurable result summary.
+ *
+ * @ingroup views_area_handlers
+ */
+class ResultArea extends AreaPlugin {
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['content'] = array(
+      'default' => 'Displaying @start - @end of @total',
+      'translatable' => TRUE,
+    );
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $variables = array(
+      'items' => array(
+        '@start -- the initial record number in the set',
+        '@end -- the last record number in the set',
+        '@total -- the total records in the set',
+        '@name -- the human-readable name of the view',
+        '@per_page -- the number of items per page',
+        '@current_page -- the current page number',
+        '@page_count -- the total page count',
+      ),
+    );
+    $list = theme('item_list', $variables);
+    $form['content'] = array(
+      '#title' => t('Display'),
+      '#type' => 'textarea',
+      '#rows' => 3,
+      '#default_value' => $this->options['content'],
+      '#description' => t('You may use HTML code in this field. The following tokens are supported:') . $list,
+    );
+  }
+
+
+  /**
+   * Find out the information to render.
+   */
+  function render($empty = FALSE) {
+    // Must have options and does not work on summaries.
+    if (!isset($this->options['content']) || $this->view->plugin_name == 'default_summary') {
+      return;
+    }
+    $output = '';
+    $format = $this->options['content'];
+    // Calculate the page totals.
+    $current_page = (int) $this->view->get_current_page() + 1;
+    $per_page = (int) $this->view->get_items_per_page();
+    $count = count($this->view->result);
+    // @TODO: Maybe use a possible is views empty functionality.
+    // Not every view has total_rows set, use view->result instead.
+    $total = isset($this->view->total_rows) ? $this->view->total_rows : count($this->view->result);
+    $name = check_plain($this->view->human_name);
+    if ($per_page === 0) {
+      $page_count = 1;
+      $start = 1;
+      $end = $total;
+    }
+    else {
+      $page_count = (int) ceil($total / $per_page);
+      $total_count = $current_page * $per_page;
+      if ($total_count > $total) {
+        $total_count = $total;
+      }
+      $start = ($current_page - 1) * $per_page + 1;
+      $end = $total_count;
+    }
+    // Get the search information.
+    $items = array('start', 'end', 'total', 'name', 'per_page', 'current_page', 'page_count');
+    $replacements = array();
+    foreach ($items as $item) {
+      $replacements["@$item"] = ${$item};
+    }
+    // Send the output.
+    if (!empty($total)) {
+      $output .= filter_xss_admin(str_replace(array_keys($replacements), array_values($replacements), $format));
+    }
+    return $output;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/area/TextArea.php b/lib/Drupal/views/Plugins/views/area/TextArea.php
new file mode 100644
index 0000000..a526184
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/area/TextArea.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\area\TextArea.
+ */
+
+namespace Drupal\views\Plugins\views\area;
+
+/**
+ * Views area text handler.
+ *
+ * @ingroup views_area_handlers
+ */
+class TextArea extends AreaPlugin {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['content'] = array('default' => '', 'translatable' => TRUE, 'format_key' => 'format');
+    $options['format'] = array('default' => NULL);
+    $options['tokenize'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['content'] = array(
+      '#type' => 'text_format',
+      '#default_value' => $this->options['content'],
+      '#rows' => 6,
+      '#format' => isset($this->options['format']) ? $this->options['format'] : filter_default_format(),
+      '#wysiwyg' => FALSE,
+    );
+
+
+    $form['tokenize'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use replacement tokens from the first row'),
+      '#default_value' => $this->options['tokenize'],
+    );
+
+    // Get a list of the available fields and arguments for token replacement.
+    $options = array();
+    foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
+      $options[t('Fields')]["[$field]"] = $handler->ui_name();
+    }
+
+    $count = 0; // This lets us prepare the key as we want it printed.
+    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+      $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
+      $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
+    }
+
+    if (!empty($options)) {
+      $output = '<p>' . t('The following tokens are available. If you would like to have the characters \'[\' and \']\' please use the html entity codes \'%5B\' or  \'%5D\' or they will get replaced with empty space.' . '</p>');
+      foreach (array_keys($options) as $type) {
+        if (!empty($options[$type])) {
+          $items = array();
+          foreach ($options[$type] as $key => $value) {
+            $items[] = $key . ' == ' . $value;
+          }
+          $output .= theme('item_list',
+            array(
+              'items' => $items,
+              'type' => $type
+            ));
+        }
+      }
+
+      $form['token_help'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Replacement patterns'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#value' => $output,
+        '#id' => 'edit-options-token-help',
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[tokenize]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+    }
+  }
+
+  function options_submit(&$form, &$form_state) {
+    $form_state['values']['options']['format'] = $form_state['values']['options']['content']['format'];
+    $form_state['values']['options']['content'] = $form_state['values']['options']['content']['value'];
+    parent::options_submit($form, $form_state);
+  }
+
+  function render($empty = FALSE) {
+    $format = isset($this->options['format']) ? $this->options['format'] : filter_default_format();
+    if (!$empty || !empty($this->options['empty'])) {
+      return $this->render_textarea($this->options['content'], $format);
+    }
+    return '';
+  }
+
+  /**
+   * Render a text area, using the proper format.
+   */
+  function render_textarea($value, $format) {
+    if ($value) {
+      if ($this->options['tokenize']) {
+        $value = $this->view->style_plugin->tokenize_value($value, 0);
+      }
+      return check_markup($value, $format, '', FALSE);
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/area/ViewArea.php b/lib/Drupal/views/Plugins/views/area/ViewArea.php
new file mode 100644
index 0000000..23393b5
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/area/ViewArea.php
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\area\ViewArea.
+ */
+
+namespace Drupal\views\Plugins\views\area;
+
+/**
+ * Views area handlers. Insert a view inside of an area.
+ *
+ * @ingroup views_area_handlers
+ */
+class ViewArea extends AreaPlugin {
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['view_to_insert'] = array('default' => '');
+    $options['inherit_arguments'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Default options form that provides the label widget that all fields
+   * should have.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $view_display = $this->view->name . ':' . $this->view->current_display;
+
+    $options = array('' => t('-Select-'));
+    $options += views_get_views_as_options(FALSE, 'all', $view_display);
+    $form['view_to_insert'] = array(
+      '#type' => 'select',
+      '#title' => t('View to insert'),
+      '#default_value' => $this->options['view_to_insert'],
+      '#description' => t('The view to insert into this area.'),
+      '#options' => $options,
+    );
+
+    $form['inherit_arguments'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Inherit contextual filters'),
+      '#default_value' => $this->options['inherit_arguments'],
+      '#description' => t('If checked, this view will receive the same contextual filters as its parent.'),
+    );
+  }
+
+  /**
+   * Render the area
+   */
+  function render($empty = FALSE) {
+    if (!empty($this->options['view_to_insert'])) {
+      list($view_name, $display_id) = explode(':', $this->options['view_to_insert']);
+
+      $view = views_get_view($view_name);
+      if (empty($view) || !$view->access($display_id)) {
+        return;
+      }
+      $view->set_display($display_id);
+
+      // Avoid recursion
+      $view->parent_views += $this->view->parent_views;
+      $view->parent_views[] = "$view_name:$display_id";
+
+      // Check if the view is part of the parent views of this view
+      $search = "$view_name:$display_id";
+      if (in_array($search, $this->view->parent_views)) {
+        drupal_set_message(t("Recursion detected in view @view display @display.", array('@view' => $view_name, '@display' => $display_id)), 'error');
+      }
+      else {
+        if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) {
+          return $view->preview($display_id, $this->view->args);
+        }
+        else {
+          return $view->preview($display_id);
+        }
+      }
+    }
+    return '';
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/argument/ArgumentDefaultPlugin.php b/lib/Drupal/views/Plugins/views/argument/ArgumentDefaultPlugin.php
new file mode 100644
index 0000000..234bb7f
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/ArgumentDefaultPlugin.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\ArgumentDefaultPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_argument_default_plugins Views argument default plugins
+ * @{
+ * Allow specialized methods of filling in arguments when they aren't provided.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The fixed argument default handler; also used as the base.
+ */
+class ArgumentDefaultPlugin extends Plugin {
+  /**
+   * Return the default argument.
+   *
+   * This needs to be overridden by every default argument handler to properly do what is needed.
+   */
+  function get_argument() { }
+
+  /**
+   * Initialize this plugin with the view and the argument
+   * it is linked to.
+   */
+  function init(&$view, &$argument, $options) {
+    $this->view = &$view;
+    $this->argument = &$argument;
+
+    $this->convert_options($options);
+    $this->unpack_options($this->options, $options);
+  }
+
+  /**
+   * Retrieve the options when this is a new access
+   * control plugin
+   */
+  function option_definition() { return array(); }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit(&$form, &$form_state, &$options = array()) { }
+
+  /**
+   * Determine if the administrator has the privileges to use this
+   * plugin
+   */
+  function access() { return TRUE; }
+
+  /**
+   * If we don't have access to the form but are showing it anyway, ensure that
+   * the form is safe and cannot be changed from user input.
+   *
+   * This is only called by child objects if specified in the options_form(),
+   * so it will not always be used.
+   */
+  function check_access(&$form, $option_name) {
+    if (!$this->access()) {
+      $form[$option_name]['#disabled'] = TRUE;
+      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
+      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default filter type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
+    }
+  }
+
+  /**
+   * Convert options from the older style.
+   *
+   * In Views 3, the method of storing default argument options has changed
+   * and each plugin now gets its own silo. This method can be used to
+   * move arguments from the old style to the new style. See
+   * views_plugin_argument_default_fixed for a good example of this method.
+   */
+  function convert_options(&$options) { }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/argument/ArgumentValidatePlugin.php b/lib/Drupal/views/Plugins/views/argument/ArgumentValidatePlugin.php
new file mode 100644
index 0000000..d2a8bbb
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/ArgumentValidatePlugin.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\ArgumentValidatePlugin.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_argument_validate_plugins Views argument validate plugins
+ * @{
+ * Allow specialized methods of validating arguments.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * Base argument validator plugin to provide basic functionality.
+ */
+class ArgumentValidatePlugin extends Plugin {
+
+  /**
+   * Initialize this plugin with the view and the argument
+   * it is linked to.
+   */
+  function init(&$view, &$argument, $options) {
+    $this->view = &$view;
+    $this->argument = &$argument;
+
+    $this->convert_options($options);
+    $this->unpack_options($this->options, $options);
+  }
+
+  /**
+   * Retrieve the options when this is a new access
+   * control plugin
+   */
+  function option_definition() { return array(); }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit(&$form, &$form_state, &$options = array()) { }
+
+  /**
+   * Convert options from the older style.
+   *
+   * In Views 3, the method of storing default argument options has changed
+   * and each plugin now gets its own silo. This method can be used to
+   * move arguments from the old style to the new style. See
+   * views_plugin_argument_default_fixed for a good example of this method.
+   */
+  function convert_options(&$options) { }
+
+  /**
+   * Determine if the administrator has the privileges to use this plugin
+   */
+  function access() { return TRUE; }
+
+  /**
+   * If we don't have access to the form but are showing it anyway, ensure that
+   * the form is safe and cannot be changed from user input.
+   *
+   * This is only called by child objects if specified in the options_form(),
+   * so it will not always be used.
+   */
+  function check_access(&$form, $option_name) {
+    if (!$this->access()) {
+      $form[$option_name]['#disabled'] = TRUE;
+      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
+      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default filter type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
+    }
+  }
+
+  function validate_argument($arg) { return TRUE; }
+
+  /**
+   * Process the summary arguments for displaying.
+   *
+   * Some plugins alter the argument so it uses something else interal.
+   * For example the user validation set's the argument to the uid,
+   * for a faster query. But there are use cases where you want to use
+   * the old value again, for example the summary.
+   */
+  function process_summary_arguments(&$args) { }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/argument/FixedArgumentDefault.php b/lib/Drupal/views/Plugins/views/argument/FixedArgumentDefault.php
new file mode 100644
index 0000000..e566ff7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/FixedArgumentDefault.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\FixedArgumentDefault.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+/**
+ * The fixed argument default handler.
+ *
+ * @ingroup views_argument_default_plugins
+ */
+class FixedArgumentDefault extends ArgumentDefaultPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['argument'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['argument'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Fixed value'),
+      '#default_value' => $this->options['argument'],
+    );
+  }
+
+  /**
+   * Return the default argument.
+   */
+  function get_argument() {
+    return $this->options['argument'];
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['argument']) && isset($this->argument->options['default_argument_fixed'])) {
+      $options['argument'] = $this->argument->options['default_argument_fixed'];
+    }
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/argument/NumericArgumentValidate.php b/lib/Drupal/views/Plugins/views/argument/NumericArgumentValidate.php
new file mode 100644
index 0000000..b675bac
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/NumericArgumentValidate.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\NumericArgumentValidate.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+/**
+ * Validate whether an argument is numeric or not.
+ *
+ * @ingroup views_argument_validate_plugins
+ */
+class NumericArgumentValidate extends ArgumentValidatePlugin {
+  function validate_argument($argument) {
+    return is_numeric($argument);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/argument/PhpArgumentDefault.php b/lib/Drupal/views/Plugins/views/argument/PhpArgumentDefault.php
new file mode 100644
index 0000000..dbc78cb
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/PhpArgumentDefault.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\PhpArgumentDefault.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+/**
+ * Default argument plugin to provide a PHP code block.
+ *
+ * @ingroup views_argument_default_plugins
+ */
+class PhpArgumentDefault extends ArgumentDefaultPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['code'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['code'] = array(
+      '#type' => 'textarea',
+      '#title' => t('PHP contextual filter code'),
+      '#default_value' => $this->options['code'],
+      '#description' => t('Enter PHP code that returns a value to use for this filter. Do not use &lt;?php ?&gt;. You must return only a single value for just this filter. Some variables are available: the view object will be "$view". The argument handler will be "$argument", for example you may change the title used for substitutions for this argument by setting "argument->validated_title"".'),
+    );
+
+    // Only do this if using one simple standard form gadget
+    $this->check_access($form, 'code');
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['code']) && isset($this->argument->options['default_argument_php'])) {
+      $options['code'] = $this->argument->options['default_argument_php'];
+    }
+  }
+
+  /**
+   * Only let users with PHP block visibility permissions set/modify this
+   * default plugin.
+   */
+  function access() {
+    return user_access('use PHP for settings');
+  }
+
+  function get_argument() {
+    // set up variables to make it easier to reference during the argument.
+    $view = &$this->view;
+    $argument = &$this->argument;
+    ob_start();
+    $result = eval($this->options['code']);
+    ob_end_clean();
+    return $result;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/argument/PhpArgumentValidate.php b/lib/Drupal/views/Plugins/views/argument/PhpArgumentValidate.php
new file mode 100644
index 0000000..d343f0b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/PhpArgumentValidate.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\PhpArgumentValidate.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+/**
+ * Provide PHP code to validate whether or not an argument is ok.
+ *
+ * @ingroup views_argument_validate_plugins
+ */
+class PhpArgumentValidate extends ArgumentValidatePlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['code'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['code'] = array(
+      '#type' => 'textarea',
+      '#title' => t('PHP validate code'),
+      '#default_value' => $this->options['code'],
+      '#description' => t('Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use &lt;?php ?&gt;. The argument to validate will be "$argument" and the view will be "$view". You may change the argument by setting "$handler->argument". You may change the title used for substitutions for this argument by setting "$handler->validated_title".'),
+    );
+
+    $this->check_access($form, 'code');
+  }
+
+  /**
+   * Only let users with PHP block visibility permissions set/modify this
+   * validate plugin.
+   */
+  function access() {
+    return user_access('use PHP for settings');
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['code']) && isset($this->argument->options['validate_argument_php'])) {
+      $options['code'] = $this->argument->options['validate_argument_php'];
+    }
+  }
+
+  function validate_argument($argument) {
+    // set up variables to make it easier to reference during the argument.
+    $view = &$this->view;
+    $handler = &$this->argument;
+
+    ob_start();
+    $result = eval($this->options['code']);
+    ob_end_clean();
+    return $result;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/argument/RawArgumentDefault.php b/lib/Drupal/views/Plugins/views/argument/RawArgumentDefault.php
new file mode 100644
index 0000000..263958f
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/argument/RawArgumentDefault.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\argument\RawArgumentDefault.
+ */
+
+namespace Drupal\views\Plugins\views\argument;
+
+/**
+ * Default argument plugin to use the raw value from the URL.
+ *
+ * @ingroup views_argument_default_plugins
+ */
+class RawArgumentDefault extends ArgumentDefaultPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['index'] = array('default' => '');
+    $options['use_alias'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    // Using range(1, 10) will create an array keyed 0-9, which allows arg() to
+    // properly function since it is also zero-based.
+    $form['index'] = array(
+      '#type' => 'select',
+      '#title' => t('Path component'),
+      '#default_value' => $this->options['index'],
+      '#options' => range(1, 10),
+      '#description' => t('The numbering starts from 1, e.g. on the page admin/structure/types, the 3rd path component is "types".'),
+    );
+    $form['use_alias'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use path alias'),
+      '#default_value' => $this->options['use_alias'],
+      '#description' => t('Use path alias instead of internal path.'),
+    );
+  }
+
+  function get_argument() {
+    $path = NULL;
+    if ($this->options['use_alias']) {
+      $path = drupal_get_path_alias();
+    }
+    if ($arg = arg($this->options['index'], $path)) {
+      return $arg;
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/cache/CacheNone.php b/lib/Drupal/views/Plugins/views/cache/CacheNone.php
new file mode 100644
index 0000000..8efbf2f
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/cache/CacheNone.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\cache\CacheNone.
+ */
+
+namespace Drupal\views\Plugins\views\cache;
+
+/**
+ * Caching plugin that provides no caching at all.
+ *
+ * @ingroup views_cache_plugins
+ */
+class CacheNone extends CachePlugin {
+  function cache_start() { /* do nothing */ }
+
+  function summary_title() {
+    return t('None');
+  }
+
+  function cache_get($type) {
+    return FALSE;
+  }
+
+  function cache_set($type) { }
+}
diff --git a/lib/Drupal/views/Plugins/views/cache/CachePlugin.php b/lib/Drupal/views/Plugins/views/cache/CachePlugin.php
new file mode 100644
index 0000000..e2bba58
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/cache/CachePlugin.php
@@ -0,0 +1,326 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\cache\CachePlugin.
+ */
+
+namespace Drupal\views\Plugins\views\cache;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_cache_plugins Views cache plugins
+ * @{
+ * @todo.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The base plugin to handle caching.
+ */
+class CachePlugin extends Plugin {
+  /**
+   * Contains all data that should be written/read from cache.
+   */
+  var $storage = array();
+
+  /**
+   * What table to store data in.
+   */
+  var $table = 'cache_views_data';
+
+  /**
+   * Stores the cache id used for the results cache, once get_results_key() got
+   * executed.
+   *
+   * @see views_plugin_cache::get_results_key
+   * @var string
+   */
+  public $_results_key;
+
+  /**
+   * Stores the cache id used for the output cache, once get_output_key() got
+   * executed.
+   *
+   * @see views_plugin_cache::get_output_key
+   * @var string
+   */
+  public $_output_key;
+
+  /**
+   * Initialize the plugin.
+   *
+   * @param $view
+   *   The view object.
+   * @param $display
+   *   The display handler.
+   */
+  function init(&$view, &$display) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    if (is_object($display->handler)) {
+      $options = $display->handler->get_option('cache');
+      // Overlay incoming options on top of defaults
+      $this->unpack_options($this->options, $options);
+    }
+  }
+
+  /**
+   * Return a string to display as the clickable title for the
+   * access control.
+   */
+  function summary_title() {
+    return t('Unknown');
+  }
+
+  /**
+   * Determine the expiration time of the cache type, or NULL if no expire.
+   *
+   * Plugins must override this to implement expiration.
+   *
+   * @param $type
+   *   The cache type, either 'query', 'result' or 'output'.
+   */
+   function cache_expire($type) { }
+
+   /**
+    * Determine expiration time in the cache table of the cache type
+    * or CACHE_PERMANENT if item shouldn't be removed automatically from cache.
+    *
+    * Plugins must override this to implement expiration in the cache table.
+    *
+    * @param $type
+    *   The cache type, either 'query', 'result' or 'output'.
+    */
+  function cache_set_expire($type) {
+    return CACHE_PERMANENT;
+  }
+
+
+  /**
+   * Save data to the cache.
+   *
+   * A plugin should override this to provide specialized caching behavior.
+   */
+  function cache_set($type) {
+    switch ($type) {
+      case 'query':
+        // Not supported currently, but this is certainly where we'd put it.
+        break;
+      case 'results':
+        $data = array(
+          'result' => $this->view->result,
+          'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0,
+          'current_page' => $this->view->get_current_page(),
+        );
+        cache($this->table)->set($this->get_results_key(), $data, $this->cache_set_expire($type));
+        break;
+      case 'output':
+        $this->gather_headers();
+        $this->storage['output'] = $this->view->display_handler->output;
+        cache($this->table)->set($this->get_output_key(), $this->storage, $this->cache_set_expire($type));
+        break;
+    }
+  }
+
+
+  /**
+   * Retrieve data from the cache.
+   *
+   * A plugin should override this to provide specialized caching behavior.
+   */
+  function cache_get($type) {
+    $cutoff = $this->cache_expire($type);
+    switch ($type) {
+      case 'query':
+        // Not supported currently, but this is certainly where we'd put it.
+        return FALSE;
+      case 'results':
+        // Values to set: $view->result, $view->total_rows, $view->execute_time,
+        // $view->current_page.
+        if ($cache = cache($this->table)->get($this->get_results_key())) {
+          if (!$cutoff || $cache->created > $cutoff) {
+            $this->view->result = $cache->data['result'];
+            $this->view->total_rows = $cache->data['total_rows'];
+            $this->view->set_current_page($cache->data['current_page']);
+            $this->view->execute_time = 0;
+            return TRUE;
+          }
+        }
+        return FALSE;
+      case 'output':
+        if ($cache = cache($this->table)->get($this->get_output_key())) {
+          if (!$cutoff || $cache->created > $cutoff) {
+            $this->storage = $cache->data;
+            $this->view->display_handler->output = $cache->data['output'];
+            $this->restore_headers();
+            return TRUE;
+          }
+        }
+        return FALSE;
+    }
+  }
+
+  /**
+   * Clear out cached data for a view.
+   *
+   * We're just going to nuke anything related to the view, regardless of display,
+   * to be sure that we catch everything. Maybe that's a bad idea.
+   */
+  function cache_flush() {
+    cache($this->table)->deletePrefix($this->view->name . ':');
+  }
+
+  /**
+   * Post process any rendered data.
+   *
+   * This can be valuable to be able to cache a view and still have some level of
+   * dynamic output. In an ideal world, the actual output will include HTML
+   * comment based tokens, and then the post process can replace those tokens.
+   *
+   * Example usage. If it is known that the view is a node view and that the
+   * primary field will be a nid, you can do something like this:
+   *
+   * <!--post-FIELD-NID-->
+   *
+   * And then in the post render, create an array with the text that should
+   * go there:
+   *
+   * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1');
+   *
+   * All of the cached result data will be available in $view->result, as well,
+   * so all ids used in the query should be discoverable.
+   */
+  function post_render(&$output) { }
+
+  /**
+   * Start caching javascript, css and other out of band info.
+   *
+   * This takes a snapshot of the current system state so that we don't
+   * duplicate it. Later on, when gather_headers() is run, this information
+   * will be removed so that we don't hold onto it.
+   */
+  function cache_start() {
+    $this->storage['head'] = drupal_add_html_head();
+    $this->storage['css'] = drupal_add_css();
+    $this->storage['js'] = drupal_add_js();
+  }
+
+  /**
+   * Gather out of band data, compare it to what we started with and store the difference.
+   */
+  function gather_headers() {
+    // Simple replacement for head
+    if (isset($this->storage['head'])) {
+      $this->storage['head'] = str_replace($this->storage['head'], '', drupal_add_html_head());
+    }
+    else {
+      $this->storage['head'] = '';
+    }
+
+    // Slightly less simple for CSS:
+    $css = drupal_add_css();
+    $css_start = isset($this->storage['css']) ? $this->storage['css'] : array();
+    $this->storage['css'] = array_diff_assoc($css, $css_start);
+
+    // Get javascript after/before views renders.
+    $js = drupal_add_js();
+    $js_start = isset($this->storage['js']) ? $this->storage['js'] : array();
+    // If there are any differences between the old and the new javascript then
+    // store them to be added later.
+    $this->storage['js'] = array_diff_assoc($js, $js_start);
+
+    // Special case the settings key and get the difference of the data.
+    $settings = isset($js['settings']['data']) ? $js['settings']['data'] : array();
+    $settings_start = isset($js_start['settings']['data']) ? $js_start['settings']['data'] : array();
+    $this->storage['js']['settings'] = array_diff_assoc($settings, $settings_start);
+  }
+
+  /**
+   * Restore out of band data saved to cache. Copied from Panels.
+   */
+  function restore_headers() {
+    if (!empty($this->storage['head'])) {
+      drupal_add_html_head($this->storage['head']);
+    }
+    if (!empty($this->storage['css'])) {
+      foreach ($this->storage['css'] as $args) {
+        drupal_add_css($args['data'], $args);
+      }
+    }
+    if (!empty($this->storage['js'])) {
+      foreach ($this->storage['js'] as $key => $args) {
+        if ($key != 'settings') {
+          drupal_add_js($args['data'], $args);
+        }
+        else {
+          foreach ($args as $setting) {
+            drupal_add_js($setting, 'setting');
+          }
+        }
+      }
+    }
+  }
+
+  function get_results_key() {
+    global $user;
+
+    if (!isset($this->_results_key)) {
+
+      $build_info = $this->view->build_info;
+
+      $query_plugin = $this->view->display_handler->get_plugin('query');
+
+      foreach (array('query','count_query') as $index) {
+        // If the default query back-end is used generate SQL query strings from
+        // the query objects.
+        if ($build_info[$index] instanceof Drupal\Core\Database\Query\Select) {
+          $query = clone $build_info[$index];
+          $query->preExecute();
+          $build_info[$index] = (string)$query;
+        }
+      }
+      $key_data = array(
+        'build_info' => $build_info,
+        'roles' => array_keys($user->roles),
+        'super-user' => $user->uid == 1, // special caching for super user.
+        'language' => drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode,
+        'base_url' => $GLOBALS['base_url'],
+      );
+      foreach (array('exposed_info', 'page', 'sort', 'order', 'items_per_page', 'offset') as $key) {
+        if (isset($_GET[$key])) {
+          $key_data[$key] = $_GET[$key];
+        }
+      }
+
+      $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . md5(serialize($key_data));
+    }
+
+    return $this->_results_key;
+  }
+
+  function get_output_key() {
+    global $user;
+    if (!isset($this->_output_key)) {
+      $key_data = array(
+        'result' => $this->view->result,
+        'roles' => array_keys($user->roles),
+        'super-user' => $user->uid == 1, // special caching for super user.
+        'theme' => $GLOBALS['theme'],
+        'language' => drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode,
+        'base_url' => $GLOBALS['base_url'],
+      );
+
+      $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . md5(serialize($key_data));
+    }
+
+    return $this->_output_key;
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/cache/TimeCache.php b/lib/Drupal/views/Plugins/views/cache/TimeCache.php
new file mode 100644
index 0000000..255e697
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/cache/TimeCache.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\cache\TimeCache.
+ */
+
+namespace Drupal\views\Plugins\views\cache;
+
+/**
+ * Simple caching of query results for Views displays.
+ *
+ * @ingroup views_cache_plugins
+ */
+class TimeCache extends CachePlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['results_lifespan'] = array('default' => 3600);
+    $options['results_lifespan_custom'] = array('default' => 0);
+    $options['output_lifespan'] = array('default' => 3600);
+    $options['output_lifespan_custom'] = array('default' => 0);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $options = array(60, 300, 1800, 3600, 21600, 518400);
+    $options = drupal_map_assoc($options, 'format_interval');
+    $options = array(-1 => t('Never cache')) + $options + array('custom' => t('Custom'));
+
+    $form['results_lifespan'] = array(
+      '#type' => 'select',
+      '#title' => t('Query results'),
+      '#description' => t('The length of time raw query results should be cached.'),
+      '#options' => $options,
+      '#default_value' => $this->options['results_lifespan'],
+    );
+    $form['results_lifespan_custom'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Seconds'),
+      '#size' => '25',
+      '#maxlength' => '30',
+      '#description' => t('Length of time in seconds raw query results should be cached.'),
+      '#default_value' => $this->options['results_lifespan_custom'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="cache_options[results_lifespan]"]' => array('value' => 'custom'),
+        ),
+      ),
+    );
+    $form['output_lifespan'] = array(
+      '#type' => 'select',
+      '#title' => t('Rendered output'),
+      '#description' => t('The length of time rendered HTML output should be cached.'),
+      '#options' => $options,
+      '#default_value' => $this->options['output_lifespan'],
+    );
+    $form['output_lifespan_custom'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Seconds'),
+      '#size' => '25',
+      '#maxlength' => '30',
+      '#description' => t('Length of time in seconds rendered HTML output should be cached.'),
+      '#default_value' => $this->options['output_lifespan_custom'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="cache_options[output_lifespan]"]' => array('value' => 'custom'),
+        ),
+      ),
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    $custom_fields = array('output_lifespan', 'results_lifespan');
+    foreach ($custom_fields as $field) {
+      if ($form_state['values']['cache_options'][$field] == 'custom' && !is_numeric($form_state['values']['cache_options'][$field . '_custom'])) {
+        form_error($form[$field .'_custom'], t('Custom time values must be numeric.'));
+      }
+    }
+  }
+
+  function summary_title() {
+    $results_lifespan = $this->get_lifespan('results');
+    $output_lifespan = $this->get_lifespan('output');
+    return format_interval($results_lifespan, 1) . '/' . format_interval($output_lifespan, 1);
+  }
+
+  function get_lifespan($type) {
+    $lifespan = $this->options[$type . '_lifespan'] == 'custom' ? $this->options[$type . '_lifespan_custom'] : $this->options[$type . '_lifespan'];
+    return $lifespan;
+  }
+
+  function cache_expire($type) {
+    $lifespan = $this->get_lifespan($type);
+    if ($lifespan) {
+      $cutoff = REQUEST_TIME - $lifespan;
+      return $cutoff;
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  function cache_set_expire($type) {
+    $lifespan = $this->get_lifespan($type);
+    if ($lifespan) {
+      return time() + $lifespan;
+    }
+    else {
+      return CACHE_PERMANENT;
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display/AttachmentDisplay.php b/lib/Drupal/views/Plugins/views/display/AttachmentDisplay.php
new file mode 100644
index 0000000..f428d3c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/AttachmentDisplay.php
@@ -0,0 +1,284 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\AttachmentDisplay.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+/**
+ * The plugin that handles an attachment display.
+ *
+ * Attachment displays are secondary displays that are 'attached' to a primary
+ * display. Effectively they are a simple way to get multiple views within
+ * the same view. They can share some information.
+ *
+ * @ingroup views_display_plugins
+ */
+class AttachmentDisplay extends DisplayPlugin {
+  function option_definition () {
+    $options = parent::option_definition();
+
+    $options['displays'] = array('default' => array());
+    $options['attachment_position'] = array('default' => 'before');
+    $options['inherit_arguments'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['inherit_exposed_filters'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['inherit_pager'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['render_pager'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function execute() {
+    return $this->view->render($this->display->id);
+  }
+
+  function attachment_positions($position = NULL) {
+    $positions = array(
+      'before' => t('Before'),
+      'after' => t('After'),
+      'both' => t('Both'),
+    );
+
+    if ($position) {
+      return $positions[$position];
+    }
+
+    return $positions;
+  }
+
+  /**
+   * Provide the summary for attachment options in the views UI.
+   *
+   * This output is returned as an array.
+   */
+  function options_summary(&$categories, &$options) {
+    // It is very important to call the parent function here:
+    parent::options_summary($categories, $options);
+
+    $categories['attachment'] = array(
+      'title' => t('Attachment settings'),
+      'column' => 'second',
+      'build' => array(
+        '#weight' => -10,
+      ),
+    );
+
+    $displays = array_filter($this->get_option('displays'));
+    if (count($displays) > 1) {
+      $attach_to = t('Multiple displays');
+    }
+    elseif (count($displays) == 1) {
+      $display = array_shift($displays);
+      if (!empty($this->view->display[$display])) {
+        $attach_to = check_plain($this->view->display[$display]->display_title);
+      }
+    }
+
+    if (!isset($attach_to)) {
+      $attach_to = t('Not defined');
+    }
+
+    $options['displays'] = array(
+      'category' => 'attachment',
+      'title' => t('Attach to'),
+      'value' => $attach_to,
+    );
+
+    $options['attachment_position'] = array(
+      'category' => 'attachment',
+      'title' => t('Attachment position'),
+      'value' => $this->attachment_positions($this->get_option('attachment_position')),
+    );
+
+    $options['inherit_arguments'] = array(
+      'category' => 'attachment',
+      'title' => t('Inherit contextual filters'),
+      'value' => $this->get_option('inherit_arguments') ? t('Yes') : t('No'),
+    );
+
+    $options['inherit_exposed_filters'] = array(
+      'category' => 'attachment',
+      'title' => t('Inherit exposed filters'),
+      'value' => $this->get_option('inherit_exposed_filters') ? t('Yes') : t('No'),
+    );
+
+    $options['inherit_pager'] = array(
+      'category' => 'pager',
+      'title' => t('Inherit pager'),
+      'value' => $this->get_option('inherit_pager') ? t('Yes') : t('No'),
+    );
+
+    $options['render_pager'] = array(
+      'category' => 'pager',
+      'title' => t('Render pager'),
+      'value' => $this->get_option('render_pager') ? t('Yes') : t('No'),
+    );
+
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_form($form, $form_state);
+
+    switch ($form_state['section']) {
+      case 'inherit_arguments':
+        $form['#title'] .= t('Inherit contextual filters');
+        $form['inherit_arguments'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Inherit'),
+          '#description' => t('Should this display inherit its contextual filter values from the parent display to which it is attached?'),
+          '#default_value' => $this->get_option('inherit_arguments'),
+        );
+        break;
+      case 'inherit_exposed_filters':
+        $form['#title'] .= t('Inherit exposed filters');
+        $form['inherit_exposed_filters'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Inherit'),
+          '#description' => t('Should this display inherit its exposed filter values from the parent display to which it is attached?'),
+          '#default_value' => $this->get_option('inherit_exposed_filters'),
+        );
+        break;
+      case 'inherit_pager':
+        $form['#title'] .= t('Inherit pager');
+        $form['inherit_pager'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Inherit'),
+          '#description' => t('Should this display inherit its paging values from the parent display to which it is attached?'),
+          '#default_value' => $this->get_option('inherit_pager'),
+        );
+        break;
+      case 'render_pager':
+        $form['#title'] .= t('Render pager');
+        $form['render_pager'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Render'),
+          '#description' => t('Should this display render the pager values? This is only meaningful if inheriting a pager.'),
+          '#default_value' => $this->get_option('render_pager'),
+        );
+        break;
+      case 'attachment_position':
+        $form['#title'] .= t('Position');
+        $form['attachment_position'] = array(
+          '#type' => 'radios',
+          '#description' => t('Attach before or after the parent display?'),
+          '#options' => $this->attachment_positions(),
+          '#default_value' => $this->get_option('attachment_position'),
+        );
+        break;
+      case 'displays':
+        $form['#title'] .= t('Attach to');
+        $displays = array();
+        foreach ($this->view->display as $display_id => $display) {
+          if (!empty($display->handler) && $display->handler->accept_attachments()) {
+            $displays[$display_id] = $display->display_title;
+          }
+        }
+        $form['displays'] = array(
+          '#type' => 'checkboxes',
+          '#description' => t('Select which display or displays this should attach to.'),
+          '#options' => $displays,
+          '#default_value' => $this->get_option('displays'),
+        );
+        break;
+    }
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_submit($form, $form_state);
+    switch ($form_state['section']) {
+      case 'inherit_arguments':
+      case 'inherit_pager':
+      case 'render_pager':
+      case 'inherit_exposed_filters':
+      case 'attachment_position':
+      case 'displays':
+        $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
+        break;
+    }
+  }
+
+  /**
+   * Attach to another view.
+   */
+  function attach_to($display_id) {
+    $displays = $this->get_option('displays');
+
+    if (empty($displays[$display_id])) {
+      return;
+    }
+
+    if (!$this->access()) {
+      return;
+    }
+
+    // Get a fresh view because our current one has a lot of stuff on it because it's
+    // already been executed.
+    $view = $this->view->clone_view();
+    $view->original_args = $view->args;
+
+    $args = $this->get_option('inherit_arguments') ? $this->view->args : array();
+    $view->set_arguments($args);
+    $view->set_display($this->display->id);
+    if ($this->get_option('inherit_pager')) {
+      $view->display_handler->use_pager = $this->view->display[$display_id]->handler->use_pager();
+      $view->display_handler->set_option('pager', $this->view->display[$display_id]->handler->get_option('pager'));
+    }
+
+    $attachment = $view->execute_display($this->display->id, $args);
+
+    switch ($this->get_option('attachment_position')) {
+      case 'before':
+        $this->view->attachment_before .= $attachment;
+        break;
+      case 'after':
+        $this->view->attachment_after .= $attachment;
+        break;
+      case 'both':
+        $this->view->attachment_before .= $attachment;
+        $this->view->attachment_after .= $attachment;
+        break;
+    }
+
+    $view->destroy();
+  }
+
+  /**
+   * Attachment displays only use exposed widgets if
+   * they are set to inherit the exposed filter settings
+   * of their parent display.
+   */
+  function uses_exposed() {
+    if (!empty($this->options['inherit_exposed_filters']) && parent::uses_exposed()) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * If an attachment is set to inherit the exposed filter
+   * settings from its parent display, then don't render and
+   * display a second set of exposed filter widgets.
+   */
+  function displays_exposed() {
+    return $this->options['inherit_exposed_filters'] ? FALSE : TRUE;
+  }
+
+  function use_pager() {
+    return !empty($this->use_pager);
+  }
+
+  function render_pager() {
+    return !empty($this->use_pager) && $this->get_option('render_pager');
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display/BlockDisplay.php b/lib/Drupal/views/Plugins/views/display/BlockDisplay.php
new file mode 100644
index 0000000..10be639
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/BlockDisplay.php
@@ -0,0 +1,240 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\BlockDisplay.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+/**
+ * The plugin that handles a block.
+ *
+ * @ingroup views_display_plugins
+ */
+class BlockDisplay extends DisplayPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['block_description'] = array('default' => '', 'translatable' => TRUE);
+    $options['block_caching'] = array('default' => DRUPAL_NO_CACHE);
+
+    return $options;
+  }
+
+  /**
+   * The default block handler doesn't support configurable items,
+   * but extended block handlers might be able to do interesting
+   * stuff with it.
+   */
+  function execute_hook_block_list($delta = 0, $edit = array()) {
+    $delta = $this->view->name . '-' . $this->display->id;
+    $desc = $this->get_option('block_description');
+
+    if (empty($desc)) {
+      if ($this->display->display_title == $this->definition['title']) {
+        $desc = t('View: !view', array('!view' => $this->view->get_human_name()));
+      }
+      else {
+        $desc = t('View: !view: !display', array('!view' => $this->view->get_human_name(), '!display' => $this->display->display_title));
+      }
+    }
+    return array(
+      $delta => array(
+        'info' => $desc,
+        'cache' => $this->get_cache_type()
+      ),
+    );
+  }
+
+  /**
+   * The display block handler returns the structure necessary for a block.
+   */
+  function execute() {
+    // Prior to this being called, the $view should already be set to this
+    // display, and arguments should be set on the view.
+    $info['content'] = $this->view->render();
+    $info['subject'] = filter_xss_admin($this->view->get_title());
+    if (!empty($this->view->result) || $this->get_option('empty') || !empty($this->view->style_plugin->definition['even empty'])) {
+      return $info;
+    }
+  }
+
+  /**
+   * Provide the summary for page options in the views UI.
+   *
+   * This output is returned as an array.
+   */
+  function options_summary(&$categories, &$options) {
+    // It is very important to call the parent function here:
+    parent::options_summary($categories, $options);
+
+    $categories['block'] = array(
+      'title' => t('Block settings'),
+      'column' => 'second',
+      'build' => array(
+        '#weight' => -10,
+      ),
+    );
+
+    $block_description = strip_tags($this->get_option('block_description'));
+    if (empty($block_description)) {
+      $block_description = t('None');
+    }
+
+    $options['block_description'] = array(
+      'category' => 'block',
+      'title' => t('Block name'),
+      'value' => views_ui_truncate($block_description, 24),
+    );
+
+    $types = $this->block_caching_modes();
+    $options['block_caching'] = array(
+      'category' => 'other',
+      'title' => t('Block caching'),
+      'value' => $types[$this->get_cache_type()],
+    );
+  }
+
+  /**
+   * Provide a list of core's block caching modes.
+   */
+  function block_caching_modes() {
+    return array(
+      DRUPAL_NO_CACHE => t('Do not cache'),
+      DRUPAL_CACHE_GLOBAL => t('Cache once for everything (global)'),
+      DRUPAL_CACHE_PER_PAGE => t('Per page'),
+      DRUPAL_CACHE_PER_ROLE => t('Per role'),
+      DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE => t('Per role per page'),
+      DRUPAL_CACHE_PER_USER => t('Per user'),
+      DRUPAL_CACHE_PER_USER | DRUPAL_CACHE_PER_PAGE => t('Per user per page'),
+    );
+  }
+
+  /**
+   * Provide a single method to figure caching type, keeping a sensible default
+   * for when it's unset.
+   */
+  function get_cache_type() {
+    $cache_type = $this->get_option('block_caching');
+    if (empty($cache_type)) {
+      $cache_type = DRUPAL_NO_CACHE;
+    }
+    return $cache_type;
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_form($form, $form_state);
+
+    switch ($form_state['section']) {
+      case 'block_description':
+        $form['#title'] .= t('Block admin description');
+        $form['block_description'] = array(
+          '#type' => 'textfield',
+          '#description' => t('This will appear as the name of this block in administer >> structure >> blocks.'),
+          '#default_value' => $this->get_option('block_description'),
+        );
+        break;
+      case 'block_caching':
+        $form['#title'] .= t('Block caching type');
+
+        $form['block_caching'] = array(
+          '#type' => 'radios',
+          '#description' => t("This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed."),
+          '#options' => $this->block_caching_modes(),
+          '#default_value' => $this->get_cache_type(),
+        );
+        break;
+      case 'exposed_form_options':
+        $this->view->init_handlers();
+        if (!$this->uses_exposed() && parent::uses_exposed()) {
+          $form['exposed_form_options']['warning'] = array(
+            '#weight' => -10,
+            '#markup' => '<div class="messages warning">' . t('Exposed filters in block displays require "Use AJAX" to be set to work correctly.') . '</div>',
+          );
+        }
+    }
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_submit($form, $form_state);
+    switch ($form_state['section']) {
+      case 'display_id':
+        $this->update_block_bid($form_state['view']->name, $this->display->id, $this->display->new_id);
+        break;
+      case 'block_description':
+        $this->set_option('block_description', $form_state['values']['block_description']);
+        break;
+      case 'block_caching':
+        $this->set_option('block_caching', $form_state['values']['block_caching']);
+        $this->save_block_cache($form_state['view']->name . '-'. $form_state['display_id'], $form_state['values']['block_caching']);
+        break;
+    }
+  }
+
+  /**
+   * Block views use exposed widgets only if AJAX is set.
+   */
+    function uses_exposed() {
+      if ($this->use_ajax()) {
+        return parent::uses_exposed();
+      }
+      return FALSE;
+    }
+
+  /**
+   * Update the block delta when you change the machine readable name of the display.
+   */
+  function update_block_bid($name, $old_delta, $delta) {
+    $old_hashes = $hashes = variable_get('views_block_hashes', array());
+
+    $old_delta = $name . '-' . $old_delta;
+    $delta = $name . '-' . $delta;
+    if (strlen($old_delta) >= 32) {
+      $old_delta = md5($old_delta);
+      unset($hashes[$old_delta]);
+    }
+    if (strlen($delta) >= 32) {
+      $md5_delta = md5($delta);
+      $hashes[$md5_delta] = $delta;
+      $delta = $md5_delta;
+    }
+    db_update('block')
+      ->fields(array('delta' => $delta))
+      ->condition('delta', $old_delta)
+      ->execute();
+
+    // Update the hashes if needed.
+    if ($hashes != $old_hashes) {
+      variable_set('views_block_hashes', $hashes);
+    }
+  }
+  /**
+   * Save the block cache setting in the blocks table if this block allready
+   * exists in the blocks table. Dirty fix untill http://drupal.org/node/235673 gets in.
+   */
+  function save_block_cache($delta, $cache_setting) {
+    if (strlen($delta) >= 32) {
+      $delta = md5($delta);
+    }
+    if (db_table_exists('block') && $bid = db_query("SELECT bid FROM {block} WHERE module = 'views' AND delta = :delta", array(
+        ':delta' => $delta))->fetchField()) {
+      db_update('block')
+        ->fields(array(
+        'cache' => $cache_setting,
+        ))
+        ->condition('module','views')
+        ->condition('delta', $delta)
+        ->execute();
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display/DefaultDisplay.php b/lib/Drupal/views/Plugins/views/display/DefaultDisplay.php
new file mode 100644
index 0000000..4c8814e
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/DefaultDisplay.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\DefaultDisplay.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+/**
+ * A plugin to handle defaults on a view.
+ *
+ * @ingroup views_display_plugins
+ */
+class DefaultDisplay extends DisplayPlugin {
+  /**
+   * Determine if this display is the 'default' display which contains
+   * fallback settings
+   */
+  function is_default_display() { return TRUE; }
+
+  /**
+   * The default execute handler fully renders the view.
+   *
+   * For the simplest use:
+   * @code
+   *   $output = $view->execute_display('default', $args);
+   * @endcode
+   *
+   * For more complex usages, a view can be partially built:
+   * @code
+   *   $view->set_arguments($args);
+   *   $view->build('default'); // Build the query
+   *   $view->pre_execute(); // Pre-execute the query.
+   *   $view->execute(); // Run the query
+   *   $output = $view->render(); // Render the view
+   * @endcode
+   *
+   * If short circuited at any point, look in $view->build_info for
+   * information about the query. After execute, look in $view->result
+   * for the array of objects returned from db_query.
+   *
+   * You can also do:
+   * @code
+   *   $view->set_arguments($args);
+   *   $output = $view->render('default'); // Render the view
+   * @endcode
+   *
+   * This illustrates that render is smart enough to call build and execute
+   * if these items have not already been accomplished.
+   *
+   * Note that execute also must accomplish other tasks, such
+   * as setting page titles, breadcrumbs, and generating exposed filter
+   * data if necessary.
+   */
+  function execute() {
+    return $this->view->render($this->display->id);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display/DisplayPlugin.php b/lib/Drupal/views/Plugins/views/display/DisplayPlugin.php
new file mode 100644
index 0000000..7ca2e0b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/DisplayPlugin.php
@@ -0,0 +1,3049 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\DisplayPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+use Drupal\views\View;
+use Drupal\views\Plugins\views\Plugin;
+use Drupal\views\Plugins\views\query\QueryPluginType;
+
+/**
+ * @defgroup views_display_plugins Views display plugins
+ * @{
+ * Display plugins control how Views interact with the rest of Drupal.
+ *
+ * They can handle creating Views from a Drupal page hook; they can
+ * handle creating Views from a Drupal block hook. They can also
+ * handle creating Views from an external module source, such as
+ * a Panels pane, or an insert view, or a CCK field type.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The default display plugin handler. Display plugins handle options and
+ * basic mechanisms for different output methods.
+ */
+class DisplayPlugin extends Plugin {
+  /**
+   * The top object of a view.
+   *
+   * @var view
+   */
+  var $view = NULL;
+
+  var $handlers = array();
+
+  /**
+   * Stores all available display extenders.
+   */
+  var $extender = array();
+
+  /**
+   * Stores the rendered output of the display.
+   *
+   * @see View::render
+   * @var string
+   */
+  public $output = NULL;
+
+  function init(&$view, &$display, $options = NULL) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    // Load extenders as soon as possible.
+    $this->extender = array();
+    $extenders = views_get_enabled_display_extenders();
+    // If you update to the dev version the registry might not be loaded yet.
+    if (!empty($extenders) && class_exists('views_plugin_display_extender')) {
+      foreach ($extenders as $extender) {
+        $plugin = views_get_plugin('display_extender', $extender);
+        if ($plugin) {
+          $plugin->init($this->view, $this);
+          $this->extender[$extender] = $plugin;
+        }
+        else {
+          vpr('Invalid display extender @extender', array('@handler' => $extender));
+        }
+      }
+    }
+
+    // Track changes that the user should know about.
+    $changed = FALSE;
+
+    // Make some modifications:
+    if (!isset($options) && isset($display->display_options)) {
+      $options = $display->display_options;
+    }
+
+    if ($this->is_default_display() && isset($options['defaults'])) {
+      unset($options['defaults']);
+    }
+
+    // Cache for unpack_options, but not if we are in the ui.
+    static $unpack_options = array();
+    if (empty($view->editing)) {
+      $cid = 'unpack_options:' . md5(serialize(array($this->options, $options)));
+      if (empty($unpack_options[$cid])) {
+        $cache = views_cache_get($cid, TRUE);
+        if (!empty($cache->data)) {
+          $this->options = $cache->data;
+        }
+        else {
+          $this->unpack_options($this->options, $options);
+          views_cache_set($cid, $this->options, TRUE);
+        }
+        $unpack_options[$cid] = $this->options;
+      }
+      else {
+        $this->options = $unpack_options[$cid];
+      }
+    }
+    else {
+      $this->unpack_options($this->options, $options);
+    }
+
+    // Translate changed settings:
+    $items_per_page = $this->get_option('items_per_page');
+    $offset = $this->get_option('offset');
+    $use_pager = $this->get_option('use_pager');
+    $pager = $this->get_option('pager');
+    // Check if the pager options were already converted.
+    // The pager settings of a Views 2.x view specifying 10 items with an
+    // offset of 0 and no pager is the same as of a Views 3.x view with
+    // default settings. In this case, the only way to determine which case we
+    // are dealing with is checking the API version but that's only available
+    // for exported Views as it's not stored in the database.
+    // If you would like to change this code, really take care that you thought
+    // of every possibility.
+    // @TODO: Provide a way to convert the database views as well.
+    if (((!empty($items_per_page) && $items_per_page != 10) || !empty($offset) || !empty($use_pager))
+      || (!empty($view->api_version) && $view->api_version == 2)) {
+      // Find out the right pager type.
+      // If the view "use pager" it's a normal/full pager.
+      if ($use_pager) {
+        $type = 'full';
+      }
+      // If it does not use pager, but 0 items per page it should not page
+      // else it should display just a certain amount of items.
+      else {
+        $type = $items_per_page ? 'some' : 'none';
+      }
+
+      // Setup the pager options.
+      $pager = array(
+        'type' => $type,
+        'options' => array(
+          'offset' => intval($offset)
+        ),
+      );
+
+      if ($items_per_page) {
+        $pager['options']['items_per_page'] = $items_per_page;
+      }
+      // Setup the pager element.
+      if ($id = $this->get_option('pager_element')) {
+        $pager['options']['id'] = $id;
+      }
+
+      // Unset the previous options
+      // After edit and save the view they will be erased
+      $this->set_option('items_per_page', NULL);
+      $this->set_option('offset', NULL);
+      $this->set_option('use_pager', NULL);
+      $this->set_option('pager', $pager);
+      $changed = TRUE;
+    }
+
+
+    // Plugable headers, footer and empty texts are
+    // not compatible with previous version of views
+    // This code converts old values into a configured handler for each area
+    foreach (array('header', 'footer', 'empty') as $area) {
+      $converted = FALSE;
+      if (isset($this->options[$area]) && !is_array($this->options[$area])) {
+        if (!empty($this->options[$area])) {
+          $content = $this->get_option($area);
+          if (!empty($content) && !is_array($content)) {
+            $format = $this->get_option($area . '_format');
+            $options = array(
+              'id' => 'area',
+              'table' => 'views',
+              'field' => 'area',
+              'label' => '',
+              'relationship' => 'none',
+              'group_type' => 'group',
+              'content' => $content,
+              'format' => !empty($format) ? $format : filter_default_format(),
+            );
+
+            if ($area != 'empty' && $empty = $this->get_option($area . '_empty')) {
+              $options['empty'] = $empty;
+            }
+            $this->set_option($area, array('text' => $options));
+            $converted = TRUE;
+            $changed = TRUE;
+          }
+        }
+        // Ensure that options are at least an empty array
+        if (!$converted) {
+          $this->set_option($area, array());
+        }
+      }
+    }
+
+    // Convert distinct setting from display to query settings.
+    $distinct = $this->get_option('distinct');
+    if (!empty($distinct)) {
+      $query_settings = $this->get_option('query');
+      $query_settings['options']['distinct'] = $distinct;
+      $this->set_option('query', $query_settings);
+      // Clear the values
+      $this->set_option('distinct', NULL);
+      $changed = TRUE;
+    }
+
+    // Convert field language settings.
+    $query_options = $this->get_option('query');
+    if (isset($query_options['options']['field_language'])) {
+      $this->set_option('field_language', $query_options['options']['field_language']);
+      unset($query_options['options']['field_language']);
+      $changed = TRUE;
+    }
+    if (isset($query_options['options']['field_language_add_to_query'])) {
+      $this->set_option('field_language_add_to_query', $query_options['options']['field_language_add_to_query']);
+      unset($query_options['options']['field_language_add_to_query']);
+      $changed = TRUE;
+    }
+    $this->set_option('query', $query_options);
+
+    // Convert filter groups.
+    $filter_groups = $this->get_option('filter_groups');
+    // Only convert if it wasn't converted yet, which is the case if there is a 0 group.
+    if (isset($filter_groups['groups'][0])) {
+      // Update filter groups.
+      $filter_groups ['groups'] = views_array_key_plus($filter_groups['groups']);
+      $this->set_option('filter_groups', $filter_groups);
+      // Update the filter group on each filter.
+      $filters = $this->get_option('filters');
+      foreach ($filters as &$filter) {
+        if (isset($filter['group'])) {
+          $filter['group']++;
+        }
+        else {
+          $filter['group'] = 1;
+        }
+      }
+      $this->set_option('filters', $filters);
+      $changed = TRUE;
+    }
+
+    // Filter groups were allowed to be rewritten without its filters, so
+    // before this update the view was using the default values. To be sure that
+    // the existing view isn't broken, don't use this overridden values but copy
+    // them from the default display. Only do this if the filters are overridden
+    // but the filter_groups are not marked as so.
+    if (!$this->is_default_display() && !$this->options['defaults']['filters'] && $this->options['defaults']['filter_groups']) {
+      // Set filter_groups to be overridden and save the value in the
+      // display_options as well.
+      $this->options['defaults']['filter_groups'] = FALSE;
+      $this->display->display_options['defaults']['filter_groups'] = $this->options['defaults']['filter_groups'];
+      // Copy the filter_groups from the default, and add them to the
+      // display_options as well. $this->default_display is not initialized at
+      // this point.
+      $this->options['filter_groups'] = $this->view->display['default']->handler->options['filter_groups'];
+      $this->display->display_options['filter_groups'] = $this->options['filter_groups'];
+
+      $changed = TRUE;
+    }
+
+    // Mark the view as changed so the user has a chance to save it.
+    if ($changed) {
+      $this->view->changed = TRUE;
+    }
+  }
+
+  function destroy() {
+    parent::destroy();
+
+    foreach ($this->handlers as $type => $handlers) {
+      foreach ($handlers as $id => $handler) {
+        if (is_object($handler)) {
+          $this->handlers[$type][$id]->destroy();
+        }
+      }
+    }
+
+    if (isset($this->default_display)) {
+      unset($this->default_display);
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->destroy();
+    }
+  }
+
+  /**
+   * Determine if this display is the 'default' display which contains
+   * fallback settings
+   */
+  function is_default_display() { return FALSE; }
+
+  /**
+   * Determine if this display uses exposed filters, so the view
+   * will know whether or not to build them.
+   */
+  function uses_exposed() {
+    if (!isset($this->has_exposed)) {
+      foreach ($this->handlers as $type => $value) {
+        foreach ($this->view->$type as $id => $handler) {
+          if ($handler->can_expose() && $handler->is_exposed()) {
+            // one is all we need; if we find it, return true.
+            $this->has_exposed = TRUE;
+            return TRUE;
+          }
+        }
+      }
+      $pager = $this->get_plugin('pager');
+      if (isset($pager) && $pager->uses_exposed()) {
+        $this->has_exposed = TRUE;
+        return TRUE;
+      }
+      $this->has_exposed = FALSE;
+    }
+
+    return $this->has_exposed;
+  }
+
+  /**
+   * Determine if this display should display the exposed
+   * filters widgets, so the view will know whether or not
+   * to render them.
+   *
+   * Regardless of what this function
+   * returns, exposed filters will not be used nor
+   * displayed unless uses_exposed() returns TRUE.
+   */
+  function displays_exposed() {
+    return TRUE;
+  }
+
+  /**
+   * Does the display use AJAX?
+   */
+  function use_ajax() {
+    if (!empty($this->definition['use ajax'])) {
+      return $this->get_option('use_ajax');
+    }
+    return FALSE;
+  }
+
+  /**
+   * Does the display have a pager enabled?
+   */
+  function use_pager() {
+    $pager = $this->get_plugin('pager');
+    if ($pager) {
+      return $pager->use_pager();
+    }
+  }
+
+  /**
+   * Does the display have a more link enabled?
+   */
+  function use_more() {
+    if (!empty($this->definition['use more'])) {
+      return $this->get_option('use_more');
+    }
+    return FALSE;
+  }
+
+  /**
+   * Does the display have groupby enabled?
+   */
+  function use_group_by() {
+    return $this->get_option('group_by');
+  }
+
+  /**
+   * Should the enabled display more link be shown when no more items?
+   */
+  function use_more_always() {
+    if (!empty($this->definition['use more'])) {
+      return $this->get_option('use_more_always');
+    }
+    return FALSE;
+  }
+
+  /**
+   * Does the display have custom link text?
+   */
+  function use_more_text() {
+    if (!empty($this->definition['use more'])) {
+      return $this->get_option('use_more_text');
+    }
+    return FALSE;
+  }
+
+  /**
+   * Can this display accept attachments?
+   */
+  function accept_attachments() {
+    if (empty($this->definition['accept attachments'])) {
+      return FALSE;
+    }
+    if (!empty($this->view->argument) && $this->get_option('hide_attachment_summary')) {
+      foreach ($this->view->argument as $argument_id => $argument) {
+        if ($argument->needs_style_plugin() && empty($argument->argument_validated)) {
+          return FALSE;
+        }
+      }
+    }
+    return TRUE;
+  }
+
+  /**
+   * Allow displays to attach to other views.
+   */
+  function attach_to($display_id) { }
+
+  /**
+   * Static member function to list which sections are defaultable
+   * and what items each section contains.
+   */
+  function defaultable_sections($section = NULL) {
+    $sections = array(
+      'access' => array('access', 'access_options'),
+      'access_options' => array('access', 'access_options'),
+      'cache' => array('cache', 'cache_options'),
+      'cache_options' => array('cache', 'cache_options'),
+      'title' => array('title'),
+      'css_class' => array('css_class'),
+      'use_ajax' => array('use_ajax'),
+      'hide_attachment_summary' => array('hide_attachment_summary'),
+      'group_by' => array('group_by'),
+      'query' => array('query'),
+      'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
+      'link_display' => array('link_display', 'link_url'),
+
+      // Force these to cascade properly.
+      'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
+      'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
+      'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
+      'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
+
+      'pager' => array('pager', 'pager_options'),
+      'pager_options' => array('pager', 'pager_options'),
+
+      'exposed_form' => array('exposed_form', 'exposed_form_options'),
+      'exposed_form_options' => array('exposed_form', 'exposed_form_options'),
+
+      // These guys are special
+      'header' => array('header'),
+      'footer' => array('footer'),
+      'empty' => array('empty'),
+      'relationships' => array('relationships'),
+      'fields' => array('fields'),
+      'sorts' => array('sorts'),
+      'arguments' => array('arguments'),
+      'filters' => array('filters', 'filter_groups'),
+      'filter_groups' => array('filters', 'filter_groups'),
+    );
+
+    // If the display cannot use a pager, then we cannot default it.
+    if (empty($this->definition['use pager'])) {
+      unset($sections['pager']);
+      unset($sections['items_per_page']);
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->defaultable_sections($sections, $section);
+    }
+
+    if ($section) {
+      if (!empty($sections[$section])) {
+        return $sections[$section];
+      }
+    }
+    else {
+      return $sections;
+    }
+  }
+
+  function option_definition() {
+    $options = array(
+      'defaults' => array(
+        'default' => array(
+          'access' => TRUE,
+          'cache' => TRUE,
+          'query' => TRUE,
+          'title' => TRUE,
+          'css_class' => TRUE,
+
+          'display_description' => FALSE,
+          'use_ajax' => TRUE,
+          'hide_attachment_summary' => TRUE,
+          'pager' => TRUE,
+          'pager_options' => TRUE,
+          'use_more' => TRUE,
+          'use_more_always' => TRUE,
+          'use_more_text' => TRUE,
+          'exposed_form' => TRUE,
+          'exposed_form_options' => TRUE,
+
+          'link_display' => TRUE,
+          'link_url' => '',
+          'group_by' => TRUE,
+
+          'style_plugin' => TRUE,
+          'style_options' => TRUE,
+          'row_plugin' => TRUE,
+          'row_options' => TRUE,
+
+          'header' => TRUE,
+          'footer' => TRUE,
+          'empty' => TRUE,
+
+          'relationships' => TRUE,
+          'fields' => TRUE,
+          'sorts' => TRUE,
+          'arguments' => TRUE,
+          'filters' => TRUE,
+          'filter_groups' => TRUE,
+        ),
+        'export' => FALSE,
+      ),
+
+      'title' => array(
+        'default' => '',
+        'translatable' => TRUE,
+      ),
+      'enabled' => array(
+        'default' => TRUE,
+        'translatable' => FALSE,
+        'bool' => TRUE,
+      ),
+      'display_comment' => array(
+        'default' => '',
+      ),
+      'css_class' => array(
+        'default' => '',
+        'translatable' => FALSE,
+      ),
+      'display_description' => array(
+        'default' => '',
+        'translatable' => TRUE,
+      ),
+      'use_ajax' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'hide_attachment_summary' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      // This is legacy code:
+      // Items_per/offset/use_pager is moved to the pager plugin
+      // but the automatic update path needs this items defined, so don't remove it.
+      // @see views_plugin_display::init()
+      'items_per_page' => array(
+        'default' => 10,
+      ),
+      'offset' => array(
+        'default' => 0,
+      ),
+      'use_pager' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'use_more' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'use_more_always' => array(
+        'default' => FALSE,
+        'bool' => FALSE,
+      ),
+      'use_more_text' => array(
+        'default' => 'more',
+        'translatable' => TRUE,
+      ),
+      'link_display' => array(
+        'default' => '',
+      ),
+      'link_url' => array(
+        'default' => '',
+      ),
+      'group_by' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'field_language' => array(
+        'default' => '***CURRENT_LANGUAGE***',
+      ),
+      'field_language_add_to_query' => array(
+        'default' => 1,
+      ),
+
+      // These types are all plugins that can have individual settings
+      // and therefore need special handling.
+      'access' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
+         ),
+      ),
+      'cache' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
+         ),
+      ),
+      'query' => array(
+        'contains' => array(
+          'type' => array('default' => 'views_query', 'export' => 'export_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
+      ),
+      // Note that exposed_form plugin has options in a separate array,
+      // while access and cache do not. access and cache are legacy and
+      // that pattern should not be repeated, but it is left as is to
+      // reduce the need to modify older views. Let's consider the
+      // pattern used here to be the template from which future plugins
+      // should be copied.
+      'exposed_form' => array(
+        'contains' => array(
+          'type' => array('default' => 'basic', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
+      ),
+      'pager' => array(
+        'contains' => array(
+          'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
+      ),
+
+      // Note that the styles have their options completely independent.
+      // Like access and cache above, this is a legacy pattern and
+      // should not be repeated.
+      'style_plugin' => array(
+        'default' => 'default',
+        'export' => 'export_style',
+        'unpack_translatable' => 'unpack_style',
+      ),
+      'style_options' => array(
+        'default' => array(),
+        'export' => FALSE,
+      ),
+      'row_plugin' => array(
+        'default' => 'fields',
+        'export' => 'export_style',
+        'unpack_translatable' => 'unpack_style',
+      ),
+      'row_options' => array(
+        'default' => array(),
+        'export' => FALSE,
+      ),
+
+      'exposed_block' => array(
+        'default' => FALSE,
+      ),
+
+      'header' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+      'footer' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+      'empty' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+
+      // We want these to export last.
+      // These are the 5 handler types.
+      'relationships' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+
+      ),
+      'fields' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+      'sorts' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+      'arguments' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+      'filter_groups' => array(
+        'contains' => array(
+          'operator' => array('default' => 'AND'),
+          'groups' => array('default' => array(1 => 'AND')),
+        ),
+      ),
+      'filters' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+        'unpack_translatable' => 'unpack_handler',
+      ),
+    );
+
+    if (empty($this->definition['use pager'])) {
+      $options['defaults']['default']['use_pager'] = FALSE;
+      $options['defaults']['default']['items_per_page'] = FALSE;
+      $options['defaults']['default']['offset'] = FALSE;
+      $options['defaults']['default']['pager'] = FALSE;
+      $options['pager']['contains']['type']['default'] = 'some';
+    }
+
+    if ($this->is_default_display()) {
+      unset($options['defaults']);
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->options_definition_alter($options);
+    }
+
+    return $options;
+  }
+
+  /**
+   * Check to see if the display has a 'path' field.
+   *
+   * This is a pure function and not just a setting on the definition
+   * because some displays (such as a panel pane) may have a path based
+   * upon configuration.
+   *
+   * By default, displays do not have a path.
+   */
+  function has_path() { return FALSE; }
+
+  /**
+   * Check to see if the display has some need to link to another display.
+   *
+   * For the most part, displays without a path will use a link display. However,
+   * sometimes displays that have a path might also need to link to another display.
+   * This is true for feeds.
+   */
+  function uses_link_display() { return !$this->has_path(); }
+
+  /**
+   * Check to see if the display can put the exposed formin a block.
+   *
+   * By default, displays that do not have a path cannot disconnect
+   * the exposed form and put it in a block, because the form has no
+   * place to go and Views really wants the forms to go to a specific
+   * page.
+   */
+  function uses_exposed_form_in_block() { return $this->has_path(); }
+
+  /**
+   * Check to see which display to use when creating links within
+   * a view using this display.
+   */
+  function get_link_display() {
+    $display_id = $this->get_option('link_display');
+    // If unknown, pick the first one.
+    if (empty($display_id) || empty($this->view->display[$display_id])) {
+      foreach ($this->view->display as $display_id => $display) {
+        if (!empty($display->handler) && $display->handler->has_path()) {
+          return $display_id;
+        }
+      }
+    }
+    else {
+      return $display_id;
+    }
+    // fall-through returns NULL
+  }
+
+  /**
+   * Return the base path to use for this display.
+   *
+   * This can be overridden for displays that do strange things
+   * with the path.
+   */
+  function get_path() {
+    if ($this->has_path()) {
+      return $this->get_option('path');
+    }
+
+    $display_id = $this->get_link_display();
+    if ($display_id && !empty($this->view->display[$display_id]) && is_object($this->view->display[$display_id]->handler)) {
+      return $this->view->display[$display_id]->handler->get_path();
+    }
+  }
+
+  function get_url() {
+    return $this->view->get_url();
+  }
+
+  /**
+   * Check to see if the display needs a breadcrumb
+   *
+   * By default, displays do not need breadcrumbs
+   */
+  function uses_breadcrumb() { return FALSE; }
+
+  /**
+   * Determine if a given option is set to use the default display or the
+   * current display
+   *
+   * @return
+   *   TRUE for the default display
+   */
+  function is_defaulted($option) {
+    return !$this->is_default_display() && !empty($this->default_display) && !empty($this->options['defaults'][$option]);
+  }
+
+  /**
+   * Intelligently get an option either from this display or from the
+   * default display, if directed to do so.
+   */
+  function get_option($option) {
+    if ($this->is_defaulted($option)) {
+      return $this->default_display->get_option($option);
+    }
+
+    if (array_key_exists($option, $this->options)) {
+      return $this->options[$option];
+    }
+  }
+
+  /**
+   * Determine if the display's style uses fields.
+   */
+  function uses_fields() {
+    $plugin = $this->get_plugin();
+    if ($plugin) {
+      return $plugin->uses_fields();
+    }
+  }
+
+  /**
+   * Get the instance of a plugin, for example style or row.
+   *
+   * @param string $type
+   *   The type of the plugin.
+   * @param string $name
+   *   The name of the plugin defined in hook_views_plugins.
+   *
+   * @return views_plugin|FALSE
+   */
+  function get_plugin($type = 'style', $name = NULL) {
+    static $cache = array();
+    if (!isset($cache[$type][$name])) {
+      switch ($type) {
+        case 'style':
+        case 'row':
+          $option_name = $type . '_plugin';
+          $options = $this->get_option($type . '_options');
+          if (!$name) {
+            $name = $this->get_option($option_name);
+          }
+
+          break;
+        case 'query':
+          $views_data = views_fetch_data($this->view->base_table);
+          $name = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
+        default:
+          $option_name = $type;
+          $options = $this->get_option($type);
+          if (!$name) {
+            $name = $options['type'];
+          }
+
+          // access & cache store their options as siblings with the
+          // type; all others use an 'options' array.
+          if ($type != 'access' && $type != 'cache') {
+            $options = $options['options'];
+          }
+      }
+
+      if ($type != 'query') {
+        $plugin = views_get_plugin($type, $name);
+      }
+      else {
+        $plugin_type = new QueryPluginType();
+        $plugin = $plugin_type->createInstance($name);
+      }
+
+      if (!$plugin) {
+        return;
+      }
+      if ($type != 'query') {
+        $plugin->init($this->view, $this->display, $options);
+      }
+      else {
+        $display_id = $this->is_defaulted($option_name) ? $this->display->id : 'default';
+        $plugin->localization_keys = array($display_id, $type);
+
+        if (!isset($this->base_field)) {
+          $views_data = views_fetch_data($this->view->base_table);
+          $this->view->base_field = !empty($views_data['table']['base']['field']) ? $views_data['table']['base']['field'] : '';
+        }
+        $plugin->init($this->view->base_table, $this->view->base_field, $options);
+      }
+      $cache[$type][$name] = $plugin;
+    }
+
+    return $cache[$type][$name];
+  }
+
+  /**
+   * Get the handler object for a single handler.
+   */
+  function &get_handler($type, $id) {
+    if (!isset($this->handlers[$type])) {
+      $this->get_handlers($type);
+    }
+
+    if (isset($this->handlers[$type][$id])) {
+      return $this->handlers[$type][$id];
+    }
+
+    // So we can return a reference.
+    $null = NULL;
+    return $null;
+  }
+
+  /**
+   * Get a full array of handlers for $type. This caches them.
+   */
+  function get_handlers($type) {
+    if (!isset($this->handlers[$type])) {
+      $this->handlers[$type] = array();
+      $types = View::views_object_types();
+      $plural = $types[$type]['plural'];
+
+      foreach ($this->get_option($plural) as $id => $info) {
+        // If this is during form submission and there are temporary options
+        // which can only appear if the view is in the edit cache, use those
+        // options instead. This is used for AJAX multi-step stuff.
+        if (isset($_POST['form_id']) && isset($this->view->temporary_options[$type][$id])) {
+          $info = $this->view->temporary_options[$type][$id];
+        }
+
+        if ($info['id'] != $id) {
+          $info['id'] = $id;
+        }
+
+        // If aggregation is on, the group type might override the actual
+        // handler that is in use. This piece of code checks that and,
+        // if necessary, sets the override handler.
+        $override = NULL;
+        if ($this->use_group_by() && !empty($info['group_type'])) {
+          if (empty($this->view->query)) {
+            $this->view->init_query();
+          }
+          $aggregate = $this->view->query->get_aggregation_info();
+          if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
+            $override = $aggregate[$info['group_type']]['handler'][$type];
+          }
+        }
+
+        if (!empty($types[$type]['type'])) {
+          $handler_type = $types[$type]['type'];
+        }
+        else {
+          $handler_type = $type;
+        }
+
+        $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
+        if ($handler) {
+          // Special override for area types so they know where they come from.
+          if ($handler_type == 'area') {
+            $handler->handler_type = $type;
+          }
+
+          $handler->init($this->view, $info);
+          $this->handlers[$type][$id] = &$handler;
+        }
+
+        // Prevent reference problems.
+        unset($handler);
+      }
+    }
+
+    return $this->handlers[$type];
+  }
+
+  /**
+   * Retrieve a list of fields for the current display with the
+   *  relationship associated if it exists.
+   */
+  function get_field_labels() {
+    $options = array();
+    foreach ($this->get_handlers('relationship') as $relationship => $handler) {
+      if ($label = $handler->label()) {
+        $relationships[$relationship] = $label;
+      }
+      else {
+        $relationships[$relationship] = $handler->ui_name();
+      }
+    }
+
+    foreach ($this->get_handlers('field') as $id => $handler) {
+      if ($label = $handler->label()) {
+        $options[$id] = $label;
+      }
+      else {
+        $options[$id] = $handler->ui_name();
+      }
+      if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) {
+        $options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id];
+      }
+    }
+    return $options;
+  }
+
+  /**
+   * Intelligently set an option either from this display or from the
+   * default display, if directed to do so.
+   */
+  function set_option($option, $value) {
+    if ($this->is_defaulted($option)) {
+      return $this->default_display->set_option($option, $value);
+    }
+
+    // Set this in two places: On the handler where we'll notice it
+    // but also on the display object so it gets saved. This should
+    // only be a temporary fix.
+    $this->display->display_options[$option] = $value;
+    return $this->options[$option] = $value;
+  }
+
+  /**
+   * Set an option and force it to be an override.
+   */
+  function override_option($option, $value) {
+    $this->set_override($option, FALSE);
+    $this->set_option($option, $value);
+  }
+
+  /**
+   * Because forms may be split up into sections, this provides
+   * an easy URL to exactly the right section. Don't override this.
+   */
+  function option_link($text, $section, $class = '', $title = '') {
+    views_add_js('ajax');
+    if (!empty($class)) {
+      $text = '<span>' . $text . '</span>';
+    }
+
+    if (!trim($text)) {
+      $text = t('Broken field');
+    }
+
+    if (empty($title)) {
+      $title = $text;
+    }
+
+    return l($text, 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title, 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section)), 'html' => TRUE));
+  }
+
+  /**
+   * Returns to tokens for arguments.
+   *
+   * This function is similar to views_handler_field::get_render_tokens()
+   * but without fields tokens.
+   */
+  function get_arguments_tokens() {
+    $tokens = array();
+    if (!empty($this->view->build_info['substitutions'])) {
+      $tokens = $this->view->build_info['substitutions'];
+    }
+    $count = 0;
+    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+      $token = '%' . ++$count;
+      if (!isset($tokens[$token])) {
+        $tokens[$token] = '';
+      }
+
+      // Use strip tags as there should never be HTML in the path.
+      // However, we need to preserve special characters like " that
+      // were removed by check_plain().
+      $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(decode_entities($this->view->args[$count - 1])) : '';
+    }
+
+    return $tokens;
+  }
+
+  /**
+   * Provide the default summary for options in the views UI.
+   *
+   * This output is returned as an array.
+   */
+  function options_summary(&$categories, &$options) {
+    $categories = array(
+      'title' => array(
+        'title' => t('Title'),
+        'column' => 'first',
+      ),
+      'format' => array(
+        'title' => t('Format'),
+        'column' => 'first',
+      ),
+      'filters' => array(
+        'title' => t('Filters'),
+        'column' => 'first',
+      ),
+      'fields' => array(
+        'title' => t('Fields'),
+        'column' => 'first',
+      ),
+      'pager' => array(
+        'title' => t('Pager'),
+        'column' => 'second',
+      ),
+      'exposed' => array(
+        'title' => t('Exposed form'),
+        'column' => 'third',
+        'build' => array(
+          '#weight' => 1,
+        ),
+      ),
+      'access' => array(
+        'title' => '',
+        'column' => 'second',
+        'build' => array(
+          '#weight' => -5,
+        ),
+      ),
+      'other' => array(
+        'title' => t('Other'),
+        'column' => 'third',
+        'build' => array(
+          '#weight' => 2,
+        ),
+      ),
+    );
+
+    if ($this->display->id != 'default') {
+      $options['display_id'] = array(
+        'category' => 'other',
+        'title' => t('Machine Name'),
+        'value' => !empty($this->display->new_id) ? check_plain($this->display->new_id) : check_plain($this->display->id),
+        'desc' => t('Change the machine name of this display.'),
+      );
+    }
+
+    $display_comment = check_plain(drupal_substr($this->get_option('display_comment'), 0, 10));
+    $options['display_comment'] = array(
+      'category' => 'other',
+      'title' => t('Comment'),
+      'value' => !empty($display_comment) ? $display_comment : t('No comment'),
+      'desc' => t('Comment or document this display.'),
+    );
+
+    $title = strip_tags($this->get_option('title'));
+    if (!$title) {
+      $title = t('None');
+    }
+
+    $options['title'] = array(
+      'category' => 'title',
+      'title' => t('Title'),
+      'value' => $title,
+      'desc' => t('Change the title that this display will use.'),
+    );
+
+    $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
+    $style_plugin_instance = $this->get_plugin('style');
+    $style_summary = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->summary_title();
+    $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->plugin_title();
+
+    $style = '';
+
+    $options['style_plugin'] = array(
+      'category' => 'format',
+      'title' => t('Format'),
+      'value' => $style_title,
+      'setting' => $style_summary,
+      'desc' => t('Change the way content is formatted.'),
+    );
+
+    // This adds a 'Settings' link to the style_options setting if the style has options.
+    if (!empty($style_plugin['uses options'])) {
+      $options['style_plugin']['links']['style_options'] = t('Change settings for this format');
+    }
+
+    if (!empty($style_plugin['uses row plugin'])) {
+      $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
+      $row_plugin_instance = $this->get_plugin('row');
+      $row_summary = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->summary_title();
+      $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->plugin_title();
+
+      $options['row_plugin'] = array(
+        'category' => 'format',
+        'title' => t('Show'),
+        'value' => $row_title,
+        'setting' => $row_summary,
+        'desc' => t('Change the way each row in the view is styled.'),
+      );
+      // This adds a 'Settings' link to the row_options setting if the row style has options.
+      if (!empty($row_plugin['uses options'])) {
+        $options['row_plugin']['links']['row_options'] = t('Change settings for this style');
+      }
+    }
+    if (!empty($this->definition['use ajax'])) {
+      $options['use_ajax'] = array(
+        'category' => 'other',
+        'title' => t('Use AJAX'),
+        'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
+        'desc' => t('Change whether or not this display will use AJAX.'),
+      );
+    }
+    if (!empty($this->definition['accept attachments'])) {
+      $options['hide_attachment_summary'] = array(
+        'category' => 'other',
+        'title' => t('Hide attachments in summary'),
+        'value' => $this->get_option('hide_attachment_summary') ? t('Yes') : t('No'),
+        'desc' => t('Change whether or not to display attachments when displaying a contextual filter summary.'),
+      );
+    }
+
+    $pager_plugin = $this->get_plugin('pager');
+    if (!$pager_plugin) {
+      // default to the no pager plugin.
+      $pager_plugin = views_get_plugin('pager', 'none');
+    }
+
+    $pager_str = $pager_plugin->summary_title();
+
+    $options['pager'] = array(
+      'category' => 'pager',
+      'title' => t('Use pager'),
+      'value' => $pager_plugin->plugin_title(),
+      'setting' => $pager_str,
+      'desc' => t("Change this display's pager setting."),
+    );
+
+    // If pagers aren't allowed, change the text of the item:
+    if (empty($this->definition['use pager'])) {
+      $options['pager']['title'] = t('Items to display');
+    }
+
+    if (!empty($pager_plugin->definition['uses options'])) {
+      $options['pager']['links']['pager_options'] = t('Change settings for this pager type.');
+    }
+
+    if (!empty($this->definition['use more'])) {
+      $options['use_more'] = array(
+        'category' => 'pager',
+        'title' => t('More link'),
+        'value' => $this->get_option('use_more') ? t('Yes') : t('No'),
+        'desc' => t('Specify whether this display will provide a "more" link.'),
+      );
+    }
+
+    $this->view->init_query();
+    if ($this->view->query->get_aggregation_info()) {
+      $options['group_by'] = array(
+        'category' => 'other',
+        'title' => t('Use aggregation'),
+        'value' => $this->get_option('group_by') ? t('Yes') : t('No'),
+        'desc' => t('Allow grouping and aggregation (calculation) of fields.'),
+      );
+    }
+
+    $options['query'] = array(
+      'category' => 'other',
+      'title' => t('Query settings'),
+      'value' => t('Settings'),
+      'desc' => t('Allow to set some advanced settings for the query plugin'),
+    );
+
+    $languages = array(
+        '***CURRENT_LANGUAGE***' => t("Current user's language"),
+        '***DEFAULT_LANGUAGE***' => t("Default site language"),
+        LANGUAGE_NOT_SPECIFIED => t('Language neutral'),
+    );
+    if (module_exists('language')) {
+      $languages = array_merge($languages, language_list());
+    }
+    $field_language = array();
+    $options['field_language'] = array(
+      'category' => 'other',
+      'title' => t('Field Language'),
+      'value' => $languages[$this->get_option('field_language')],
+      'desc' => t('All fields which support translations will be displayed in the selected language.'),
+    );
+
+    $access_plugin = $this->get_plugin('access');
+    if (!$access_plugin) {
+      // default to the no access control plugin.
+      $access_plugin = views_get_plugin('access', 'none');
+    }
+
+    $access_str = $access_plugin->summary_title();
+
+    $options['access'] = array(
+      'category' => 'access',
+      'title' => t('Access'),
+      'value' => $access_plugin->plugin_title(),
+      'setting' => $access_str,
+      'desc' => t('Specify access control type for this display.'),
+    );
+
+    if (!empty($access_plugin->definition['uses options'])) {
+      $options['access']['links']['access_options'] = t('Change settings for this access type.');
+    }
+
+    $cache_plugin = $this->get_plugin('cache');
+    if (!$cache_plugin) {
+      // default to the no cache control plugin.
+      $cache_plugin = views_get_plugin('cache', 'none');
+    }
+
+    $cache_str = $cache_plugin->summary_title();
+
+    $options['cache'] = array(
+      'category' => 'other',
+      'title' => t('Caching'),
+      'value' => $cache_plugin->plugin_title(),
+      'setting' => $cache_str,
+      'desc' => t('Specify caching type for this display.'),
+    );
+
+    if (!empty($cache_plugin->definition['uses options'])) {
+      $options['cache']['links']['cache_options'] = t('Change settings for this caching type.');
+    }
+
+    if (!empty($access_plugin->definition['uses options'])) {
+      $options['access']['links']['access_options'] = t('Change settings for this access type.');
+    }
+
+    if ($this->uses_link_display()) {
+      $display_id = $this->get_link_display();
+      $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
+      $link_display =  $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display;
+      $options['link_display'] = array(
+        'category' => 'other',
+        'title' => t('Link display'),
+        'value' => $link_display,
+        'desc' => t('Specify which display or custom url this display will link to.'),
+      );
+    }
+
+    if ($this->uses_exposed_form_in_block()) {
+      $options['exposed_block'] = array(
+        'category' => 'exposed',
+        'title' => t('Exposed form in block'),
+        'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
+        'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
+      );
+    }
+
+    $exposed_form_plugin = $this->get_plugin('exposed_form');
+    if (!$exposed_form_plugin) {
+      // default to the no cache control plugin.
+      $exposed_form_plugin = views_get_plugin('exposed_form', 'basic');
+    }
+
+    $exposed_form_str = $exposed_form_plugin->summary_title();
+
+    $options['exposed_form'] = array(
+      'category' => 'exposed',
+      'title' => t('Exposed form style'),
+      'value' => $exposed_form_plugin->plugin_title(),
+      'setting' => $exposed_form_str,
+      'desc' => t('Select the kind of exposed filter to use.'),
+    );
+
+    if (!empty($exposed_form_plugin->definition['uses options'])) {
+      $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.');
+    }
+
+    $css_class = check_plain(trim($this->get_option('css_class')));
+    if (!$css_class) {
+      $css_class = t('None');
+    }
+
+    $options['css_class'] = array(
+      'category' => 'other',
+      'title' => t('CSS class'),
+      'value' => $css_class,
+      'desc' => t('Change the CSS class name(s) that will be added to this display.'),
+    );
+
+    $options['analyze-theme'] = array(
+      'category' => 'other',
+      'title' => t('Theme'),
+      'value' => t('Information'),
+      'desc' => t('Get information on how to theme this display'),
+    );
+
+    foreach ($this->extender as $extender) {
+      $extender->options_summary($categories, $options);
+    }
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    if ($this->defaultable_sections($form_state['section'])) {
+      views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
+    }
+    $form['#title'] = check_plain($this->display->display_title) . ': ';
+
+    // Set the 'section' to hilite on the form.
+    // If it's the item we're looking at is pulling from the default display,
+    // reflect that. Don't use is_defaulted since we want it to show up even
+    // on the default display.
+    if (!empty($this->options['defaults'][$form_state['section']])) {
+      $form['#section'] = 'default-' . $form_state['section'];
+    }
+    else {
+      $form['#section'] = $this->display->id . '-' . $form_state['section'];
+    }
+
+    switch ($form_state['section']) {
+      case 'display_id':
+        $form['#title'] .= t('The machine name of this display');
+        $form['display_id'] = array(
+          '#type' => 'textfield',
+          '#description' => t('This is machine name of the display.'),
+          '#default_value' => !empty($this->display->new_id) ? $this->display->new_id : $this->display->id,
+          '#required' => TRUE,
+          '#size' => 64,
+        );
+        break;
+      case 'display_title':
+        $form['#title'] .= t('The name and the description of this display');
+        $form['display_title'] = array(
+          '#title' => t('Name'),
+          '#type' => 'textfield',
+          '#description' => t('This name will appear only in the administrative interface for the View.'),
+          '#default_value' => $this->display->display_title,
+        );
+        $form['display_description'] = array(
+          '#title' => t('Description'),
+          '#type' => 'textfield',
+          '#description' => t('This description will appear only in the administrative interface for the View.'),
+          '#default_value' => $this->get_option('display_description'),
+        );
+        break;
+      case 'display_comment':
+        $form['#title'] .= t("This display's comments");
+        $form['display_comment'] = array(
+          '#type' => 'textarea',
+          '#description' => t('This value will be seen and used only within the Views UI and can be used to document this display. You can use this to provide notes for other or future maintainers of your site about how or why this display is configured.'),
+          '#default_value' => $this->get_option('display_comment'),
+        );
+        break;
+      case 'title':
+        $form['#title'] .= t('The title of this view');
+        $form['title'] = array(
+          '#type' => 'textfield',
+          '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'),
+          '#default_value' => $this->get_option('title'),
+        );
+        break;
+      case 'css_class':
+        $form['#title'] .= t('CSS class');
+        $form['css_class'] = array(
+          '#type' => 'textfield',
+          '#description' => t('The CSS class names will be added to the view. This enables you to use specific CSS code for each view. You may define multiples classes separated by spaces.'),
+          '#default_value' => $this->get_option('css_class'),
+        );
+        break;
+      case 'use_ajax':
+        $form['#title'] .= t('Use AJAX when available to load this view');
+        $form['description'] = array(
+          '#markup' => '<div class="description form-item">' . t('If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content.') . '</div>',
+        );
+        $form['use_ajax'] = array(
+          '#type' => 'radios',
+          '#options' => array(1 => t('Yes'), 0 => t('No')),
+          '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
+        );
+        break;
+      case 'hide_attachment_summary':
+        $form['#title'] .= t('Hide attachments when displaying a contextual filter summary');
+        $form['hide_attachment_summary'] = array(
+          '#type' => 'radios',
+          '#options' => array(1 => t('Yes'), 0 => t('No')),
+          '#default_value' => $this->get_option('hide_attachment_summary') ? 1 : 0,
+        );
+        break;
+      case 'use_more':
+        $form['#title'] .= t('Add a more link to the bottom of the display.');
+        $form['use_more'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Create more link'),
+          '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above. You can override the url at the link display setting."),
+          '#default_value' => $this->get_option('use_more'),
+        );
+        $form['use_more_always'] = array(
+          '#type' => 'checkbox',
+          '#title' => t("Display 'more' link only if there is more content"),
+          '#description' => t("Leave this unchecked to display the 'more' link even if there are no more items to display."),
+          '#default_value' => !$this->get_option('use_more_always'),
+          '#states' => array(
+            'visible' => array(
+              ':input[name="use_more"]' => array('checked' => TRUE),
+            ),
+          ),
+        );
+        $form['use_more_text'] = array(
+          '#type' => 'textfield',
+          '#title' => t('More link text'),
+          '#description' => t("The text to display for the more link."),
+          '#default_value' => $this->get_option('use_more_text'),
+          '#states' => array(
+            'visible' => array(
+              ':input[name="use_more"]' => array('checked' => TRUE),
+            ),
+          ),
+        );
+        break;
+      case 'group_by':
+        $form['#title'] .= t('Allow grouping and aggregation (calculation) of fields.');
+        $form['group_by'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Aggregate'),
+          '#description' => t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'),
+          '#default_value' => $this->get_option('group_by'),
+        );
+        break;
+      case 'access':
+        $form['#title'] .= t('Access restrictions');
+        $form['access'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $access = $this->get_option('access');
+        $form['access']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('access', NULL, array($this->view->base_table)),
+          '#default_value' => $access['type'],
+        );
+
+        $access_plugin = views_fetch_plugin_data('access', $access['type']);
+        if (!empty($access_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#markup' => t('You may also adjust the !settings for the currently selected access restriction.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
+            '#suffix' => '</div>',
+          );
+        }
+
+        break;
+      case 'access_options':
+        $access = $this->get_option('access');
+        $plugin = $this->get_plugin('access');
+        $form['#title'] .= t('Access options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+          $form['#help_module'] = $plugin->definition['module'];
+
+          $form['access_options'] = array(
+            '#tree' => TRUE,
+          );
+          $form['access_options']['type'] = array(
+            '#type' => 'value',
+            '#value' => $access['type'],
+          );
+          $plugin->options_form($form['access_options'], $form_state);
+        }
+        break;
+      case 'cache':
+        $form['#title'] .= t('Caching');
+        $form['cache'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $cache = $this->get_option('cache');
+        $form['cache']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('cache', NULL, array($this->view->base_table)),
+          '#default_value' => $cache['type'],
+        );
+
+        $cache_plugin = views_fetch_plugin_data('cache', $cache['type']);
+        if (!empty($cache_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#suffix' => '</div>',
+            '#markup' => t('You may also adjust the !settings for the currently selected cache mechanism.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
+          );
+        }
+        break;
+      case 'cache_options':
+        $cache = $this->get_option('cache');
+        $plugin = $this->get_plugin('cache');
+        $form['#title'] .= t('Caching options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+          $form['#help_module'] = $plugin->definition['module'];
+
+          $form['cache_options'] = array(
+            '#tree' => TRUE,
+          );
+          $form['cache_options']['type'] = array(
+            '#type' => 'value',
+            '#value' => $cache['type'],
+          );
+          $plugin->options_form($form['cache_options'], $form_state);
+        }
+        break;
+      case 'query':
+        $query_options = $this->get_option('query');
+        $plugin_name = $query_options['type'];
+
+        $form['#title'] .= t('Query options');
+        $this->view->init_query();
+        if ($this->view->query) {
+          if (isset($this->view->query->definition['help topic'])) {
+            $form['#help_topic'] = $this->view->query->definition['help topic'];
+          }
+
+          if (isset($this->view->query->definition['module'])) {
+            $form['#help_module'] = $this->view->query->definition['module'];
+          }
+
+          $form['query'] = array(
+            '#tree' => TRUE,
+            'type' => array(
+              '#type' => 'value',
+              '#value' => $plugin_name,
+            ),
+            'options' => array(
+              '#tree' => TRUE,
+            ),
+          );
+
+          $this->view->query->options_form($form['query']['options'], $form_state);
+        }
+        break;
+      case 'field_language':
+        $form['#title'] .= t('Field Language');
+
+        $entities = entity_get_info();
+        $entity_tables = array();
+        $has_translation_handlers = FALSE;
+        foreach ($entities as $type => $entity_info) {
+          $entity_tables[] = $entity_info['base table'];
+
+          if (!empty($entity_info['translation'])) {
+            $has_translation_handlers = TRUE;
+          }
+        }
+
+        // Doesn't make sense to show a field setting here if we aren't querying
+        // an entity base table. Also, we make sure that there's at least one
+        // entity type with a translation handler attached.
+        if (in_array($this->view->base_table, $entity_tables) && $has_translation_handlers) {
+          $languages = array(
+            '***CURRENT_LANGUAGE***' => t("Current user's language"),
+            '***DEFAULT_LANGUAGE***' => t("Default site language"),
+            LANGUAGE_NOT_SPECIFIED => t('Language neutral'),
+          );
+          $languages = array_merge($languages, views_language_list());
+
+          $form['field_language'] = array(
+            '#type' => 'select',
+            '#title' => t('Field Language'),
+            '#description' => t('All fields which support translations will be displayed in the selected language.'),
+            '#options' => $languages,
+            '#default_value' => $this->get_option('field_language'),
+          );
+          $form['field_language_add_to_query'] = array(
+            '#type' => 'checkbox',
+            '#title' => t('When needed, add the field language condition to the query'),
+            '#default_value' => $this->get_option('field_language_add_to_query'),
+          );
+        }
+        else {
+          $form['field_language']['#markup'] = t("You don't have translatable entity types.");
+        }
+        break;
+      case 'style_plugin':
+        $form['#title'] .= t('How should this view be styled');
+        $form['#help_topic'] = 'style';
+        $form['style_plugin'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)),
+          '#default_value' => $this->get_option('style_plugin'),
+          '#description' => t('If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary.'),
+        );
+
+        $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
+        if (!empty($style_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'style_options'))) . '</div>',
+          );
+        }
+
+        break;
+      case 'style_options':
+        $form['#title'] .= t('Style options');
+        $style = TRUE;
+        $type = 'style_plugin';
+        $name = $this->get_option('style_plugin');
+
+      case 'row_options':
+        if (!isset($name)) {
+          $name = $this->get_option('row_plugin');
+        }
+        // if row, $style will be empty.
+        if (empty($style)) {
+          $form['#title'] .= t('Row style options');
+          $type = 'row_plugin';
+        }
+        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
+        if ($plugin) {
+          if (isset($plugin->definition['help topic'])) {
+            $form['#help_topic'] = $plugin->definition['help topic'];
+            $form['#help_module'] = $plugin->definition['module'];
+          }
+          $form[$form_state['section']] = array(
+            '#tree' => TRUE,
+          );
+          $plugin->options_form($form[$form_state['section']], $form_state);
+        }
+        break;
+      case 'row_plugin':
+        $form['#title'] .= t('How should each row in this view be styled');
+        $form['#help_topic'] = 'style-row';
+        $form['row_plugin'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)),
+          '#default_value' => $this->get_option('row_plugin'),
+        );
+
+        $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
+        if (!empty($row_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected row style.', array('!settings' => $this->option_link(t('settings'), 'row_options'))) . '</div>',
+          );
+        }
+
+        break;
+      case 'link_display':
+        $form['#title'] .= t('Which display to use for path');
+        foreach ($this->view->display as $display_id => $display) {
+          if ($display->handler->has_path()) {
+            $options[$display_id] = $display->display_title;
+          }
+        }
+        $options['custom_url'] = t('Custom URL');
+        if (count($options)) {
+          $form['link_display'] = array(
+            '#type' => 'radios',
+            '#options' => $options,
+            '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
+            '#default_value' => $this->get_option('link_display'),
+          );
+        }
+
+        $options = array();
+        $count = 0; // This lets us prepare the key as we want it printed.
+        foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+          $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
+          $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
+        }
+
+        // Default text.
+        // We have some options, so make a list.
+        $output = '';
+        if (!empty($options)) {
+          $output = t('<p>The following tokens are available for this link.</p>');
+          foreach (array_keys($options) as $type) {
+            if (!empty($options[$type])) {
+              $items = array();
+              foreach ($options[$type] as $key => $value) {
+                $items[] = $key . ' == ' . $value;
+              }
+              $output .= theme('item_list',
+                array(
+                  'items' => $items,
+                  'type' => $type
+                ));
+            }
+          }
+        }
+
+        $form['link_url'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Custom URL'),
+          '#default_value' => $this->get_option('link_url'),
+          '#description' => t('A Drupal path or external URL the more link will point to. Note that this will override the link display setting above.') . $output,
+          '#states' => array(
+            'visible' => array(
+              ':input[name="link_display"]' => array('value' => 'custom_url'),
+            ),
+          ),
+        );
+        break;
+      case 'analyze-theme':
+        $form['#title'] .= t('Theming information');
+        $form['#help_topic'] = 'analyze-theme';
+
+        if (isset($_POST['theme'])) {
+          $this->theme = $_POST['theme'];
+        }
+        elseif (empty($this->theme)) {
+          $this->theme = variable_get('theme_default', 'bartik');
+        }
+
+        if (isset($GLOBALS['theme']) && $GLOBALS['theme'] == $this->theme) {
+          $this->theme_registry = theme_get_registry();
+          $theme_engine = $GLOBALS['theme_engine'];
+        }
+        else {
+          $themes = list_themes();
+          $theme = $themes[$this->theme];
+
+          // Find all our ancestor themes and put them in an array.
+          $base_theme = array();
+          $ancestor = $this->theme;
+          while ($ancestor && isset($themes[$ancestor]->base_theme)) {
+            $ancestor = $themes[$ancestor]->base_theme;
+            $base_theme[] = $themes[$ancestor];
+          }
+
+          // The base themes should be initialized in the right order.
+          $base_theme = array_reverse($base_theme);
+
+          // This code is copied directly from _drupal_theme_initialize()
+          $theme_engine = NULL;
+
+          // Initialize the theme.
+          if (isset($theme->engine)) {
+            // Include the engine.
+            include_once DRUPAL_ROOT . '/' . $theme->owner;
+
+            $theme_engine = $theme->engine;
+            if (function_exists($theme_engine . '_init')) {
+              foreach ($base_theme as $base) {
+                call_user_func($theme_engine . '_init', $base);
+              }
+              call_user_func($theme_engine . '_init', $theme);
+            }
+          }
+          else {
+            // include non-engine theme files
+            foreach ($base_theme as $base) {
+              // Include the theme file or the engine.
+              if (!empty($base->owner)) {
+                include_once DRUPAL_ROOT . '/' . $base->owner;
+              }
+            }
+            // and our theme gets one too.
+            if (!empty($theme->owner)) {
+              include_once DRUPAL_ROOT . '/' . $theme->owner;
+            }
+          }
+          $this->theme_registry = _theme_load_registry($theme, $base_theme, $theme_engine);
+        }
+
+        // If there's a theme engine involved, we also need to know its extension
+        // so we can give the proper filename.
+        $this->theme_extension = '.tpl.php';
+        if (isset($theme_engine)) {
+          $extension_function = $theme_engine . '_extension';
+          if (function_exists($extension_function)) {
+            $this->theme_extension = $extension_function();
+          }
+        }
+
+        $funcs = array();
+        // Get theme functions for the display. Note that some displays may
+        // not have themes. The 'feed' display, for example, completely
+        // delegates to the style.
+        if (!empty($this->definition['theme'])) {
+          $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': '  . $this->format_themes($this->theme_functions());
+          $themes = $this->additional_theme_functions();
+          if ($themes) {
+            foreach ($themes as $theme) {
+              $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': '  . $this->format_themes($theme);
+            }
+          }
+        }
+
+        $plugin = $this->get_plugin();
+        if ($plugin) {
+          $funcs[] = $this->option_link(t('Style output'), 'analyze-theme-style') . ': ' . $this->format_themes($plugin->theme_functions(), $plugin->additional_theme_functions());
+          $themes = $plugin->additional_theme_functions();
+          if ($themes) {
+            foreach ($themes as $theme) {
+              $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': '  . $this->format_themes($theme);
+            }
+          }
+
+          if ($plugin->uses_row_plugin()) {
+            $row_plugin = $this->get_plugin('row');
+            if ($row_plugin) {
+              $funcs[] = $this->option_link(t('Row style output'), 'analyze-theme-row') . ': ' . $this->format_themes($row_plugin->theme_functions());
+              $themes = $row_plugin->additional_theme_functions();
+              if ($themes) {
+                foreach ($themes as $theme) {
+                  $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': '  . $this->format_themes($theme);
+                }
+              }
+            }
+          }
+
+          if ($plugin->uses_fields()) {
+            foreach ($this->get_handlers('field') as $id => $handler) {
+              $funcs[] = $this->option_link(t('Field @field (ID: @id)', array('@field' => $handler->ui_name(), '@id' => $id)), 'analyze-theme-field') . ': ' . $this->format_themes($handler->theme_functions());
+            }
+          }
+        }
+
+        $form['important'] = array(
+          '#markup' => '<div class="form-item description"><p>' . t('This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold.') . '</p></div>',
+        );
+
+        if (isset($this->view->display[$this->view->current_display]->new_id)) {
+          $form['important']['new_id'] = array(
+            '#prefix' => '<div class="description">',
+            '#suffix' => '</div>',
+            '#value' => t("<strong>Important!</strong> You have changed the display's machine name. Anything that attached to this display specifically, such as theming, may stop working until it is updated. To see theme suggestions for it, you need to save the view."),
+          );
+        }
+
+        foreach (list_themes() as $key => $theme) {
+          if (!empty($theme->info['hidden'])) {
+            continue;
+          }
+          $options[$key] = $theme->info['name'];
+        }
+
+        $form['box'] = array(
+          '#prefix' => '<div class="container-inline">',
+          '#suffix' => '</div>',
+        );
+        $form['box']['theme'] = array(
+          '#type' => 'select',
+          '#options' => $options,
+          '#default_value' => $this->theme,
+        );
+
+        $form['box']['change'] = array(
+          '#type' => 'submit',
+          '#value' => t('Change theme'),
+          '#submit' => array('views_ui_edit_display_form_change_theme'),
+        );
+
+        $form['analysis'] = array(
+          '#markup' => '<div class="form-item">' . theme('item_list', array('items' => $funcs)) . '</div>',
+        );
+
+        $form['rescan_button'] = array(
+          '#prefix' => '<div class="form-item">',
+          '#suffix' => '</div>',
+        );
+        $form['rescan_button']['button'] = array(
+          '#type' => 'submit',
+          '#value' => t('Rescan template files'),
+          '#submit' => array('views_ui_config_item_form_rescan'),
+        );
+        $form['rescan_button']['markup'] = array(
+          '#markup' => '<div class="description">' . t("<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system.") . '</div>',
+        );
+
+        $form_state['ok_button'] = TRUE;
+        break;
+      case 'analyze-theme-display':
+        $form['#title'] .= t('Theming information (display)');
+        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
+
+        if (empty($this->definition['theme'])) {
+          $output .= t('This display has no theming information');
+        }
+        else {
+          $output .= '<p>' . t('This is the default theme template used for this display.') . '</p>';
+          $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($this->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
+        }
+
+        if (!empty($this->definition['additional themes'])) {
+          foreach ($this->definition['additional themes'] as $theme => $type) {
+            $output .= '<p>' . t('This is an alternative template for this display.') . '</p>';
+            $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
+          }
+        }
+
+        $form['analysis'] = array(
+          '#markup' => '<div class="form-item">' . $output . '</div>',
+        );
+
+        $form_state['ok_button'] = TRUE;
+        break;
+      case 'analyze-theme-style':
+        $form['#title'] .= t('Theming information (style)');
+        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
+
+        $plugin = $this->get_plugin();
+
+        if (empty($plugin->definition['theme'])) {
+          $output .= t('This display has no style theming information');
+        }
+        else {
+          $output .= '<p>' . t('This is the default theme template used for this style.') . '</p>';
+          $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
+        }
+
+        if (!empty($plugin->definition['additional themes'])) {
+          foreach ($plugin->definition['additional themes'] as $theme => $type) {
+            $output .= '<p>' . t('This is an alternative template for this style.') . '</p>';
+            $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
+          }
+        }
+
+        $form['analysis'] = array(
+          '#markup' => '<div class="form-item">' . $output . '</div>',
+        );
+
+        $form_state['ok_button'] = TRUE;
+        break;
+      case 'analyze-theme-row':
+        $form['#title'] .= t('Theming information (row style)');
+        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
+
+        $plugin = $this->get_plugin('row');
+
+        if (empty($plugin->definition['theme'])) {
+          $output .= t('This display has no row style theming information');
+        }
+        else {
+          $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
+          $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
+        }
+
+        if (!empty($plugin->definition['additional themes'])) {
+          foreach ($plugin->definition['additional themes'] as $theme => $type) {
+            $output .= '<p>' . t('This is an alternative template for this row style.') . '</p>';
+            $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
+          }
+        }
+
+        $form['analysis'] = array(
+          '#markup' => '<div class="form-item">' . $output . '</div>',
+        );
+
+        $form_state['ok_button'] = TRUE;
+        break;
+      case 'analyze-theme-field':
+        $form['#title'] .= t('Theming information (row style)');
+        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
+
+        $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
+
+        // Field templates aren't registered the normal way...and they're always
+        // this one, anyhow.
+        $output .= '<pre>' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '</pre>';
+
+        $form['analysis'] = array(
+          '#markup' => '<div class="form-item">' . $output . '</div>',
+        );
+        $form_state['ok_button'] = TRUE;
+        break;
+
+      case 'exposed_block':
+        $form['#title'] .= t('Put the exposed form in a block');
+        $form['description'] = array(
+          '#markup' => '<div class="description form-item">' . t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.') . '</div>',
+        );
+        $form['exposed_block'] = array(
+          '#type' => 'radios',
+          '#options' => array(1 => t('Yes'), 0 => t('No')),
+          '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
+        );
+        break;
+      case 'exposed_form':
+        $form['#title'] .= t('Exposed Form');
+        $form['exposed_form'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $exposed_form = $this->get_option('exposed_form');
+        $form['exposed_form']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('exposed_form', NULL, array($this->view->base_table)),
+          '#default_value' => $exposed_form['type'],
+        );
+
+        $exposed_form_plugin = views_fetch_plugin_data('exposed_form', $exposed_form['type']);
+        if (!empty($exposed_form_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#suffix' => '</div>',
+            '#markup' => t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'exposed_form_options'))),
+          );
+        }
+        break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        $form['#title'] .= t('Exposed form options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+
+          $form['exposed_form_options'] = array(
+            '#tree' => TRUE,
+          );
+          $plugin->options_form($form['exposed_form_options'], $form_state);
+        }
+        break;
+      case 'pager':
+        $form['#title'] .= t('Select which pager, if any, to use for this view');
+        $form['pager'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $pager = $this->get_option('pager');
+        $form['pager']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('pager', empty($this->definition['use pager']) ? 'basic' : NULL, array($this->view->base_table)),
+          '#default_value' => $pager['type'],
+        );
+
+        $pager_plugin = views_fetch_plugin_data('pager', $pager['type'], array($this->view->base_table));
+        if (!empty($pager_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#suffix' => '</div>',
+            '#markup' => t('You may also adjust the !settings for the currently selected pager.', array('!settings' => $this->option_link(t('settings'), 'pager_options'))),
+          );
+        }
+
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        $form['#title'] .= t('Pager options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+
+          $form['pager_options'] = array(
+            '#tree' => TRUE,
+          );
+          $plugin->options_form($form['pager_options'], $form_state);
+        }
+        break;
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->options_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Format a list of theme templates for output by the theme info helper.
+   */
+  function format_themes($themes) {
+    $registry = $this->theme_registry;
+    $extension = $this->theme_extension;
+
+    $output = '';
+    $picked = FALSE;
+    foreach ($themes as $theme) {
+      $template = strtr($theme, '_', '-') . $extension;
+      if (!$picked && !empty($registry[$theme])) {
+        $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './';
+        if (file_exists($template_path . $template)) {
+          $hint = t('File found in folder @template-path', array('@template-path' => $template_path));
+          $template = '<strong title="'. $hint .'">' . $template . '</strong>';
+        }
+        else {
+          $template = '<strong class="error">' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . '</strong>';
+        }
+        $picked = TRUE;
+      }
+      $fixed[] = $template;
+    }
+
+    return implode(', ', array_reverse($fixed));
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function options_validate(&$form, &$form_state) {
+    switch ($form_state['section']) {
+      case 'display_title':
+        if (empty($form_state['values']['display_title'])) {
+          form_error($form['display_title'], t('Display title may not be empty.'));
+        }
+        break;
+      case 'css_class':
+        $css_class = $form_state['values']['css_class'];
+        if (preg_match('/[^a-zA-Z0-9-_ ]/', $css_class)) {
+          form_error($form['css_class'], t('CSS classes must be alphanumeric or dashes only.'));
+        }
+      break;
+      case 'display_id':
+        if ($form_state['values']['display_id']) {
+          if (preg_match('/[^a-z0-9_]/', $form_state['values']['display_id'])) {
+            form_error($form['display_id'], t('Display name must be letters, numbers, or underscores only.'));
+          }
+
+          foreach ($this->view->display as $id => $display) {
+            if ($id != $this->view->current_display && ($form_state['values']['display_id'] == $id || (isset($display->new_id) && $form_state['values']['display_id'] == $display->new_id))) {
+              form_error($form['display_id'], t('Display id should be unique.'));
+            }
+          }
+        }
+        break;
+      case 'style_options':
+        $style = TRUE;
+      case 'row_options':
+        // if row, $style will be empty.
+        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
+        if ($plugin) {
+          $plugin->options_validate($form[$form_state['section']], $form_state);
+        }
+        break;
+      case 'access_options':
+        $plugin = $this->get_plugin('access');
+        if ($plugin) {
+          $plugin->options_validate($form['access_options'], $form_state);
+        }
+        break;
+      case 'query':
+        if ($this->view->query) {
+          $this->view->query->options_validate($form['query'], $form_state);
+        }
+        break;
+      case 'cache_options':
+        $plugin = $this->get_plugin('cache');
+        if ($plugin) {
+          $plugin->options_validate($form['cache_options'], $form_state);
+        }
+        break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        if ($plugin) {
+          $plugin->options_validate($form['exposed_form_options'], $form_state);
+        }
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        if ($plugin) {
+          $plugin->options_validate($form['pager_options'], $form_state);
+        }
+        break;
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->options_validate($form, $form_state);
+    }
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) {
+    // Not sure I like this being here, but it seems (?) like a logical place.
+    $cache_plugin = $this->get_plugin('cache');
+    if ($cache_plugin) {
+      $cache_plugin->cache_flush();
+    }
+
+    $section = $form_state['section'];
+    switch ($section) {
+      case 'display_id':
+        if (isset($form_state['values']['display_id'])) {
+          $this->display->new_id = $form_state['values']['display_id'];
+        }
+        break;
+      case 'display_title':
+        $this->display->display_title = $form_state['values']['display_title'];
+        $this->set_option('display_description', $form_state['values']['display_description']);
+        break;
+      case 'access':
+        $access = $this->get_option('access');
+        if ($access['type'] != $form_state['values']['access']['type']) {
+          $plugin = views_get_plugin('access', $form_state['values']['access']['type']);
+          if ($plugin) {
+            $access = array('type' => $form_state['values']['access']['type']);
+            $this->set_option('access', $access);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options'));
+            }
+          }
+        }
+
+        break;
+      case 'access_options':
+        $plugin = views_get_plugin('access', $form_state['values'][$section]['type']);
+        if ($plugin) {
+          $plugin->options_submit($form['access_options'], $form_state);
+          $this->set_option('access', $form_state['values'][$section]);
+        }
+        break;
+      case 'cache':
+        $cache = $this->get_option('cache');
+        if ($cache['type'] != $form_state['values']['cache']['type']) {
+          $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']);
+          if ($plugin) {
+            $cache = array('type' => $form_state['values']['cache']['type']);
+            $this->set_option('cache', $cache);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options'));
+            }
+          }
+        }
+
+        break;
+      case 'cache_options':
+        $plugin = views_get_plugin('cache', $form_state['values'][$section]['type']);
+        if ($plugin) {
+          $plugin->options_submit($form['cache_options'], $form_state);
+          $this->set_option('cache', $form_state['values'][$section]);
+        }
+        break;
+      case 'query':
+        $plugin = $this->get_plugin('query');
+        if ($plugin) {
+          $plugin->options_submit($form['query']['options'], $form_state);
+          $this->set_option('query', $form_state['values'][$section]);
+        }
+        break;
+
+      case 'link_display':
+        $this->set_option('link_url', $form_state['values']['link_url']);
+      case 'title':
+      case 'css_class':
+      case 'display_comment':
+        $this->set_option($section, $form_state['values'][$section]);
+        break;
+      case 'field_language':
+        $this->set_option('field_language', $form_state['values']['field_language']);
+        $this->set_option('field_language_add_to_query', $form_state['values']['field_language_add_to_query']);
+        break;
+      case 'use_ajax':
+      case 'hide_attachment_summary':
+        $this->set_option($section, (bool)$form_state['values'][$section]);
+        break;
+      case 'use_more':
+        $this->set_option($section, intval($form_state['values'][$section]));
+        $this->set_option('use_more_always', !intval($form_state['values']['use_more_always']));
+        $this->set_option('use_more_text', $form_state['values']['use_more_text']);
+      case 'distinct':
+        $this->set_option($section, $form_state['values'][$section]);
+        break;
+      case 'group_by':
+        $this->set_option($section, $form_state['values'][$section]);
+        break;
+      case 'row_plugin':
+        // This if prevents resetting options to default if they don't change
+        // the plugin.
+        if ($this->get_option($section) != $form_state['values'][$section]) {
+          $plugin = views_get_plugin('row', $form_state['values'][$section]);
+          if ($plugin) {
+            $this->set_option($section, $form_state['values'][$section]);
+            $this->set_option('row_options', array());
+
+            // send ajax form to options page if we use it.
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options'));
+            }
+          }
+        }
+        break;
+      case 'style_plugin':
+        // This if prevents resetting options to default if they don't change
+        // the plugin.
+        if ($this->get_option($section) != $form_state['values'][$section]) {
+          $plugin = views_get_plugin('style', $form_state['values'][$section]);
+          if ($plugin) {
+            $this->set_option($section, $form_state['values'][$section]);
+            $this->set_option('style_options', array());
+            // send ajax form to options page if we use it.
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options'));
+            }
+          }
+        }
+        break;
+      case 'style_options':
+        $style = TRUE;
+      case 'row_options':
+        // if row, $style will be empty.
+        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
+        if ($plugin) {
+          $plugin->options_submit($form['options'][$section], $form_state);
+        }
+        $this->set_option($section, $form_state['values'][$section]);
+        break;
+      case 'exposed_block':
+        $this->set_option($section, (bool) $form_state['values'][$section]);
+        break;
+      case 'exposed_form':
+        $exposed_form = $this->get_option('exposed_form');
+        if ($exposed_form['type'] != $form_state['values']['exposed_form']['type']) {
+          $plugin = views_get_plugin('exposed_form', $form_state['values']['exposed_form']['type']);
+          if ($plugin) {
+            $exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array());
+            $this->set_option('exposed_form', $exposed_form);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('exposed_form_options'));
+            }
+          }
+        }
+
+        break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        if ($plugin) {
+          $exposed_form = $this->get_option('exposed_form');
+          $plugin->options_submit($form['exposed_form_options'], $form_state);
+          $exposed_form['options'] = $form_state['values'][$section];
+          $this->set_option('exposed_form', $exposed_form);
+        }
+        break;
+      case 'pager':
+        $pager = $this->get_option('pager');
+        if ($pager['type'] != $form_state['values']['pager']['type']) {
+          $plugin = views_get_plugin('pager', $form_state['values']['pager']['type']);
+          if ($plugin) {
+            // Because pagers have very similar options, let's allow pagers to
+            // try to carry the options over.
+            $plugin->init($this->view, $this->display, $pager['options']);
+
+            $pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options);
+            $this->set_option('pager', $pager);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('pager_options'));
+            }
+          }
+        }
+
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        if ($plugin) {
+          $pager = $this->get_option('pager');
+          $plugin->options_submit($form['pager_options'], $form_state);
+          $pager['options'] = $form_state['values'][$section];
+          $this->set_option('pager', $pager);
+        }
+        break;
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->options_submit($form, $form_state);
+    }
+  }
+
+  /**
+   * If override/revert was clicked, perform the proper toggle.
+   */
+  function options_override($form, &$form_state) {
+    $this->set_override($form_state['section']);
+  }
+
+  /**
+   * Flip the override setting for the given section.
+   *
+   * @param string $section
+   *   Which option should be marked as overridden, for example "filters".
+   * @param bool $new_state
+   *   Select the new state of the option.
+   *     - TRUE: Revert to default.
+   *     - FALSE: Mark it as overridden.
+   */
+  function set_override($section, $new_state = NULL) {
+    $options = $this->defaultable_sections($section);
+    if (!$options) {
+      return;
+    }
+
+    if (!isset($new_state)) {
+      $new_state = empty($this->options['defaults'][$section]);
+    }
+
+    // For each option that is part of this group, fix our settings.
+    foreach ($options as $option) {
+      if ($new_state) {
+        // Revert to defaults.
+        unset($this->options[$option]);
+        unset($this->display->display_options[$option]);
+      }
+      else {
+        // copy existing values into our display.
+        $this->options[$option] = $this->get_option($option);
+        $this->display->display_options[$option] = $this->options[$option];
+      }
+      $this->options['defaults'][$option] = $new_state;
+      $this->display->display_options['defaults'][$option] = $new_state;
+    }
+  }
+
+  /**
+   * Inject anything into the query that the display handler needs.
+   */
+  function query() {
+    foreach ($this->extender as $extender) {
+      $extender->query();
+    }
+  }
+
+  /**
+   * Not all display plugins will support filtering
+   */
+  function render_filters() { }
+
+  /**
+   * Not all display plugins will suppert pager rendering.
+   */
+  function render_pager() {
+    return TRUE;
+  }
+
+  /**
+   * Render the 'more' link
+   */
+  function render_more_link() {
+    if ($this->use_more() && ($this->use_more_always() || (!empty($this->view->query->pager) && $this->view->query->pager->has_more_records()))) {
+      $path = $this->get_path();
+
+      if ($this->get_option('link_display') == 'custom_url' && $override_path = $this->get_option('link_url')) {
+        $tokens = $this->get_arguments_tokens();
+        $path = strtr($override_path, $tokens);
+      }
+
+      if ($path) {
+        if (empty($override_path)) {
+          $path = $this->view->get_url(NULL, $path);
+        }
+        $url_options = array();
+        if (!empty($this->view->exposed_raw_input)) {
+          $url_options['query'] = $this->view->exposed_raw_input;
+        }
+        $theme = views_theme_functions('views_more', $this->view, $this->display);
+        $path = check_url(url($path, $url_options));
+
+        return theme($theme, array('more_url' => $path, 'link_text' => check_plain($this->use_more_text()), 'view' => $this->view));
+      }
+    }
+  }
+
+
+  /**
+   * Legacy functions.
+   */
+
+  /**
+   * Render the header of the view.
+   */
+  function render_header() {
+    $empty = !empty($this->view->result);
+    return $this->render_area('header', $empty);
+  }
+
+  /**
+   * Render the footer of the view.
+   */
+  function render_footer() {
+    $empty = !empty($this->view->result);
+    return $this->render_area('footer', $empty);
+  }
+
+  function render_empty() {
+    return $this->render_area('empty');
+  }
+
+  /**
+   * If this display creates a block, implement one of these.
+   */
+  function hook_block_list($delta = 0, $edit = array()) { return array(); }
+
+  /**
+   * If this display creates a page with a menu item, implement it here.
+   */
+  function hook_menu() { return array(); }
+
+  /**
+   * Render this display.
+   */
+  function render() {
+    return theme($this->theme_functions(), array('view' => $this->view));
+  }
+
+  function render_area($area, $empty = FALSE) {
+    $return = '';
+    foreach ($this->get_handlers($area) as $area) {
+      $return .= $area->render($empty);
+    }
+    return $return;
+  }
+
+
+  /**
+   * Determine if the user has access to this display of the view.
+   */
+  function access($account = NULL) {
+    if (!isset($account)) {
+      global $user;
+      $account = $user;
+    }
+
+    // Full override.
+    if (user_access('access all views', $account)) {
+      return TRUE;
+    }
+
+    $plugin = $this->get_plugin('access');
+    if ($plugin) {
+      return $plugin->access($account);
+    }
+
+    // fallback to all access if no plugin.
+    return TRUE;
+  }
+
+  /**
+   * Set up any variables on the view prior to execution. These are separated
+   * from execute because they are extremely common and unlikely to be
+   * overridden on an individual display.
+   */
+  function pre_execute() {
+    $this->view->set_use_ajax($this->use_ajax());
+    if ($this->use_more() && !$this->use_more_always()) {
+      $this->view->get_total_rows = TRUE;
+    }
+    $this->view->init_handlers();
+    if ($this->uses_exposed()) {
+      $exposed_form = $this->get_plugin('exposed_form');
+      $exposed_form->pre_execute();
+    }
+
+    foreach ($this->extender as $extender) {
+      $extender->pre_execute();
+    }
+  }
+
+  /**
+   * When used externally, this is how a view gets run and returns
+   * data in the format required.
+   *
+   * The base class cannot be executed.
+   */
+  function execute() { }
+
+  /**
+   * Fully render the display for the purposes of a live preview or
+   * some other AJAXy reason.
+   */
+  function preview() { return $this->view->render(); }
+
+  /**
+   * Displays can require a certain type of style plugin. By default, they will
+   * be 'normal'.
+   */
+  function get_style_type() { return 'normal'; }
+
+  /**
+   * Make sure the display and all associated handlers are valid.
+   *
+   * @return
+   *   Empty array if the display is valid; an array of error strings if it is not.
+   */
+  function validate() {
+    $errors = array();
+    // Make sure displays that use fields HAVE fields.
+    if ($this->uses_fields()) {
+      $fields = FALSE;
+      foreach ($this->get_handlers('field') as $field) {
+        if (empty($field->options['exclude'])) {
+          $fields = TRUE;
+        }
+      }
+
+      if (!$fields) {
+        $errors[] = t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display->display_title));
+      }
+    }
+
+    if ($this->has_path() && !$this->get_option('path')) {
+      $errors[] = t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display->display_title));
+    }
+
+    // Validate style plugin
+    $style = $this->get_plugin();
+    if (empty($style)) {
+      $errors[] = t('Display "@display" has an invalid style plugin.', array('@display' => $this->display->display_title));
+    }
+    else {
+      $result = $style->validate();
+      if (!empty($result) && is_array($result)) {
+        $errors = array_merge($errors, $result);
+      }
+    }
+
+    // Validate query plugin.
+    $query = $this->get_plugin('query');
+    $result = $query->validate();
+    if (!empty($result) && is_array($result)) {
+      $errors = array_merge($errors, $result);
+    }
+
+    // Validate handlers
+    foreach (View::views_object_types() as $type => $info) {
+      foreach ($this->get_handlers($type) as $handler) {
+        $result = $handler->validate();
+        if (!empty($result) && is_array($result)) {
+          $errors = array_merge($errors, $result);
+        }
+      }
+    }
+
+    return $errors;
+  }
+
+  /**
+   * Check if the provided identifier is unique.
+   *
+   * @param string $id
+   *   The id of the handler which is checked.
+   * @param string $identifier
+   *   The actual get identifier configured in the exposed settings.
+   *
+   * @return bool
+   *   Returns whether the identifier is unique on all handlers.
+   *
+   */
+  function is_identifier_unique($id, $identifier) {
+    foreach (View::views_object_types() as $type => $info) {
+      foreach ($this->get_handlers($type) as $key => $handler) {
+        if ($handler->can_expose() && $handler->is_exposed()) {
+          if ($id != $key && $identifier == $handler->options['expose']['identifier']) {
+            return FALSE;
+          }
+        }
+      }
+    }
+    return TRUE;
+  }
+
+  /**
+   * Provide the block system with any exposed widget blocks for this display.
+   */
+  function get_special_blocks() {
+    $blocks = array();
+
+    if ($this->uses_exposed_form_in_block()) {
+      $delta = '-exp-' . $this->view->name . '-' . $this->display->id;
+      $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id));
+
+      $blocks[$delta] = array(
+        'info' => $desc,
+        'cache' => DRUPAL_NO_CACHE,
+      );
+    }
+
+    return $blocks;
+  }
+
+  /**
+   * Render any special blocks provided for this display.
+   */
+  function view_special_blocks($type) {
+    if ($type == '-exp') {
+      // avoid interfering with the admin forms.
+      if (arg(0) == 'admin' && arg(1) == 'structure' && arg(2) == 'views') {
+        return;
+      }
+      $this->view->init_handlers();
+
+      if ($this->uses_exposed() && $this->get_option('exposed_block')) {
+        $exposed_form = $this->get_plugin('exposed_form');
+        return array(
+          'content' => $exposed_form->render_exposed_form(TRUE),
+        );
+      }
+    }
+  }
+
+  /**
+   * Override of export_option()
+   *
+   * Because displays do not want to export options that are NOT overridden from the
+   * default display, we need some special handling during the export process.
+   */
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // The $prefix is wrong because we store our actual options a little differently:
+    $prefix = '$handler->display->display_options';
+    $output = '';
+    if (!$parents && !$this->is_default_display()) {
+      // Do not export items that are not overridden.
+      if ($this->is_defaulted($option)) {
+        return;
+      }
+
+      // If this is not defaulted and is overrideable, flip the switch to say this
+      // is overridden.
+      if ($this->defaultable_sections($option)) {
+        $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n";
+      }
+    }
+
+    $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
+    return $output;
+  }
+
+  /**
+   * Special method to export items that have handlers.
+   *
+   * This method was specified in the option_definition() as the method to utilize to
+   * export fields, filters, sort criteria, relationships and arguments. This passes
+   * the export off to the individual handlers so that they can export themselves
+   * properly.
+   */
+  function export_handler($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+
+    // cut the 's' off because the data is stored as the plural form but we need
+    // the singular form. Who designed that anyway? Oh yeah, I did. :(
+    if ($option != 'header' && $option != 'footer' && $option != 'empty') {
+      $type = substr($option, 0, -1);
+    }
+    else {
+      $type = $option;
+    }
+    $types = View::views_object_types();
+    foreach ($storage[$option] as $id => $info) {
+      if (!empty($types[$type]['type'])) {
+        $handler_type = $types[$type]['type'];
+      }
+      else {
+        $handler_type = $type;
+      }
+      // If aggregation is on, the group type might override the actual
+      // handler that is in use. This piece of code checks that and,
+      // if necessary, sets the override handler.
+      $override = NULL;
+      if ($this->use_group_by() && !empty($info['group_type'])) {
+        if (empty($this->view->query)) {
+          $this->view->init_query();
+        }
+        $aggregate = $this->view->query->get_aggregation_info();
+        if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
+          $override = $aggregate[$info['group_type']]['handler'][$type];
+        }
+      }
+      $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
+      if ($handler) {
+        $handler->init($this->view, $info);
+        $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n";
+        $output .= $handler->export_options($indent, $prefix . "['$option']['$id']");
+      }
+
+      // Prevent reference problems.
+      unset($handler);
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Styles are stored as style_plugin and style_options or row_plugin and
+   * row_options accordingly. The options are told not to export, and the
+   * export for the plugin should export both.
+   */
+  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $style_plugin = $this->get_plugin();
+    if ($option == 'style_plugin') {
+      $type = 'style';
+      $options_field = 'style_options';
+      $plugin = $style_plugin;
+    }
+    else {
+      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
+        return;
+      }
+
+      $type = 'row';
+      $options_field = 'row_options';
+      $plugin = $this->get_plugin('row');
+      // If the style plugin doesn't use row plugins, don't even bother.
+    }
+
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $this->get_option($option);
+      $output .= $indent . $prefix . "['$option'] = '$value';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['$options_field']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for plugin export
+   *
+   * Plugins other than styles are stored in array with 'type' being the key
+   * to the plugin. For modern plugins, the options are stored in the 'options'
+   * array, but for legacy plugins (access and cache) options are stored as
+   * siblings to the type.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $plugin_type = end($parents);
+    $plugin = $this->get_plugin($plugin_type);
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $storage[$option];
+      $new_prefix = $prefix . "['$plugin_type']";
+
+      $output .= $indent . $new_prefix . "['$option'] = '$value';\n";
+
+      if ($plugin_type != 'access' && $plugin_type!= 'cache') {
+        $new_prefix .= "['options']";
+      }
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $new_prefix);
+    }
+
+    return $output;
+  }
+
+  function unpack_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $style_plugin = $this->get_plugin();
+    if ($option == 'style_plugin') {
+      $type = 'style';
+      $options_field = 'style_options';
+      $plugin = $style_plugin;
+    }
+    else {
+      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
+        return;
+      }
+
+      $type = 'row';
+      $options_field = 'row_options';
+      $plugin = $this->get_plugin('row');
+      // If the style plugin doesn't use row plugins, don't even bother.
+    }
+
+    if ($plugin) {
+      return $plugin->unpack_translatables($translatable, $parents);
+    }
+  }
+
+  /**
+   * Special handling for plugin unpacking.
+   */
+  function unpack_plugin(&$translatable, $storage, $option, $definition, $parents) {
+    $plugin_type = end($parents);
+    $plugin = $this->get_plugin($plugin_type);
+    if ($plugin) {
+      // Write which plugin to use.
+      return $plugin->unpack_translatables($translatable, $parents);
+    }
+  }
+
+    /**
+   * Special method to unpack items that have handlers.
+   *
+   * This method was specified in the option_definition() as the method to utilize to
+   * export fields, filters, sort criteria, relationships and arguments. This passes
+   * the export off to the individual handlers so that they can export themselves
+   * properly.
+   */
+  function unpack_handler(&$translatable, $storage, $option, $definition, $parents) {
+    $output = '';
+
+    // cut the 's' off because the data is stored as the plural form but we need
+    // the singular form. Who designed that anyway? Oh yeah, I did. :(
+    if ($option != 'header' && $option != 'footer' && $option != 'empty') {
+      $type = substr($option, 0, -1);
+    }
+    else {
+      $type = $option;
+    }
+    $types = View::views_object_types();
+    foreach ($storage[$option] as $id => $info) {
+      if (!empty($types[$type]['type'])) {
+        $handler_type = $types[$type]['type'];
+      }
+      else {
+        $handler_type = $type;
+      }
+      $handler = views_get_handler($info['table'], $info['field'], $handler_type);
+      if ($handler) {
+        $handler->init($this->view, $info);
+        $handler->unpack_translatables($translatable, array_merge($parents, array($type, $info['table'], $info['id'])));
+      }
+
+      // Prevent reference problems.
+      unset($handler);
+    }
+
+    return $output;
+  }
+
+  /**
+   * Provide some helpful text for the arguments.
+   * The result should contain of an array with
+   *   - filter value present: The title of the fieldset in the argument
+   *     where you can configure what should be done with a given argument.
+   *   - filter value not present: The tiel of the fieldset in the argument
+   *     where you can configure what should be done if the argument does not
+   *     exist.
+   *   - description: A description about how arguments comes to the display.
+   *     For example blocks don't get it from url.
+   */
+  function get_argument_text() {
+    return array(
+      'filter value not present' => t('When the filter value is <em>NOT</em> available'),
+      'filter value present' => t('When the filter value <em>IS</em> available or a default is provided'),
+      'description' => t("This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default'."),
+    );
+  }
+
+  /**
+   * Provide some helpful text for pagers.
+   *
+   * The result should contain of an array within
+   *   - items per page title
+   */
+  function get_pager_text() {
+    return array(
+      'items per page title' => t('Items to display'),
+      'items per page description' => t('The number of items to display. Enter 0 for no limit.')
+    );
+  }
+}
+
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/display/FeedDisplay.php b/lib/Drupal/views/Plugins/views/display/FeedDisplay.php
new file mode 100644
index 0000000..34447a7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/FeedDisplay.php
@@ -0,0 +1,234 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\FeedDisplay.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * The plugin that handles a feed, such as RSS or atom.
+ *
+ * For the most part, feeds are page displays but with some subtle differences.
+ *
+ * @ingroup views_display_plugins
+ */
+class FeedDisplay extends DisplayPlugin {
+  function init(&$view, &$display, $options = NULL) {
+    parent::init($view, $display, $options);
+
+    // Set the default row style. Ideally this would be part of the option
+    // definition, but in this case it's dependent on the view's base table,
+    // which we don't know until init().
+    $row_plugins = views_fetch_plugin_names('row', $this->get_style_type(), array($view->base_table));
+    $default_row_plugin = key($row_plugins);
+    if ($this->options['row_plugin'] == '') {
+      $this->options['row_plugin'] = $default_row_plugin;
+    }
+  }
+
+  function uses_breadcrumb() { return FALSE; }
+  function get_style_type() { return 'feed'; }
+
+  /**
+   * Feeds do not go through the normal page theming mechanism. Instead, they
+   * go through their own little theme function and then return NULL so that
+   * Drupal believes that the page has already rendered itself...which it has.
+   */
+  function execute() {
+    $output = $this->view->render();
+    if (empty($output)) {
+      return drupal_not_found();
+    }
+
+    $response = $this->view->getResponse();
+    $response->setContent($output);
+    return $response;
+  }
+
+  function preview() {
+    if (!empty($this->view->live_preview)) {
+      return '<pre>' . check_plain($this->view->render()) . '</pre>';
+    }
+    return $this->view->render();
+  }
+
+  /**
+   * Instead of going through the standard views_view.tpl.php, delegate this
+   * to the style handler.
+   */
+  function render() {
+    return $this->view->style_plugin->render($this->view->result);
+  }
+
+  function defaultable_sections($section = NULL) {
+    if (in_array($section, array('style_options', 'style_plugin', 'row_options', 'row_plugin',))) {
+      return FALSE;
+    }
+
+    $sections = parent::defaultable_sections($section);
+
+    // Tell views our sitename_title option belongs in the title section.
+    if ($section == 'title') {
+      $sections[] = 'sitename_title';
+    }
+    elseif (!$section) {
+      $sections['title'][] = 'sitename_title';
+    }
+    return $sections;
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['displays'] = array('default' => array());
+
+    // Overrides for standard stuff:
+    $options['style_plugin']['default'] = 'rss';
+    $options['style_options']['default']  = array('description' => '');
+    $options['sitename_title']['default'] = FALSE;
+    $options['row_plugin']['default'] = '';
+    $options['defaults']['default']['style_plugin'] = FALSE;
+    $options['defaults']['default']['style_options'] = FALSE;
+    $options['defaults']['default']['row_plugin'] = FALSE;
+    $options['defaults']['default']['row_options'] = FALSE;
+
+    return $options;
+  }
+
+  function options_summary(&$categories, &$options) {
+    // It is very important to call the parent function here:
+    parent::options_summary($categories, $options);
+
+    // Since we're childing off the 'page' type, we'll still *call* our
+    // category 'page' but let's override it so it says feed settings.
+    $categories['page'] = array(
+      'title' => t('Feed settings'),
+      'column' => 'second',
+      'build' => array(
+        '#weight' => -10,
+      ),
+    );
+
+    if ($this->get_option('sitename_title')) {
+      $options['title']['value'] = t('Using the site name');
+    }
+
+    // I don't think we want to give feeds menus directly.
+    unset($options['menu']);
+
+    $displays = array_filter($this->get_option('displays'));
+    if (count($displays) > 1) {
+      $attach_to = t('Multiple displays');
+    }
+    elseif (count($displays) == 1) {
+      $display = array_shift($displays);
+      if (!empty($this->view->display[$display])) {
+        $attach_to = check_plain($this->view->display[$display]->display_title);
+      }
+    }
+
+    if (!isset($attach_to)) {
+      $attach_to = t('None');
+    }
+
+    $options['displays'] = array(
+      'category' => 'page',
+      'title' => t('Attach to'),
+      'value' => $attach_to,
+    );
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    // It is very important to call the parent function here.
+    parent::options_form($form, $form_state);
+
+    switch ($form_state['section']) {
+      case 'title':
+        $title = $form['title'];
+        // A little juggling to move the 'title' field beyond our checkbox.
+        unset($form['title']);
+        $form['sitename_title'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Use the site name for the title'),
+          '#default_value' => $this->get_option('sitename_title'),
+        );
+        $form['title'] = $title;
+        $form['title']['#states'] = array(
+          'visible' => array(
+            ':input[name="sitename_title"]' => array('checked' => FALSE),
+          ),
+        );
+        break;
+      case 'displays':
+        $form['#title'] .= t('Attach to');
+        $displays = array();
+        foreach ($this->view->display as $display_id => $display) {
+          if (!empty($display->handler) && $display->handler->accept_attachments()) {
+            $displays[$display_id] = $display->display_title;
+          }
+        }
+        $form['displays'] = array(
+          '#type' => 'checkboxes',
+          '#description' => t('The feed icon will be available only to the selected displays.'),
+          '#options' => $displays,
+          '#default_value' => $this->get_option('displays'),
+        );
+        break;
+      case 'path':
+        $form['path']['#description'] = t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss.xml", putting one % in the path for each contextual filter you have defined in the view.');
+    }
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_submit($form, $form_state);
+    switch ($form_state['section']) {
+      case 'title':
+        $this->set_option('sitename_title', $form_state['values']['sitename_title']);
+        break;
+      case 'displays':
+        $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
+        break;
+    }
+  }
+
+  /**
+   * Attach to another view.
+   */
+  function attach_to($display_id) {
+    $displays = $this->get_option('displays');
+    if (empty($displays[$display_id])) {
+      return;
+    }
+
+    // Defer to the feed style; it may put in meta information, and/or
+    // attach a feed icon.
+    $plugin = $this->get_plugin();
+    if ($plugin) {
+      $clone = $this->view->clone_view();
+      $clone->set_display($this->display->id);
+      $clone->build_title();
+      $plugin->attach_to($display_id, $this->get_path(), $clone->get_title());
+
+      // Clean up
+      $clone->destroy();
+      unset($clone);
+    }
+  }
+
+  function uses_link_display() {
+    return TRUE;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display/PageDisplay.php b/lib/Drupal/views/Plugins/views/display/PageDisplay.php
new file mode 100644
index 0000000..b3787d6
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display/PageDisplay.php
@@ -0,0 +1,634 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display\PageDisplay.
+ */
+
+namespace Drupal\views\Plugins\views\display;
+
+/**
+ * The plugin that handles a full page.
+ *
+ * @ingroup views_display_plugins
+ */
+class PageDisplay extends DisplayPlugin {
+  /**
+   * The page display has a path.
+   */
+  function has_path() { return TRUE; }
+  function uses_breadcrumb() { return TRUE; }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['path'] = array('default' => '');
+    $options['menu'] = array(
+      'contains' => array(
+        'type' => array('default' => 'none'),
+        // Do not translate menu and title as menu system will.
+        'title' => array('default' => '', 'translatable' => FALSE),
+        'description' => array('default' => '', 'translatable' => FALSE),
+        'weight' => array('default' => 0),
+        'name' => array('default' => variable_get('menu_default_node_menu', 'navigation')),
+        'context' => array('default' => ''),
+       ),
+    );
+    $options['tab_options'] = array(
+      'contains' => array(
+        'type' => array('default' => 'none'),
+        // Do not translate menu and title as menu system will.
+        'title' => array('default' => '', 'translatable' => FALSE),
+        'description' => array('default' => '', 'translatable' => FALSE),
+        'weight' => array('default' => 0),
+        'name' => array('default' => 'navigation'),
+       ),
+    );
+
+    return $options;
+  }
+
+  /**
+   * Add this display's path information to Drupal's menu system.
+   */
+  function execute_hook_menu($callbacks) {
+    $items = array();
+    // Replace % with the link to our standard views argument loader
+    // views_arg_load -- which lives in views.module
+
+    $bits = explode('/', $this->get_option('path'));
+    $page_arguments = array($this->view->name, $this->display->id);
+    $this->view->init_handlers();
+    $view_arguments = $this->view->argument;
+
+    // Replace % with %views_arg for menu autoloading and add to the
+    // page arguments so the argument actually comes through.
+    foreach ($bits as $pos => $bit) {
+      if ($bit == '%') {
+        $argument = array_shift($view_arguments);
+        if (!empty($argument->options['specify_validation']) && $argument->options['validate']['type'] != 'none') {
+          $bits[$pos] = '%views_arg';
+        }
+        $page_arguments[] = $pos;
+      }
+    }
+
+    $path = implode('/', $bits);
+
+    $access_plugin = $this->get_plugin('access');
+    if (!isset($access_plugin)) {
+      $access_plugin = views_get_plugin('access', 'none');
+    }
+
+    // Get access callback might return an array of the callback + the dynamic arguments.
+    $access_plugin_callback = $access_plugin->get_access_callback();
+
+    if (is_array($access_plugin_callback)) {
+      $access_arguments = array();
+
+      // Find the plugin arguments.
+      $access_plugin_method = array_shift($access_plugin_callback);
+      $access_plugin_arguments = array_shift($access_plugin_callback);
+      if (!is_array($access_plugin_arguments)) {
+        $access_plugin_arguments = array();
+      }
+
+      $access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments);
+
+      // Move the plugin arguments to the access arguments array.
+      $i = 1;
+      foreach ($access_plugin_arguments as $key => $value) {
+        if (is_int($value)) {
+          $access_arguments[$i] = $value;
+          $access_plugin_arguments[$key] = $i;
+          $i++;
+        }
+      }
+    }
+    else {
+      $access_arguments = array($access_plugin_callback);
+    }
+
+    if ($path) {
+      $items[$path] = array(
+        // default views page entry
+        'page callback' => 'views_page',
+        'page arguments' => $page_arguments,
+        // Default access check (per display)
+        'access callback' => 'views_access',
+        'access arguments' => $access_arguments,
+        // Identify URL embedded arguments and correlate them to a handler
+        'load arguments'  => array($this->view->name, $this->display->id, '%index'),
+      );
+      $menu = $this->get_option('menu');
+      if (empty($menu)) {
+        $menu = array('type' => 'none');
+      }
+      // Set the title and description if we have one.
+      if ($menu['type'] != 'none') {
+        $items[$path]['title'] = $menu['title'];
+        $items[$path]['description'] = $menu['description'];
+      }
+
+      if (isset($menu['weight'])) {
+        $items[$path]['weight'] = intval($menu['weight']);
+      }
+
+      switch ($menu['type']) {
+        case 'none':
+        default:
+          $items[$path]['type'] = MENU_CALLBACK;
+          break;
+        case 'normal':
+          $items[$path]['type'] = MENU_NORMAL_ITEM;
+          // Insert item into the proper menu
+          $items[$path]['menu_name'] = $menu['name'];
+          break;
+        case 'tab':
+          $items[$path]['type'] = MENU_LOCAL_TASK;
+          break;
+        case 'default tab':
+          $items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK;
+          break;
+      }
+
+      // Add context for contextual links.
+      // @see menu_contextual_links()
+      if (!empty($menu['context'])) {
+        $items[$path]['context'] = MENU_CONTEXT_INLINE;
+      }
+
+      // If this is a 'default' tab, check to see if we have to create teh
+      // parent menu item.
+      if ($menu['type'] == 'default tab') {
+        $tab_options = $this->get_option('tab_options');
+        if (!empty($tab_options['type']) && $tab_options['type'] != 'none') {
+          $bits = explode('/', $path);
+          // Remove the last piece.
+          $bit = array_pop($bits);
+
+          // we can't do this if they tried to make the last path bit variable.
+          // @todo: We can validate this.
+          if ($bit != '%views_arg' && !empty($bits)) {
+            $default_path = implode('/', $bits);
+            $items[$default_path] = array(
+              // default views page entry
+              'page callback' => 'views_page',
+              'page arguments' => $page_arguments,
+              // Default access check (per display)
+              'access callback' => 'views_access',
+              'access arguments' => $access_arguments,
+              // Identify URL embedded arguments and correlate them to a handler
+              'load arguments'  => array($this->view->name, $this->display->id, '%index'),
+              'title' => $tab_options['title'],
+              'description' => $tab_options['description'],
+              'menu_name' => $tab_options['name'],
+            );
+            switch ($tab_options['type']) {
+              default:
+              case 'normal':
+                $items[$default_path]['type'] = MENU_NORMAL_ITEM;
+                break;
+              case 'tab':
+                $items[$default_path]['type'] = MENU_LOCAL_TASK;
+                break;
+            }
+            if (isset($tab_options['weight'])) {
+              $items[$default_path]['weight'] = intval($tab_options['weight']);
+            }
+          }
+        }
+      }
+    }
+
+    return $items;
+  }
+
+  /**
+   * The display page handler returns a normal view, but it also does
+   * a drupal_set_title for the page, and does a views_set_page_view
+   * on the view.
+   */
+  function execute() {
+    // Let the world know that this is the page view we're using.
+    views_set_page_view($this->view);
+
+    // Prior to this being called, the $view should already be set to this
+    // display, and arguments should be set on the view.
+    $this->view->build();
+    if (!empty($this->view->build_info['fail'])) {
+      return drupal_not_found();
+    }
+
+    if (!empty($this->view->build_info['denied'])) {
+      return drupal_access_denied();
+    }
+
+    $this->view->get_breadcrumb(TRUE);
+
+
+    // And now render the view.
+    $render = $this->view->render();
+
+    // First execute the view so it's possible to get tokens for the title.
+    // And the title, which is much easier.
+    drupal_set_title(filter_xss_admin($this->view->get_title()), PASS_THROUGH);
+    return $render;
+  }
+
+  /**
+   * Provide the summary for page options in the views UI.
+   *
+   * This output is returned as an array.
+   */
+  function options_summary(&$categories, &$options) {
+    // It is very important to call the parent function here:
+    parent::options_summary($categories, $options);
+
+    $categories['page'] = array(
+      'title' => t('Page settings'),
+      'column' => 'second',
+      'build' => array(
+        '#weight' => -10,
+      ),
+    );
+
+    $path = strip_tags('/' . $this->get_option('path'));
+    if (empty($path)) {
+      $path = t('None');
+    }
+
+    $options['path'] = array(
+      'category' => 'page',
+      'title' => t('Path'),
+      'value' => views_ui_truncate($path, 24),
+    );
+
+    $menu = $this->get_option('menu');
+    if (!is_array($menu)) {
+      $menu = array('type' => 'none');
+    }
+    switch($menu['type']) {
+      case 'none':
+      default:
+        $menu_str = t('No menu');
+        break;
+      case 'normal':
+        $menu_str = t('Normal: @title', array('@title' => $menu['title']));
+        break;
+      case 'tab':
+      case 'default tab':
+        $menu_str = t('Tab: @title', array('@title' => $menu['title']));
+        break;
+    }
+
+    $options['menu'] = array(
+      'category' => 'page',
+      'title' => t('Menu'),
+      'value' => views_ui_truncate($menu_str, 24),
+    );
+
+    // This adds a 'Settings' link to the style_options setting if the style has options.
+    if ($menu['type'] == 'default tab') {
+      $options['menu']['setting'] = t('Parent menu item');
+      $options['menu']['links']['tab_options'] = t('Change settings for the parent menu');
+    }
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    // It is very important to call the parent function here:
+    parent::options_form($form, $form_state);
+
+    switch ($form_state['section']) {
+      case 'path':
+        $form['#title'] .= t('The menu path or URL of this view');
+        $form['#help_topic'] = 'path';
+        $form['path'] = array(
+          '#type' => 'textfield',
+          '#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
+          '#default_value' => $this->get_option('path'),
+	  '#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='),
+	  '#field_suffix' => '</span>&lrm;',
+	  '#attributes' => array('dir'=>'ltr'),
+        );
+        break;
+      case 'menu':
+        $form['#title'] .= t('Menu item entry');
+        $form['#help_topic'] = 'menu';
+        $form['menu'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+        $menu = $this->get_option('menu');
+        if (empty($menu)) {
+          $menu = array('type' => 'none', 'title' => '', 'weight' => 0);
+        }
+        $form['menu']['type'] = array(
+          '#prefix' => '<div class="views-left-30">',
+          '#suffix' => '</div>',
+          '#title' => t('Type'),
+          '#type' => 'radios',
+          '#options' => array(
+            'none' => t('No menu entry'),
+            'normal' => t('Normal menu entry'),
+            'tab' => t('Menu tab'),
+            'default tab' => t('Default menu tab')
+          ),
+          '#default_value' => $menu['type'],
+        );
+
+        $form['menu']['title'] = array(
+          '#prefix' => '<div class="views-left-50">',
+          '#title' => t('Title'),
+          '#type' => 'textfield',
+          '#default_value' => $menu['title'],
+          '#description' => t('If set to normal or tab, enter the text to use for the menu item.'),
+          '#states' => array(
+            'visible' => array(
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'normal'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'tab'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'default tab'),
+              ),
+            ),
+          ),
+        );
+        $form['menu']['description'] = array(
+          '#title' => t('Description'),
+          '#type' => 'textfield',
+          '#default_value' => $menu['description'],
+          '#description' => t("If set to normal or tab, enter the text to use for the menu item's description."),
+          '#states' => array(
+            'visible' => array(
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'normal'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'tab'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'default tab'),
+              ),
+            ),
+          ),
+        );
+
+        // Only display the menu selector if menu module is enabled.
+        if (module_exists('menu')) {
+          $form['menu']['name'] = array(
+            '#title' => t('Menu'),
+            '#type' => 'select',
+            '#options' => menu_get_menus(),
+            '#default_value' => $menu['name'],
+            '#description' => t('Insert item into an available menu.'),
+            '#states' => array(
+              'visible' => array(
+                array(
+                  ':input[name="menu[type]"]' => array('value' => 'normal'),
+                ),
+                array(
+                  ':input[name="menu[type]"]' => array('value' => 'tab'),
+                ),
+              ),
+            ),
+          );
+        }
+        else {
+          $form['menu']['name'] = array(
+            '#type' => 'value',
+            '#value' => $menu['name'],
+          );
+          $form['menu']['markup'] = array(
+            '#markup' => t('Menu selection requires the activation of menu module.'),
+          );
+        }
+        $form['menu']['weight'] = array(
+          '#title' => t('Weight'),
+          '#type' => 'textfield',
+          '#default_value' => isset($menu['weight']) ? $menu['weight'] : 0,
+          '#description' => t('The lower the weight the higher/further left it will appear.'),
+          '#states' => array(
+            'visible' => array(
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'normal'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'tab'),
+              ),
+              array(
+                ':input[name="menu[type]"]' => array('value' => 'default tab'),
+              ),
+            ),
+          ),
+        );
+        $form['menu']['context'] = array(
+          '#title' => t('Context'),
+          '#suffix' => '</div>',
+          '#type' => 'checkbox',
+          '#default_value' => !empty($menu['context']),
+          '#description' => t('Displays the link in contextual links'),
+          '#states' => array(
+            'visible' => array(
+              ':input[name="menu[type]"]' => array('value' => 'tab'),
+            ),
+          ),
+        );
+        break;
+      case 'tab_options':
+        $form['#title'] .= t('Default tab options');
+        $tab_options = $this->get_option('tab_options');
+        if (empty($tab_options)) {
+          $tab_options = array('type' => 'none', 'title' => '', 'weight' => 0);
+        }
+
+        $form['tab_markup'] = array(
+          '#markup' => '<div class="form-item description">' . t('When providing a menu item as a tab, Drupal needs to know what the parent menu item of that tab will be. Sometimes the parent will already exist, but other times you will need to have one created. The path of a parent item will always be the same path with the last part left off. i.e, if the path to this view is <em>foo/bar/baz</em>, the parent path would be <em>foo/bar</em>.') . '</div>',
+        );
+
+        $form['tab_options'] = array(
+          '#prefix' => '<div class="clearfix">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+        $form['tab_options']['type'] = array(
+          '#prefix' => '<div class="views-left-25">',
+          '#suffix' => '</div>',
+          '#title' => t('Parent menu item'),
+          '#type' => 'radios',
+          '#options' => array('none' => t('Already exists'), 'normal' => t('Normal menu item'), 'tab' => t('Menu tab')),
+          '#default_value' => $tab_options['type'],
+        );
+        $form['tab_options']['title'] = array(
+          '#prefix' => '<div class="views-left-75">',
+          '#title' => t('Title'),
+          '#type' => 'textfield',
+          '#default_value' => $tab_options['title'],
+          '#description' => t('If creating a parent menu item, enter the title of the item.'),
+          '#states' => array(
+            'visible' => array(
+              array(
+                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
+              ),
+              array(
+                ':input[name="tab_options[type]"]' => array('value' => 'tab'),
+              ),
+            ),
+          ),
+        );
+        $form['tab_options']['description'] = array(
+          '#title' => t('Description'),
+          '#type' => 'textfield',
+          '#default_value' => $tab_options['description'],
+          '#description' => t('If creating a parent menu item, enter the description of the item.'),
+          '#states' => array(
+            'visible' => array(
+              array(
+                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
+              ),
+              array(
+                ':input[name="tab_options[type]"]' => array('value' => 'tab'),
+              ),
+            ),
+          ),
+        );
+        // Only display the menu selector if menu module is enabled.
+        if (module_exists('menu')) {
+          $form['tab_options']['name'] = array(
+            '#title' => t('Menu'),
+            '#type' => 'select',
+            '#options' => menu_get_menus(),
+            '#default_value' => $tab_options['name'],
+            '#description' => t('Insert item into an available menu.'),
+            '#states' => array(
+              'visible' => array(
+                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
+              ),
+            ),
+          );
+        }
+        else {
+          $form['tab_options']['name'] = array(
+            '#type' => 'value',
+            '#value' => $tab_options['name'],
+          );
+          $form['tab_options']['markup'] = array(
+            '#markup' => t('Menu selection requires the activation of menu module.'),
+          );
+        }
+        $form['tab_options']['weight'] = array(
+          '#suffix' => '</div>',
+          '#title' => t('Tab weight'),
+          '#type' => 'textfield',
+          '#default_value' => $tab_options['weight'],
+          '#size' => 5,
+          '#description' => t('If the parent menu item is a tab, enter the weight of the tab. The lower the number, the more to the left it will be.'),
+          '#states' => array(
+            'visible' => array(
+              ':input[name="tab_options[type]"]' => array('value' => 'tab'),
+            ),
+          ),
+        );
+        break;
+    }
+  }
+
+  function options_validate(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_validate($form, $form_state);
+    switch ($form_state['section']) {
+      case 'path':
+        if (strpos($form_state['values']['path'], '$arg') !== FALSE) {
+          form_error($form['path'], t('"$arg" is no longer supported. Use % instead.'));
+        }
+
+        if (strpos($form_state['values']['path'], '%') === 0) {
+          form_error($form['path'], t('"%" may not be used for the first segment of a path.'));
+        }
+
+        // automatically remove '/' from path.
+        $form_state['values']['path'] = trim($form_state['values']['path'], '/');
+
+        break;
+      case 'menu':
+        $path = $this->get_option('path');
+        if ($form_state['values']['menu']['type'] == 'normal' && strpos($path, '%') !== FALSE) {
+          form_error($form['menu']['type'], t('Views cannot create normal menu items for paths with a % in them.'));
+        }
+
+        if ($form_state['values']['menu']['type'] == 'default tab' || $form_state['values']['menu']['type'] == 'tab') {
+          $bits = explode('/', $path);
+          $last = array_pop($bits);
+          if ($last == '%') {
+            form_error($form['menu']['type'], t('A display whose path ends with a % cannot be a tab.'));
+          }
+        }
+
+        if ($form_state['values']['menu']['type'] != 'none' && empty($form_state['values']['menu']['title'])) {
+          form_error($form['menu']['title'], t('Title is required for this menu type.'));
+        }
+        break;
+    }
+  }
+
+  function options_submit(&$form, &$form_state) {
+    // It is very important to call the parent function here:
+    parent::options_submit($form, $form_state);
+    switch ($form_state['section']) {
+      case 'path':
+        $this->set_option('path', $form_state['values']['path']);
+        break;
+      case 'menu':
+        $this->set_option('menu', $form_state['values']['menu']);
+        // send ajax form to options page if we use it.
+        if ($form_state['values']['menu']['type'] == 'default tab') {
+          views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('tab_options'));
+        }
+        break;
+      case 'tab_options':
+        $this->set_option('tab_options', $form_state['values']['tab_options']);
+        break;
+    }
+  }
+
+  function validate() {
+    $errors = parent::validate();
+
+    $menu = $this->get_option('menu');
+    if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) {
+      $errors[] = t('Display @display is set to use a menu but the menu link text is not set.', array('@display' => $this->display->display_title));
+    }
+
+    if ($menu['type'] == 'default tab') {
+      $tab_options = $this->get_option('tab_options');
+      if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) {
+        $errors[] = t('Display @display is set to use a parent menu but the parent menu link text is not set.', array('@display' => $this->display->display_title));
+      }
+    }
+
+    return $errors;
+  }
+
+  function get_argument_text() {
+    return array(
+      'filter value not present' => t('When the filter value is <em>NOT</em> in the URL'),
+      'filter value present' => t('When the filter value <em>IS</em> in the URL or a default is provided'),
+      'description' => t('The contextual filter values is provided by the URL.'),
+    );
+  }
+
+  function get_pager_text() {
+    return array(
+      'items per page title' => t('Items per page'),
+      'items per page description' => t('The number of items to display per page. Enter 0 for no limit.')
+    );
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/display_extender/DisplayExtenderPlugin.php b/lib/Drupal/views/Plugins/views/display_extender/DisplayExtenderPlugin.php
new file mode 100644
index 0000000..c92b71b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/display_extender/DisplayExtenderPlugin.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\display_extender\DisplayExtenderPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\display_extender;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @todo.
+ *
+ * @ingroup views_display_plugins
+ */
+class DisplayExtenderPlugin extends Plugin {
+  function init(&$view, &$display) {
+    $this->view = $view;
+    $this->display = $display;
+  }
+
+
+  /**
+   * Provide a form to edit options for this plugin.
+   */
+  function options_definition_alter(&$options) { }
+
+  /**
+   * Provide a form to edit options for this plugin.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Validate the options form.
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Handle any special handling on the validate form.
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  /**
+   * Set up any variables on the view prior to execution.
+   */
+  function pre_execute() { }
+
+  /**
+   * Inject anything into the query that the display_extender handler needs.
+   */
+  function query() { }
+
+  /**
+   * Provide the default summary for options in the views UI.
+   *
+   * This output is returned as an array.
+   */
+  function options_summary(&$categories, &$options) { }
+
+  /**
+   * Static member function to list which sections are defaultable
+   * and what items each section contains.
+   */
+  function defaultable_sections(&$sections, $section = NULL) { }
+}
diff --git a/lib/Drupal/views/Plugins/views/exposed_form/BasicExposedForm.php b/lib/Drupal/views/Plugins/views/exposed_form/BasicExposedForm.php
new file mode 100644
index 0000000..910948f
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/exposed_form/BasicExposedForm.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\exposed_form\BasicExposedForm.
+ */
+
+namespace Drupal\views\Plugins\views\exposed_form;
+
+/**
+ * Exposed form plugin that provides a basic exposed form.
+ *
+ * @ingroup views_exposed_form_plugins
+ */
+class BasicExposedForm extends ExposedFormPlugin { }
diff --git a/lib/Drupal/views/Plugins/views/exposed_form/ExposedFormPlugin.inc b/lib/Drupal/views/Plugins/views/exposed_form/ExposedFormPlugin.inc
new file mode 100644
index 0000000..c1f4f21
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/exposed_form/ExposedFormPlugin.inc
@@ -0,0 +1,329 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\cache\ExposedFormPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\exposed_form;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_exposed_form_plugins Views exposed form plugins
+ * @{
+ * Plugins that handle the validation/submission and rendering of exposed forms.
+ *
+ * If needed, it is possible to use them to add additional form elements.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The base plugin to handle exposed filter forms.
+ */
+class ExposedFormPlugin extends Plugin {
+
+  /**
+   * Initialize the plugin.
+   *
+   * @param $view
+   *   The view object.
+   * @param $display
+   *   The display handler.
+   */
+  function init(&$view, &$display, $options = array()) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    $this->unpack_options($this->options, $options);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['submit_button'] = array('default' => t('Apply'), 'translatable' => TRUE);
+    $options['reset_button'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['reset_button_label'] = array('default' => 'Reset', 'translatable' => TRUE);
+    $options['exposed_sorts_label'] = array('default' => 'Sort by', 'translatable' => TRUE);
+    $options['sort_asc_label'] = array('default' => 'Asc', 'translatable' => TRUE);
+    $options['sort_desc_label'] = array('default' => 'Desc', 'translatable' => TRUE);
+    $options['autosubmit'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['autosubmit_hide'] = array('default' => TRUE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['submit_button'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Submit button text'),
+      '#description' => t('Text to display in the submit button of the exposed form.'),
+      '#default_value' => $this->options['submit_button'],
+      '#required' => TRUE,
+    );
+
+    $form['reset_button'] = array (
+      '#type' => 'checkbox',
+      '#title' => t('Include reset button'),
+      '#description' => t('If checked the exposed form will provide a button to reset all the applied exposed filters'),
+      '#default_value' => $this->options['reset_button'],
+    );
+
+    $form['reset_button_label'] = array(
+     '#type' => 'textfield',
+      '#title' => t('Reset button label'),
+      '#description' => t('Text to display in the reset button of the exposed form.'),
+      '#default_value' => $this->options['reset_button_label'],
+      '#required' => TRUE,
+      '#states' => array(
+        'invisible' => array(
+          'input[name="exposed_form_options[reset_button]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+
+    $form['exposed_sorts_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Exposed sorts label'),
+      '#description' => t('Text to display as the label of the exposed sort select box.'),
+      '#default_value' => $this->options['exposed_sorts_label'],
+      '#required' => TRUE,
+    );
+
+    $form['sort_asc_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Ascending'),
+      '#description' => t('Text to use when exposed sort is ordered ascending.'),
+      '#default_value' => $this->options['sort_asc_label'],
+      '#required' => TRUE,
+    );
+
+    $form['sort_desc_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Descending'),
+      '#description' => t('Text to use when exposed sort is ordered descending.'),
+      '#default_value' => $this->options['sort_desc_label'],
+      '#required' => TRUE,
+    );
+
+    $form['autosubmit'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Autosubmit'),
+      '#description' => t('Automatically submit the form once an element is changed.'),
+      '#default_value' => $this->options['autosubmit'],
+    );
+
+    $form['autosubmit_hide'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide submit button'),
+      '#description' => t('Hide submit button if javascript is enabled.'),
+      '#default_value' => $this->options['autosubmit_hide'],
+      '#states' => array(
+        'invisible' => array(
+          'input[name="exposed_form_options[autosubmit]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+  }
+
+  /**
+   * Render the exposed filter form.
+   *
+   * This actually does more than that; because it's using FAPI, the form will
+   * also assign data to the appropriate handlers for use in building the
+   * query.
+   */
+  function render_exposed_form($block = FALSE) {
+    // Deal with any exposed filters we may have, before building.
+    $form_state = array(
+      'view' => &$this->view,
+      'display' => &$this->display,
+      'method' => 'get',
+      'rerender' => TRUE,
+      'no_redirect' => TRUE,
+      'always_process' => TRUE,
+    );
+
+    // Some types of displays (eg. attachments) may wish to use the exposed
+    // filters of their parent displays instead of showing an additional
+    // exposed filter form for the attachment as well as that for the parent.
+    if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
+      unset($form_state['rerender']);
+    }
+
+    if (!empty($this->ajax)) {
+      $form_state['ajax'] = TRUE;
+    }
+
+    $form_state['exposed_form_plugin'] = $this;
+    $form = drupal_build_form('views_exposed_form', $form_state);
+    $output = drupal_render($form);
+
+    if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
+      return "";
+    }
+    else {
+      return $output;
+    }
+  }
+
+  function query() {
+    $view = $this->view;
+    $exposed_data = isset($view->exposed_data) ? $view->exposed_data : array();
+    $sort_by = isset($exposed_data['sort_by']) ? $exposed_data['sort_by'] : NULL;
+    if (!empty($sort_by)) {
+      // Make sure the original order of sorts is preserved
+      // (e.g. a sticky sort is often first)
+      if (isset($view->sort[$sort_by])) {
+        $view->query->orderby = array();
+        foreach ($view->sort as $key => $sort) {
+          if (!$sort->is_exposed()) {
+            $sort->query();
+          }
+          else if ($key == $sort_by) {
+            if (isset($exposed_data['sort_order']) && in_array($exposed_data['sort_order'], array('ASC', 'DESC'))) {
+              $sort->options['order'] = $exposed_data['sort_order'];
+            }
+            $sort->set_relationship();
+            $sort->query();
+          }
+        }
+      }
+    }
+  }
+
+  function pre_render($values) { }
+
+  function post_render(&$output) { }
+
+  function pre_execute() { }
+
+  function post_execute() { }
+
+  function exposed_form_alter(&$form, &$form_state) {
+    if (!empty($this->options['reset_button'])) {
+      $form['reset'] = array(
+        '#value' => $this->options['reset_button_label'],
+        '#type' => 'submit',
+      );
+    }
+
+    $form['submit']['#value'] = $this->options['submit_button'];
+    // Check if there is exposed sorts for this view
+    $exposed_sorts = array();
+    foreach ($this->view->sort as $id => $handler) {
+      if ($handler->can_expose() && $handler->is_exposed()) {
+        $exposed_sorts[$id] = check_plain($handler->options['expose']['label']);
+      }
+    }
+
+    if (count($exposed_sorts)) {
+      $form['sort_by'] = array(
+        '#type' => 'select',
+        '#options' => $exposed_sorts,
+        '#title' => $this->options['exposed_sorts_label'],
+      );
+      $sort_order = array(
+        'ASC' => $this->options['sort_asc_label'],
+        'DESC' => $this->options['sort_desc_label'],
+      );
+      if (isset($form_state['input']['sort_by']) && isset($this->view->sort[$form_state['input']['sort_by']])) {
+        $default_sort_order = $this->view->sort[$form_state['input']['sort_by']]->options['order'];
+      } else {
+        $first_sort = reset($this->view->sort);
+        $default_sort_order = $first_sort->options['order'];
+      }
+
+      if (!isset($form_state['input']['sort_by'])) {
+        $keys = array_keys($exposed_sorts);
+        $form_state['input']['sort_by'] = array_shift($keys);
+      }
+
+      $form['sort_order'] = array(
+        '#type' => 'select',
+        '#options' => $sort_order,
+        '#title' => t('Order'),
+        '#default_value' => $default_sort_order,
+      );
+      $form['submit']['#weight'] = 10;
+      if (isset($form['reset'])) {
+        $form['reset']['#weight'] = 10;
+      }
+    }
+
+    $pager = $this->view->display_handler->get_plugin('pager');
+    if ($pager) {
+      $pager->exposed_form_alter($form, $form_state);
+      $form_state['pager_plugin'] = $pager;
+    }
+
+
+    // Apply autosubmit values.
+    if (!empty($this->options['autosubmit'])) {
+      $form = array_merge_recursive($form, array('#attributes' => array('class' => array('ctools-auto-submit-full-form'))));
+      $form['submit']['#attributes']['class'][] = 'ctools-use-ajax';
+      $form['submit']['#attributes']['class'][] = 'ctools-auto-submit-click';
+      $form['#attached']['js'][] = drupal_get_path('module', 'ctools') . '/js/auto-submit.js';
+
+      if (!empty($this->options['autosubmit_hide'])) {
+        $form['submit']['#attributes']['class'][] = 'js-hide';
+      }
+    }
+  }
+
+  function exposed_form_validate(&$form, &$form_state) {
+    if (isset($form_state['pager_plugin'])) {
+      $form_state['pager_plugin']->exposed_form_validate($form, $form_state);
+    }
+  }
+
+  /**
+  * This function is executed when exposed form is submited.
+  *
+  * @param $form
+  *   Nested array of form elements that comprise the form.
+  * @param $form_state
+  *   A keyed array containing the current state of the form.
+  * @param $exclude
+  *   Nested array of keys to exclude of insert into
+  *   $view->exposed_raw_input
+  */
+  function exposed_form_submit(&$form, &$form_state, &$exclude) {
+    if (!empty($form_state['values']['op']) && $form_state['values']['op'] == $this->options['reset_button_label']) {
+      $this->reset_form($form, $form_state);
+    }
+    if (isset($form_state['pager_plugin'])) {
+      $form_state['pager_plugin']->exposed_form_submit($form, $form_state, $exclude);
+      $exclude[] = 'pager_plugin';
+    }
+  }
+
+  function reset_form(&$form, &$form_state) {
+    // _SESSION is not defined for users who are not logged in.
+
+    // If filters are not overridden, store the 'remember' settings on the
+    // default display. If they are, store them on this display. This way,
+    // multiple displays in the same view can share the same filters and
+    // remember settings.
+    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+
+    if (isset($_SESSION['views'][$this->view->name][$display_id])) {
+      unset($_SESSION['views'][$this->view->name][$display_id]);
+    }
+
+    // Set the form to allow redirect.
+    if (empty($this->view->live_preview)) {
+      $form_state['no_redirect'] = FALSE;
+    }
+    else {
+      $form_state['rebuild'] = TRUE;
+      $this->view->exposed_data = array();
+    }
+
+    $form_state['values'] = array();
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/exposed_form/InputRequiredExposedForm.php b/lib/Drupal/views/Plugins/views/exposed_form/InputRequiredExposedForm.php
new file mode 100644
index 0000000..ea844a4
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/exposed_form/InputRequiredExposedForm.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\exposed_form\InputRequiredExposedForm.
+ */
+
+namespace Drupal\views\Plugins\views\exposed_form;
+
+/**
+ * Exposed form plugin that provides an exposed form with required input.
+ *
+ * @ingroup views_exposed_form_plugins
+ */
+class InputRequiredExposedForm extends ExposedFormPlugin {
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['text_input_required'] = array('default' => t('Select any filter and click on Apply to see results'), 'translatable' => TRUE);
+    $options['text_input_required_format'] = array('default' => NULL);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['text_input_required'] = array(
+      '#type' => 'text_format',
+      '#title' => t('Text on demand'),
+      '#description' => t('Text to display instead of results until the user selects and applies an exposed filter.'),
+      '#default_value' => $this->options['text_input_required'],
+      '#format' => isset($this->options['text_input_required_format']) ? $this->options['text_input_required_format'] : filter_default_format(),
+      '#wysiwyg' => FALSE,
+    );
+  }
+
+  function options_submit(&$form, &$form_state) {
+    $form_state['values']['exposed_form_options']['text_input_required_format'] = $form_state['values']['exposed_form_options']['text_input_required']['format'];
+    $form_state['values']['exposed_form_options']['text_input_required'] = $form_state['values']['exposed_form_options']['text_input_required']['value'];
+    parent::options_submit($form, $form_state);
+  }
+
+  function exposed_filter_applied() {
+    static $cache = NULL;
+    if (!isset($cache)) {
+      $view = $this->view;
+      if (is_array($view->filter) && count($view->filter)) {
+        foreach ($view->filter as $filter_id => $filter) {
+          if ($filter->is_exposed()) {
+            $identifier = $filter->options['expose']['identifier'];
+            if (isset($view->exposed_input[$identifier])) {
+              $cache = TRUE;
+              return $cache;
+            }
+          }
+        }
+      }
+      $cache = FALSE;
+    }
+
+    return $cache;
+  }
+
+  function pre_render($values) {
+    if (!$this->exposed_filter_applied()) {
+      $options = array(
+        'id' => 'area',
+        'table' => 'views',
+        'field' => 'area',
+        'label' => '',
+        'relationship' => 'none',
+        'group_type' => 'group',
+        'content' => $this->options['text_input_required'],
+        'format' => $this->options['text_input_required_format'],
+      );
+      $handler = views_get_handler('views', 'area', 'area');
+      $handler->init($this->view, $options);
+      $this->display->handler->handlers['empty'] = array(
+        'area' => $handler,
+      );
+      $this->display->handler->set_option('empty', array('text' => $options));
+    }
+  }
+
+  function query() {
+    if (!$this->exposed_filter_applied()) {
+      // We return with no query; this will force the empty text.
+      $this->view->built = TRUE;
+      $this->view->executed = TRUE;
+      $this->view->result = array();
+    }
+    else {
+      parent::query();
+    }
+  }
+
+}
diff --git a/lib/Drupal/views/Plugins/views/field/BooleanField.php b/lib/Drupal/views/Plugins/views/field/BooleanField.php
new file mode 100644
index 0000000..5c865dd
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/BooleanField.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\BooleanField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to provide proper displays for booleans.
+ *
+ * Allows for display of true/false, yes/no, on/off, enabled/disabled.
+ *
+ * Definition terms:
+ *   - output formats: An array where the first entry is displayed on boolean true
+ *      and the second is displayed on boolean false. An example for sticky is:
+ *      @code
+ *      'output formats' => array(
+ *        'sticky' => array(t('Sticky'), ''),
+ *      ),
+ *      @endcode
+ *
+ * @ingroup views_field_handlers
+ */
+class BooleanField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['type'] = array('default' => 'yes-no');
+    $options['not'] = array('definition bool' => 'reverse');
+
+    return $options;
+  }
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $default_formats = array(
+      'yes-no' => array(t('Yes'), t('No')),
+      'true-false' => array(t('True'), t('False')),
+      'on-off' => array(t('On'), t('Off')),
+      'enabled-disabled' => array(t('Enabled'), t('Disabled')),
+      'unicode-yes-no' => array('✔', '✖'),
+    );
+    $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array();
+    $this->formats = array_merge($default_formats, $output_formats);
+  }
+
+  function options_form(&$form, &$form_state) {
+    foreach ($this->formats as $key => $item) {
+      $options[$key] = implode('/', $item);
+    }
+
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Output format'),
+      '#options' => $options,
+      '#default_value' => $this->options['type'],
+    );
+    $form['not'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Reverse'),
+      '#description' => t('If checked, true will be displayed as false.'),
+      '#default_value' => $this->options['not'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (!empty($this->options['not'])) {
+      $value = !$value;
+    }
+
+    if (isset($this->formats[$this->options['type']])) {
+      return $value ? $this->formats[$this->options['type']][0] : $this->formats[$this->options['type']][1];
+    }
+    else {
+      return $value ? $this->formats['yes-no'][0] : $this->formats['yes-no'][1];
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/ContextualLinksField.php b/lib/Drupal/views/Plugins/views/field/ContextualLinksField.php
new file mode 100644
index 0000000..36295be
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/ContextualLinksField.php
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\ContextualLinksField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Provides a handler that adds contextual links.
+ *
+ * @ingroup views_field_handlers
+ */
+class ContextualLinksField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['fields'] = array('default' => array());
+    $options['destination'] = array('default' => 1);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $all_fields = $this->view->display_handler->get_field_labels();
+    // Offer to include only those fields that follow this one.
+    $field_options = array_slice($all_fields, 0, array_search($this->options['id'], array_keys($all_fields)));
+    $form['fields'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Fields'),
+      '#description' => t('Fields to be included as contextual links.'),
+      '#options' => $field_options,
+      '#default_value' => $this->options['fields'],
+    );
+    $form['destination'] = array(
+      '#type' => 'select',
+      '#title' => t('Include destination'),
+      '#description' => t('Include a "destination" parameter in the link to return the user to the original view upon completing the contextual action.'),
+      '#options' => array(
+        '0' => t('No'),
+        '1' => t('Yes'),
+      ),
+      '#default_value' => $this->options['destination'],
+    );
+  }
+
+  function pre_render(&$values) {
+    // Add a row plugin css class for the contextual link.
+    $class = 'contextual-links-region';
+    if (!empty($this->view->style_plugin->options['row_class'])) {
+      $this->view->style_plugin->options['row_class'] .= " $class";
+    }
+    else {
+      $this->view->style_plugin->options['row_class'] = $class;
+    }
+  }
+
+  /**
+   * Render the contextual fields.
+   */
+  function render($values) {
+    $links = array();
+    foreach ($this->options['fields'] as $field) {
+      if (empty($this->view->style_plugin->rendered_fields[$this->view->row_index][$field])) {
+        continue;
+      }
+      $title = $this->view->field[$field]->last_render_text;
+      $path = '';
+      if (!empty($this->view->field[$field]->options['alter']['path'])) {
+        $path = $this->view->field[$field]->options['alter']['path'];
+      }
+      if (!empty($title)) {
+        // Make sure that tokens are replaced for this paths as well.
+        $tokens = $this->get_render_tokens(array());
+        $path = strip_tags(decode_entities(strtr($path, $tokens)));
+
+        $links[$field] = array(
+          'href' => $path,
+          'title' => $title,
+        );
+        if (!empty($this->options['destination'])) {
+          $links[$field]['query'] = drupal_get_destination();
+        }
+      }
+    }
+
+    if (!empty($links)) {
+      $build = array(
+        '#prefix' => '<div class="contextual-links-wrapper">',
+        '#suffix' => '</div>',
+        '#theme' => 'links__contextual',
+        '#links' => $links,
+        '#attributes' => array('class' => array('contextual-links')),
+        '#attached' => array(
+          'library' => array(array('contextual', 'contextual-links')),
+        ),
+        '#access' => user_access('access contextual links'),
+      );
+      return drupal_render($build);
+    }
+    else {
+      return '';
+    }
+  }
+
+  function query() { }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/CounterField.php b/lib/Drupal/views/Plugins/views/field/CounterField.php
new file mode 100644
index 0000000..6bd49dd
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/CounterField.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\CounterField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Field handler to show a counter of the current row.
+ *
+ * @ingroup views_field_handlers
+ */
+class CounterField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['counter_start'] = array('default' => 1);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['counter_start'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Starting value'),
+      '#default_value' => $this->options['counter_start'],
+      '#description' => t('Specify the number the counter should start at.'),
+      '#size' => 2,
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  function query() {
+    // do nothing -- to override the parent query.
+  }
+
+  function render($values) {
+    // Note:  1 is subtracted from the counter start value below because the
+    // counter value is incremented by 1 at the end of this function.
+    $count = is_numeric($this->options['counter_start']) ? $this->options['counter_start'] - 1 : 0;
+    $pager = $this->view->query->pager;
+    // Get the base count of the pager.
+    if ($pager->use_pager()) {
+      $count += ($pager->get_items_per_page() * $pager->get_current_page() + $pager->get_offset());
+    }
+    // Add the counter for the current site.
+    $count += $this->view->row_index + 1;
+
+    return $count;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/CustomField.php b/lib/Drupal/views/Plugins/views/field/CustomField.php
new file mode 100644
index 0000000..6cc3446
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/CustomField.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\CustomField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to provide a field that is completely custom by the administrator.
+ *
+ * @ingroup views_field_handlers
+ */
+class CustomField extends FieldPlugin {
+  function query() {
+    // do nothing -- to override the parent query.
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    // Override the alter text option to always alter the text.
+    $options['alter']['contains']['alter_text'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['hide_alter_empty'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // Remove the checkbox
+    unset($form['alter']['alter_text']);
+    unset($form['alter']['text']['#states']);
+    unset($form['alter']['help']['#states']);
+    $form['#pre_render'][] = 'views_handler_field_custom_pre_render_move_text';
+  }
+
+  function render($values) {
+    // Return the text, so the code never thinks the value is empty.
+    return $this->options['alter']['text'];
+  }
+}
+
+/**
+ * Prerender function to move the textarea to the top.
+ */
+function views_handler_field_custom_pre_render_move_text($form) {
+  $form['text'] = $form['alter']['text'];
+  $form['help'] = $form['alter']['help'];
+  unset($form['alter']['text']);
+  unset($form['alter']['help']);
+
+  return $form;
+}
diff --git a/lib/Drupal/views/Plugins/views/field/DateField.php b/lib/Drupal/views/Plugins/views/field/DateField.php
new file mode 100644
index 0000000..256d27e
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/DateField.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\CustomField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to provide proper displays for dates.
+ *
+ * @ingroup views_field_handlers
+ */
+class DateField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['date_format'] = array('default' => 'small');
+    $options['custom_date_format'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+
+    $date_formats = array();
+    $date_types = system_get_date_types();
+    foreach ($date_types as $key => $value) {
+      $date_formats[$value['type']] = check_plain(t($value['title'] . ' format')) . ': ' . format_date(REQUEST_TIME, $value['type']);
+    }
+
+    $form['date_format'] = array(
+      '#type' => 'select',
+      '#title' => t('Date format'),
+      '#options' => $date_formats + array(
+        'custom' => t('Custom'),
+        'raw time ago' => t('Time ago'),
+        'time ago' => t('Time ago (with "ago" appended)'),
+        'raw time hence' => t('Time hence'),
+        'time hence' => t('Time hence (with "hence" appended)'),
+        'raw time span' => t('Time span (future dates have "-" prepended)'),
+        'inverse time span' => t('Time span (past dates have "-" prepended)'),
+        'time span' => t('Time span (with "ago/hence" appended)'),
+      ),
+      '#default_value' => isset($this->options['date_format']) ? $this->options['date_format'] : 'small',
+    );
+    $form['custom_date_format'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom date format'),
+      '#description' => t('If "Custom", see <a href="http://us.php.net/manual/en/function.date.php" target="_blank">the PHP docs</a> for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.'),
+      '#default_value' => isset($this->options['custom_date_format']) ? $this->options['custom_date_format'] : '',
+    );
+    // Setup #states for all possible date_formats on the custom_date_format form element.
+    foreach (array('custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span') as $custom_date_possible) {
+      $form['custom_date_format']['#states']['visible'][] = array(
+        ':input[name="options[date_format]"]' => array('value' => $custom_date_possible),
+      );
+    }
+
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    $format = $this->options['date_format'];
+    if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span'))) {
+      $custom_format = $this->options['custom_date_format'];
+    }
+
+    if ($value) {
+      $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
+      switch ($format) {
+        case 'raw time ago':
+          return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
+        case 'time ago':
+          return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
+        case 'raw time hence':
+          return format_interval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2);
+        case 'time hence':
+          return t('%time hence', array('%time' => format_interval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2)));
+        case 'raw time span':
+          return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
+        case 'inverse time span':
+          return ($time_diff > 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
+        case 'time span':
+          return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
+        case 'custom':
+          if ($custom_format == 'r') {
+            return format_date($value, $format, $custom_format, null, 'en');
+          }
+          return format_date($value, $format, $custom_format);
+        default:
+          return format_date($value, $format);
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/EntityField.php b/lib/Drupal/views/Plugins/views/field/EntityField.php
new file mode 100644
index 0000000..e0c8d2d
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/EntityField.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\EntityField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to display data from entity objects.
+ *
+ * Fields based upon this handler work with all query-backends if the tables
+ * used by the query backend have an 'entity type' specified. In order to
+ * make fields based upon this handler automatically available to all compatible
+ * query backends, the views field can be defined in the table
+ * @code views_entity_{ENTITY_TYPE} @endcode.
+ *
+ * @ingroup views_field_handlers
+ */
+class EntityField extends FieldPlugin {
+
+  /**
+   * Stores the entity type which is loaded by this field.
+   */
+  public $entity_type;
+
+  /**
+   * Stores all entites which are in the result.
+   */
+  public $entities;
+
+  /**
+   * The base field of the entity type assosiated with this field.
+   */
+  public $base_field;
+
+  /**
+   * Initialize the entity type.
+   */
+  public function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Initialize the entity-type used.
+    $table_data = views_fetch_data($this->table);
+    $this->entity_type = $table_data['table']['entity type'];
+  }
+
+  /**
+   * Overriden to add the field for the entity id.
+   */
+  function query() {
+    $this->table_alias = $base_table = $this->view->base_table;
+    $this->base_field = $this->view->base_field;
+
+    if (!empty($this->relationship)) {
+      foreach ($this->view->relationship as $relationship) {
+        if ($relationship->alias == $this->relationship) {
+          $base_table = $relationship->definition['base'];
+          $this->table_alias = $relationship->alias;
+
+          $table_data = views_fetch_data($base_table);
+          $this->base_field = empty($relationship->definition['base field']) ? $table_data['table']['base']['field'] : $relationship->definition['base field'];
+        }
+      }
+    }
+
+    // Add the field if the query back-end implements an add_field() method,
+    // just like the default back-end.
+    if (method_exists($this->query, 'add_field')) {
+      $this->field_alias = $this->query->add_field($this->table_alias, $this->base_field, '');
+    }
+
+    $this->add_additional_fields();
+  }
+
+  /**
+   * Load the entities for all rows that are about to be displayed.
+   */
+  function pre_render(&$values) {
+    if (!empty($values)) {
+      list($this->entity_type, $this->entities) = $this->query->get_result_entities($values, !empty($this->relationship) ? $this->relationship : NULL, $this->field_alias);
+    }
+  }
+
+  /**
+   * Overridden to return the entity object, or a certain property of the entity.
+   */
+  function get_value($values, $field = NULL) {
+    if (isset($this->entities[$this->view->row_index])) {
+      $entity = $this->entities[$this->view->row_index];
+      // Support to get a certain part of the entity.
+      if (isset($field) && isset($entity->{$field})) {
+        return $entity->{$field};
+      }
+      // Support to get a part of the values as the normal get_value.
+      elseif (isset($field) && isset($values->{$this->aliases[$field]})) {
+        return $values->{$this->aliases[$field]};
+      }
+      else {
+        return $entity;
+      }
+    }
+    return FALSE;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/FieldPlugin.php b/lib/Drupal/views/Plugins/views/field/FieldPlugin.php
new file mode 100644
index 0000000..80d6522
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/FieldPlugin.php
@@ -0,0 +1,1689 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\FieldPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_field_handlers Views field handlers
+ * @{
+ * Handlers to tell Views how to build and display fields.
+ *
+ */
+
+/**
+ * Indicator of the render_text() method for rendering a single item.
+ * (If no render_item() is present).
+ */
+define('VIEWS_HANDLER_RENDER_TEXT_PHASE_SINGLE_ITEM', 0);
+
+/**
+ * Indicator of the render_text() method for rendering the whole element.
+ * (if no render_item() method is available).
+ */
+define('VIEWS_HANDLER_RENDER_TEXT_PHASE_COMPLETELY', 1);
+
+/**
+ * Indicator of the render_text() method for rendering the empty text.
+ */
+define('VIEWS_HANDLER_RENDER_TEXT_PHASE_EMPTY', 2);
+
+/**
+ * Base field handler that has no options and renders an unformatted field.
+ *
+ * Definition terms:
+ * - additional fields: An array of fields that should be added to the query
+ *                      for some purpose. The array is in the form of:
+ *                      array('identifier' => array('table' => tablename,
+ *                      'field' => fieldname); as many fields as are necessary
+ *                      may be in this array.
+ * - click sortable: If TRUE, this field may be click sorted.
+ *
+ * @ingroup views_field_handlers
+ */
+class FieldPlugin extends Plugin {
+  var $field_alias = 'unknown';
+  var $aliases = array();
+
+  /**
+   * The field value prior to any rewriting.
+   *
+   * @var mixed
+   */
+  public $original_value = NULL;
+
+  /**
+   * @var array
+   * Stores additional fields which get's added to the query.
+   * The generated aliases are stored in $aliases.
+   */
+  var $additional_fields = array();
+
+  /**
+   * Construct a new field handler.
+   */
+  function construct() {
+    parent::construct();
+
+    $this->additional_fields = array();
+    if (!empty($this->definition['additional fields'])) {
+      $this->additional_fields = $this->definition['additional fields'];
+    }
+
+    if (!isset($this->options['exclude'])) {
+      $this->options['exclude'] = '';
+    }
+  }
+
+  /**
+   * Determine if this field can allow advanced rendering.
+   *
+   * Fields can set this to FALSE if they do not wish to allow
+   * token based rewriting or link-making.
+   */
+  function allow_advanced_render() {
+    return TRUE;
+  }
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+  }
+
+  /**
+   * Called to add the field to a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+    // Add the field.
+    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
+    $this->field_alias = $this->query->add_field($this->table_alias, $this->real_field, NULL, $params);
+
+    $this->add_additional_fields();
+  }
+
+  /**
+   * Add 'additional' fields to the query.
+   *
+   * @param $fields
+   * An array of fields. The key is an identifier used to later find the
+   * field alias used. The value is either a string in which case it's
+   * assumed to be a field on this handler's table; or it's an array in the
+   * form of
+   * @code array('table' => $tablename, 'field' => $fieldname) @endcode
+   */
+  function add_additional_fields($fields = NULL) {
+    if (!isset($fields)) {
+      // notice check
+      if (empty($this->additional_fields)) {
+        return;
+      }
+      $fields = $this->additional_fields;
+    }
+
+    $group_params = array();
+    if ($this->options['group_type'] != 'group') {
+      $group_params = array(
+        'function' => $this->options['group_type'],
+      );
+    }
+
+    if (!empty($fields) && is_array($fields)) {
+      foreach ($fields as $identifier => $info) {
+        if (is_array($info)) {
+          if (isset($info['table'])) {
+            $table_alias = $this->query->ensure_table($info['table'], $this->relationship);
+          }
+          else {
+            $table_alias = $this->table_alias;
+          }
+
+          if (empty($table_alias)) {
+            debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['handler'], '@identifier' => $identifier, '@table' => $info['table'])));
+            $this->aliases[$identifier] = 'broken';
+            continue;
+          }
+
+          $params = array();
+          if (!empty($info['params'])) {
+            $params = $info['params'];
+          }
+
+          $params += $group_params;
+          $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field'], NULL, $params);
+        }
+        else {
+          $this->aliases[$info] = $this->query->add_field($this->table_alias, $info, NULL, $group_params);
+        }
+      }
+    }
+  }
+
+  /**
+   * Called to determine what to tell the clicksorter.
+   */
+  function click_sort($order) {
+    if (isset($this->field_alias)) {
+      // Since fields should always have themselves already added, just
+      // add a sort on the field.
+      $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
+      $this->query->add_orderby(NULL, NULL, $order, $this->field_alias, $params);
+    }
+  }
+
+  /**
+   * Determine if this field is click sortable.
+   */
+  function click_sortable() {
+    return !empty($this->definition['click sortable']);
+  }
+
+  /**
+   * Get this field's label.
+   */
+  function label() {
+    if (!isset($this->options['label'])) {
+      return '';
+    }
+    return $this->options['label'];
+  }
+
+  /**
+   * Return an HTML element based upon the field's element type.
+   */
+  function element_type($none_supported = FALSE, $default_empty = FALSE, $inline = FALSE) {
+    if ($none_supported) {
+      if ($this->options['element_type'] === '0') {
+        return '';
+      }
+    }
+    if ($this->options['element_type']) {
+      return check_plain($this->options['element_type']);
+    }
+
+    if ($default_empty) {
+      return '';
+    }
+
+    if ($inline) {
+      return 'span';
+    }
+
+    if (isset($this->definition['element type'])) {
+      return $this->definition['element type'];
+    }
+
+    return 'span';
+  }
+
+  /**
+   * Return an HTML element for the label based upon the field's element type.
+   */
+  function element_label_type($none_supported = FALSE, $default_empty = FALSE) {
+    if ($none_supported) {
+      if ($this->options['element_label_type'] === '0') {
+        return '';
+      }
+    }
+    if ($this->options['element_label_type']) {
+      return check_plain($this->options['element_label_type']);
+    }
+
+    if ($default_empty) {
+      return '';
+    }
+
+    return 'span';
+  }
+
+  /**
+   * Return an HTML element for the wrapper based upon the field's element type.
+   */
+  function element_wrapper_type($none_supported = FALSE, $default_empty = FALSE) {
+    if ($none_supported) {
+      if ($this->options['element_wrapper_type'] === '0') {
+        return 0;
+      }
+    }
+    if ($this->options['element_wrapper_type']) {
+      return check_plain($this->options['element_wrapper_type']);
+    }
+
+    if ($default_empty) {
+      return '';
+    }
+
+    return 'div';
+  }
+
+  /**
+   * Provide a list of elements valid for field HTML.
+   *
+   * This function can be overridden by fields that want more or fewer
+   * elements available, though this seems like it would be an incredibly
+   * rare occurence.
+   */
+  function get_elements() {
+    static $elements = NULL;
+    if (!isset($elements)) {
+      $elements = variable_get('views_field_rewrite_elements', array(
+        '' => t('- Use default -'),
+        '0' => t('- None -'),
+        'div' => 'DIV',
+        'span' => 'SPAN',
+        'h1' => 'H1',
+        'h2' => 'H2',
+        'h3' => 'H3',
+        'h4' => 'H4',
+        'h5' => 'H5',
+        'h6' => 'H6',
+        'p' => 'P',
+        'strong' => 'STRONG',
+        'em' => 'EM',
+      ));
+    }
+
+    return $elements;
+  }
+
+  /**
+   * Return the class of the field.
+   */
+  function element_classes($row_index = NULL) {
+    $classes = explode(' ', $this->options['element_class']);
+    foreach ($classes as &$class) {
+      $class = $this->tokenize_value($class, $row_index);
+      $class = views_clean_css_identifier($class);
+    }
+    return implode(' ', $classes);
+  }
+
+  /**
+   * Replace a value with tokens from the last field.
+   *
+   * This function actually figures out which field was last and uses its
+   * tokens so they will all be available.
+   */
+  function tokenize_value($value, $row_index = NULL) {
+    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
+      $fake_item = array(
+        'alter_text' => TRUE,
+        'text' => $value,
+      );
+
+      // Use isset() because empty() will trigger on 0 and 0 is
+      // the first row.
+      if (isset($row_index) && isset($this->view->style_plugin->render_tokens[$row_index])) {
+        $tokens = $this->view->style_plugin->render_tokens[$row_index];
+      }
+      else {
+        // Get tokens from the last field.
+        $last_field = end($this->view->field);
+        if (isset($last_field->last_tokens)) {
+          $tokens = $last_field->last_tokens;
+        }
+        else {
+          $tokens = $last_field->get_render_tokens($fake_item);
+        }
+      }
+
+      $value = strip_tags($this->render_altered($fake_item, $tokens));
+      if (!empty($this->options['alter']['trim_whitespace'])) {
+        $value = trim($value);
+      }
+    }
+
+    return $value;
+  }
+
+  /**
+   * Return the class of the field's label.
+   */
+  function element_label_classes($row_index = NULL) {
+    $classes = explode(' ', $this->options['element_label_class']);
+    foreach ($classes as &$class) {
+      $class = $this->tokenize_value($class, $row_index);
+      $class = views_clean_css_identifier($class);
+    }
+    return implode(' ', $classes);
+  }
+
+  /**
+   * Return the class of the field's wrapper.
+   */
+  function element_wrapper_classes($row_index = NULL) {
+    $classes = explode(' ', $this->options['element_wrapper_class']);
+    foreach ($classes as &$class) {
+      $class = $this->tokenize_value($class, $row_index);
+      $class = views_clean_css_identifier($class);
+    }
+    return implode(' ', $classes);
+  }
+
+  /**
+   * Get the value that's supposed to be rendered.
+   *
+   * This api exists so that other modules can easy set the values of the field
+   * without having the need to change the render method as well.
+   *
+   * @param $values
+   *   An object containing all retrieved values.
+   * @param $field
+   *   Optional name of the field where the value is stored.
+   */
+  function get_value($values, $field = NULL) {
+    $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
+    if (isset($values->{$alias})) {
+      return $values->{$alias};
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['label'] = array('default' => $this->definition['title'], 'translatable' => TRUE);
+    $options['exclude'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['alter'] = array(
+      'contains' => array(
+        'alter_text' => array('default' => FALSE, 'bool' => TRUE),
+        'text' => array('default' => '', 'translatable' => TRUE),
+        'make_link' => array('default' => FALSE, 'bool' => TRUE),
+        'path' => array('default' => '', 'translatable' => TRUE),
+        'absolute' => array('default' => FALSE, 'bool' => TRUE),
+        'external' => array('default' => FALSE, 'bool' => TRUE),
+        'replace_spaces' => array('default' => FALSE, 'bool' => TRUE),
+        'path_case' => array('default' => 'none', 'translatable' => FALSE),
+        'trim_whitespace' => array('default' => FALSE, 'bool' => TRUE),
+        'alt' => array('default' => '', 'translatable' => TRUE),
+        'rel' => array('default' => ''),
+        'link_class' => array('default' => ''),
+        'prefix' => array('default' => '', 'translatable' => TRUE),
+        'suffix' => array('default' => '', 'translatable' => TRUE),
+        'target' => array('default' => '', 'translatable' => TRUE),
+        'nl2br' => array('default' => FALSE, 'bool' => TRUE),
+        'max_length' => array('default' => ''),
+        'word_boundary' => array('default' => TRUE, 'bool' => TRUE),
+        'ellipsis' => array('default' => TRUE, 'bool' => TRUE),
+        'more_link' => array('default' => FALSE, 'bool' => TRUE),
+        'more_link_text' => array('default' => '', 'translatable' => TRUE),
+        'more_link_path' => array('default' => ''),
+        'strip_tags' => array('default' => FALSE, 'bool' => TRUE),
+        'trim' => array('default' => FALSE, 'bool' => TRUE),
+        'preserve_tags' => array('default' => ''),
+        'html' => array('default' => FALSE, 'bool' => TRUE),
+      ),
+    );
+    $options['element_type'] = array('default' => '');
+    $options['element_class'] = array('default' => '');
+
+    $options['element_label_type'] = array('default' => '');
+    $options['element_label_class'] = array('default' => '');
+    $options['element_label_colon'] = array('default' => TRUE, 'bool' => TRUE);
+
+    $options['element_wrapper_type'] = array('default' => '');
+    $options['element_wrapper_class'] = array('default' => '');
+
+    $options['element_default_classes'] = array('default' => TRUE, 'bool' => TRUE);
+
+    $options['empty'] = array('default' => '', 'translatable' => TRUE);
+    $options['hide_empty'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['empty_zero'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['hide_alter_empty'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Performs some cleanup tasks on the options array before saving it.
+   */
+  function options_submit(&$form, &$form_state) {
+    $options = &$form_state['values']['options'];
+    $types = array('element_type', 'element_label_type', 'element_wrapper_type');
+    $classes = array_combine(array('element_class', 'element_label_class', 'element_wrapper_class'), $types);
+
+    foreach ($types as $type) {
+      if (!$options[$type . '_enable']) {
+        $options[$type] = '';
+      }
+    }
+
+    foreach ($classes as $class => $type) {
+      if (!$options[$class . '_enable'] || !$options[$type . '_enable']) {
+        $options[$class] = '';
+      }
+    }
+
+    if (empty($options['custom_label'])) {
+      $options['label'] = '';
+      $options['element_label_colon'] = FALSE;
+    }
+  }
+
+  /**
+   * Default options form that provides the label widget that all fields
+   * should have.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $label = $this->label();
+    $form['custom_label'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Create a label'),
+      '#description' => t('Enable to create a label for this field.'),
+      '#default_value' => $label !== '',
+      '#weight' => -103,
+    );
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label'),
+      '#default_value' => $label,
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[custom_label]"]' => array('checked' => TRUE),
+        ),
+      ),
+
+      '#weight' => -102,
+    );
+    $form['element_label_colon'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Place a colon after the label'),
+      '#default_value' => $this->options['element_label_colon'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[custom_label]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#weight' => -101,
+    );
+
+    $form['exclude'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Exclude from display'),
+      '#default_value' => $this->options['exclude'],
+      '#description' => t('Enable to load this field as hidden. Often used to group fields, or to use as token in another field.'),
+      '#weight' => -100,
+    );
+
+    $form['style_settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Style settings'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => 99,
+    );
+
+    $form['element_type_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Customize field HTML'),
+      '#default_value' => !empty($this->options['element_type']) || (string) $this->options['element_type'] == '0' || !empty($this->options['element_class']) || (string) $this->options['element_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_type'] = array(
+      '#title' => t('HTML element'),
+      '#options' => $this->get_elements(),
+      '#type' => 'select',
+      '#default_value' => $this->options['element_type'],
+      '#description' => t('Choose the HTML element to wrap around this field, e.g. H1, H2, etc.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['element_class_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Create a CSS class'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#default_value' => !empty($this->options['element_class']) || (string) $this->options['element_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_class'] = array(
+      '#title' => t('CSS class'),
+      '#description' => t('You may use token substitutions from the rewriting section in this class.'),
+      '#type' => 'textfield',
+      '#default_value' => $this->options['element_class'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_type_enable]"]' => array('checked' => TRUE),
+          ':input[name="options[element_class_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['element_label_type_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Customize label HTML'),
+      '#default_value' => !empty($this->options['element_label_type']) || (string) $this->options['element_label_type'] == '0' || !empty($this->options['element_label_class']) || (string) $this->options['element_label_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_label_type'] = array(
+      '#title' => t('Label HTML element'),
+      '#options' => $this->get_elements(FALSE),
+      '#type' => 'select',
+      '#default_value' => $this->options['element_label_type'],
+      '#description' => t('Choose the HTML element to wrap around this label, e.g. H1, H2, etc.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_label_class_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Create a CSS class'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#default_value' => !empty($this->options['element_label_class']) || (string) $this->options['element_label_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_label_class'] = array(
+      '#title' => t('CSS class'),
+      '#description' => t('You may use token substitutions from the rewriting section in this class.'),
+      '#type' => 'textfield',
+      '#default_value' => $this->options['element_label_class'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE),
+          ':input[name="options[element_label_class_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['element_wrapper_type_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Customize field and label wrapper HTML'),
+      '#default_value' => !empty($this->options['element_wrapper_type']) || (string) $this->options['element_wrapper_type'] == '0' || !empty($this->options['element_wrapper_class']) || (string) $this->options['element_wrapper_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_wrapper_type'] = array(
+      '#title' => t('Wrapper HTML element'),
+      '#options' => $this->get_elements(FALSE),
+      '#type' => 'select',
+      '#default_value' => $this->options['element_wrapper_type'],
+      '#description' => t('Choose the HTML element to wrap around this field and label, e.g. H1, H2, etc. This may not be used if the field and label are not rendered together, such as with a table.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['element_wrapper_class_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Create a CSS class'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#default_value' => !empty($this->options['element_wrapper_class']) || (string) $this->options['element_wrapper_class'] == '0',
+      '#fieldset' => 'style_settings',
+    );
+    $form['element_wrapper_class'] = array(
+      '#title' => t('CSS class'),
+      '#description' => t('You may use token substitutions from the rewriting section in this class.'),
+      '#type' => 'textfield',
+      '#default_value' => $this->options['element_wrapper_class'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[element_wrapper_class_enable]"]' => array('checked' => TRUE),
+          ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['element_default_classes'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Add default classes'),
+      '#default_value' => $this->options['element_default_classes'],
+      '#description' => t('Use default Views classes to identify the field, field label and field content.'),
+      '#fieldset' => 'style_settings',
+    );
+
+    $form['alter'] = array(
+      '#title' => t('Rewrite results'),
+      '#type' => 'fieldset',
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => 100,
+    );
+
+    if ($this->allow_advanced_render()) {
+      $form['alter']['#tree'] = TRUE;
+      $form['alter']['alter_text'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Rewrite the output of this field'),
+        '#description' => t('Enable to override the output of this field with custom text or replacement tokens.'),
+        '#default_value' => $this->options['alter']['alter_text'],
+      );
+
+      $form['alter']['text'] = array(
+        '#title' => t('Text'),
+        '#type' => 'textarea',
+        '#default_value' => $this->options['alter']['text'],
+        '#description' => t('The text to display for this field. You may include HTML. You may enter data from this view as per the "Replacement patterns" below.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['make_link'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Output this field as a link'),
+        '#description' => t('If checked, this field will be made into a link. The destination must be given below.'),
+        '#default_value' => $this->options['alter']['make_link'],
+      );
+      $form['alter']['path'] = array(
+        '#title' => t('Link path'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['path'],
+        '#description' => t('The Drupal path or absolute URL for this link. You may enter data from this view as per the "Replacement patterns" below.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+        '#maxlength' => 255,
+      );
+      $form['alter']['absolute'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Use absolute path'),
+        '#default_value' => $this->options['alter']['absolute'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['replace_spaces'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Replace spaces with dashes'),
+        '#default_value' => $this->options['alter']['replace_spaces'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['external'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('External server URL'),
+        '#default_value' => $this->options['alter']['external'],
+        '#description' => t("Links to an external server using a full URL: e.g. 'http://www.example.com' or 'www.example.com'."),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['path_case'] = array(
+        '#type' => 'select',
+        '#title' => t('Transform the case'),
+        '#description' => t('When printing url paths, how to transform the case of the filter value.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+       '#options' => array(
+          'none' => t('No transform'),
+          'upper' => t('Upper case'),
+          'lower' => t('Lower case'),
+          'ucfirst' => t('Capitalize first letter'),
+          'ucwords' => t('Capitalize each word'),
+        ),
+        '#default_value' => $this->options['alter']['path_case'],
+      );
+      $form['alter']['link_class'] = array(
+        '#title' => t('Link class'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['link_class'],
+        '#description' => t('The CSS class to apply to the link.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['alt'] = array(
+        '#title' => t('Title text'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['alt'],
+        '#description' => t('Text to place as "title" text which most browsers display as a tooltip when hovering over the link.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['rel'] = array(
+        '#title' => t('Rel Text'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['rel'],
+        '#description' => t('Include Rel attribute for use in lightbox2 or other javascript utility.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['prefix'] = array(
+        '#title' => t('Prefix text'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['prefix'],
+        '#description' => t('Any text to display before this link. You may include HTML.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['suffix'] = array(
+        '#title' => t('Suffix text'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['suffix'],
+        '#description' => t('Any text to display after this link. You may include HTML.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['target'] = array(
+        '#title' => t('Target'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['target'],
+        '#description' => t("Target of the link, such as _blank, _parent or an iframe's name. This field is rarely used."),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+
+      // Get a list of the available fields and arguments for token replacement.
+      $options = array();
+      foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
+        $options[t('Fields')]["[$field]"] = $handler->ui_name();
+        // We only use fields up to (and including) this one.
+        if ($field == $this->options['id']) {
+          break;
+        }
+      }
+      $count = 0; // This lets us prepare the key as we want it printed.
+      foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+        $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
+        $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
+      }
+
+      $this->document_self_tokens($options[t('Fields')]);
+
+      // Default text.
+      $output = t('<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
+      // We have some options, so make a list.
+      if (!empty($options)) {
+        $output = t('<p>The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.
+If you would like to have the characters \'[\' and \']\' please use the html entity codes \'%5B\' or  \'%5D\' or they will get replaced with empty space.</p>');
+        foreach (array_keys($options) as $type) {
+          if (!empty($options[$type])) {
+            $items = array();
+            foreach ($options[$type] as $key => $value) {
+              $items[] = $key . ' == ' . $value;
+            }
+            $output .= theme('item_list',
+              array(
+                'items' => $items,
+                'type' => $type
+              ));
+          }
+        }
+      }
+      // This construct uses 'hidden' and not markup because process doesn't
+      // run. It also has an extra div because the dependency wants to hide
+      // the parent in situations like this, so we need a second div to
+      // make this work.
+      $form['alter']['help'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Replacement patterns'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#value' => $output,
+        '#states' => array(
+          'visible' => array(
+            array(
+              ':input[name="options[alter][make_link]"]' => array('checked' => TRUE),
+            ),
+            array(
+              ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE),
+            ),
+            array(
+              ':input[name="options[alter][more_link]"]' => array('checked' => TRUE),
+            ),
+          ),
+        ),
+      );
+
+      $form['alter']['trim'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Trim this field to a maximum length'),
+        '#description' => t('Enable to trim the field to a maximum length of characters'),
+        '#default_value' => $this->options['alter']['trim'],
+      );
+
+      $form['alter']['max_length'] = array(
+        '#title' => t('Maximum length'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['max_length'],
+        '#description' => t('The maximum number of characters this field can be.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['word_boundary'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Trim only on a word boundary'),
+        '#description' => t('If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing.'),
+        '#default_value' => $this->options['alter']['word_boundary'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['ellipsis'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Add an ellipsis'),
+        '#description' => t('If checked, a "..." will be added if a field was trimmed.'),
+        '#default_value' => $this->options['alter']['ellipsis'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['more_link'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Add a read-more link if output is trimmed.'),
+        '#description' => t('If checked, a read-more link will be added at the end of the trimmed output'),
+        '#default_value' => $this->options['alter']['more_link'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['more_link_text'] = array(
+        '#type' => 'textfield',
+        '#title' => t('More link text'),
+        '#default_value' => $this->options['alter']['more_link_text'],
+        '#description' => t('The text which will be displayed on the more link. You may enter data from this view as per the "Replacement patterns" above.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+            ':input[name="options[alter][more_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $form['alter']['more_link_path'] = array(
+        '#type' => 'textfield',
+        '#title' => t('More link path'),
+        '#default_value' => $this->options['alter']['more_link_path'],
+        '#description' => t('The path which is used for the more link. You may enter data from this view as per the "Replacement patterns" above.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+            ':input[name="options[alter][more_link]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['html'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Field can contain HTML'),
+        '#description' => t('If checked, HTML corrector will be run to ensure tags are properly closed after trimming.'),
+        '#default_value' => $this->options['alter']['html'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][trim]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['strip_tags'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Strip HTML tags'),
+        '#description' => t('If checked, all HTML tags will be stripped.'),
+        '#default_value' => $this->options['alter']['strip_tags'],
+      );
+
+      $form['alter']['preserve_tags'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Preserve certain tags'),
+        '#description' => t('List the tags that need to be preserved during the stripping process. example &quot;&lt;p&gt; &lt;br&gt;&quot; which will preserve all p and br elements'),
+        '#default_value' => $this->options['alter']['preserve_tags'],
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[alter][strip_tags]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+
+      $form['alter']['trim_whitespace'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Remove whitespace'),
+        '#description' => t('If checked, all whitespaces at the beginning and the end of the output will be removed.'),
+        '#default_value' => $this->options['alter']['trim_whitespace'],
+      );
+
+      $form['alter']['nl2br'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Convert newlines to HTML &lt;br&gt; tags'),
+        '#description' => t('If checked, all newlines chars (e.g. \n) are converted into HTML &lt;br&gt; tags.'),
+        '#default_value' => $this->options['alter']['nl2br'],
+      );
+    }
+
+    $form['empty_field_behavior'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('No results behavior'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => 100,
+    );
+
+    $form['empty'] = array(
+      '#type' => 'textarea',
+      '#title' => t('No results text'),
+      '#default_value' => $this->options['empty'],
+      '#description' => t('Provide text to display if this field returns no results. You may include HTML. You may enter data from this view as per the "Replacement patterns" in the "Rewrite Results" section below.'),
+      '#fieldset' => 'empty_field_behavior',
+    );
+
+    $form['empty_zero'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Count the number 0 as empty'),
+      '#default_value' => $this->options['empty_zero'],
+      '#description' => t('Enable to display the "no results text" if the field contains the number 0.'),
+      '#fieldset' => 'empty_field_behavior',
+    );
+
+    $form['hide_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide if empty'),
+      '#default_value' => $this->options['hide_empty'],
+      '#description' => t('Enable to hide this field if it is empty. Note that the field label or rewritten output may still be displayed. To hide labels, check the style or row style settings for empty fields. To hide rewritten content, check the "Hide rewriting if empty" checkbox.'),
+      '#fieldset' => 'empty_field_behavior',
+    );
+
+    $form['hide_alter_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide rewriting if empty'),
+      '#default_value' => $this->options['hide_alter_empty'],
+      '#description' => t('Do not display rewritten content if this field is empty.'),
+      '#fieldset' => 'empty_field_behavior',
+    );
+  }
+
+  /**
+   * Provide extra data to the administration form
+   */
+  function admin_summary() {
+    return $this->label();
+  }
+
+  /**
+   * Run before any fields are rendered.
+   *
+   * This gives the handlers some time to set up before any handler has
+   * been rendered.
+   *
+   * @param $values
+   *   An array of all objects returned from the query.
+   */
+  function pre_render(&$values) { }
+
+  /**
+   * Render the field.
+   *
+   * @param $values
+   *   The values retrieved from the database.
+   */
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->sanitize_value($value);
+  }
+
+  /**
+   * Render a field using advanced settings.
+   *
+   * This renders a field normally, then decides if render-as-link and
+   * text-replacement rendering is necessary.
+   */
+  function advanced_render($values) {
+    if ($this->allow_advanced_render() && method_exists($this, 'render_item')) {
+      $raw_items = $this->get_items($values);
+      // If there are no items, set the original value to NULL.
+      if (empty($raw_items)) {
+        $this->original_value = NULL;
+      }
+    }
+    else {
+      $value = $this->render($values);
+      if (is_array($value)) {
+        $value = drupal_render($value);
+      }
+      $this->last_render = $value;
+      $this->original_value = $value;
+    }
+
+    if ($this->allow_advanced_render()) {
+      $tokens = NULL;
+      if (method_exists($this, 'render_item')) {
+        $items = array();
+        foreach ($raw_items as $count => $item) {
+          $value = $this->render_item($count, $item);
+          if (is_array($value)) {
+            $value = drupal_render($value);
+          }
+          $this->last_render = $value;
+          $this->original_value = $this->last_render;
+
+          $alter = $item + $this->options['alter'];
+          $alter['phase'] = VIEWS_HANDLER_RENDER_TEXT_PHASE_SINGLE_ITEM;
+          $items[] = $this->render_text($alter);
+        }
+
+        $value = $this->render_items($items);
+      }
+      else {
+        $alter = array('phase' => VIEWS_HANDLER_RENDER_TEXT_PHASE_COMPLETELY) + $this->options['alter'];
+        $value = $this->render_text($alter);
+      }
+
+      if (is_array($value)) {
+        $value = drupal_render($value);
+      }
+      // This happens here so that render_as_link can get the unaltered value of
+      // this field as a token rather than the altered value.
+      $this->last_render = $value;
+    }
+
+    if (empty($this->last_render)) {
+      if ($this->is_value_empty($this->last_render, $this->options['empty_zero'], FALSE)) {
+        $alter = $this->options['alter'];
+        $alter['alter_text'] = 1;
+        $alter['text'] = $this->options['empty'];
+        $alter['phase'] = VIEWS_HANDLER_RENDER_TEXT_PHASE_EMPTY;
+        $this->last_render = $this->render_text($alter);
+      }
+    }
+
+    return $this->last_render;
+  }
+
+  /**
+   * Checks if a field value is empty.
+   *
+   * @param $value
+   *   The field value.
+   * @param bool $empty_zero
+   *   Whether or not this field is configured to consider 0 as empty.
+   * @param bool $no_skip_empty
+   *   Whether or not to use empty() to check the value.
+   *
+   * @return bool
+   * TRUE if the value is considered empty, FALSE otherwise.
+   */
+  function is_value_empty($value, $empty_zero, $no_skip_empty = TRUE) {
+    if (!isset($value)) {
+      $empty = TRUE;
+    }
+    else {
+      $empty = ($empty_zero || ($value !== 0 && $value !== '0'));
+    }
+
+    if ($no_skip_empty) {
+      $empty = empty($value) && $empty;
+    }
+    return $empty;
+  }
+
+  /**
+   * Perform an advanced text render for the item.
+   *
+   * This is separated out as some fields may render lists, and this allows
+   * each item to be handled individually.
+   */
+  function render_text($alter) {
+    $value = $this->last_render;
+
+    if (!empty($alter['alter_text']) && $alter['text'] !== '') {
+      $tokens = $this->get_render_tokens($alter);
+      $value = $this->render_altered($alter, $tokens);
+    }
+
+    if (!empty($this->options['alter']['trim_whitespace'])) {
+      $value = trim($value);
+    }
+
+    // Check if there should be no further rewrite for empty values.
+    $no_rewrite_for_empty = $this->options['hide_alter_empty'] && $this->is_value_empty($this->original_value, $this->options['empty_zero']);
+
+    // Check whether the value is empty and return nothing, so the field isn't rendered.
+    // First check whether the field should be hidden if the value(hide_alter_empty = TRUE) /the rewrite is empty (hide_alter_empty = FALSE).
+    // For numeric values you can specify whether "0"/0 should be empty.
+    if ((($this->options['hide_empty'] && empty($value))
+        || ($alter['phase'] != VIEWS_HANDLER_RENDER_TEXT_PHASE_EMPTY && $no_rewrite_for_empty))
+      && $this->is_value_empty($value, $this->options['empty_zero'], FALSE)) {
+      return '';
+    }
+    // Only in empty phase.
+    if ($alter['phase'] == VIEWS_HANDLER_RENDER_TEXT_PHASE_EMPTY && $no_rewrite_for_empty) {
+      // If we got here then $alter contains the value of "No results text"
+      // and so there is nothing left to do.
+      return $value;
+    }
+
+    if (!empty($alter['strip_tags'])) {
+      $value = strip_tags($value, $alter['preserve_tags']);
+    }
+
+    $suffix = '';
+    if (!empty($alter['trim']) && !empty($alter['max_length'])) {
+      $length = strlen($value);
+      $value = $this->render_trim_text($alter, $value);
+      if ($this->options['alter']['more_link'] && strlen($value) < $length) {
+        $tokens = $this->get_render_tokens($alter);
+        $more_link_text = $this->options['alter']['more_link_text'] ? $this->options['alter']['more_link_text'] : t('more');
+        $more_link_text = strtr(filter_xss_admin($more_link_text), $tokens);
+        $more_link_path = $this->options['alter']['more_link_path'];
+        $more_link_path = strip_tags(decode_entities(strtr($more_link_path, $tokens)));
+
+        // Take sure that paths which was runned through url() does work as well.
+        $base_path = base_path();
+        // Checks whether the path starts with the base_path.
+        if (strpos($more_link_path, $base_path) === 0) {
+          $more_link_path = drupal_substr($more_link_path, drupal_strlen($base_path));
+        }
+
+        $more_link = l($more_link_text, $more_link_path);
+
+        $suffix .= " " . $more_link;
+      }
+    }
+
+    if (!empty($alter['nl2br'])) {
+      $value = nl2br($value);
+    }
+    $this->last_render_text = $value;
+
+    if (!empty($alter['make_link']) && !empty($alter['path'])) {
+      if (!isset($tokens)) {
+       $tokens = $this->get_render_tokens($alter);
+      }
+      $value = $this->render_as_link($alter, $value, $tokens);
+    }
+
+    return $value . $suffix;
+  }
+
+  /**
+   * Render this field as altered text, from a fieldset set by the user.
+   */
+  function render_altered($alter, $tokens) {
+    // Filter this right away as our substitutions are already sanitized.
+    $value = filter_xss_admin($alter['text']);
+    $value = strtr($value, $tokens);
+
+    return $value;
+  }
+
+  /**
+   * Trim the field down to the specified length.
+   */
+  function render_trim_text($alter, $value) {
+    if (!empty($alter['strip_tags'])) {
+      // NOTE: It's possible that some external fields might override the
+      // element type so if someone from, say, CCK runs into a bug here,
+      // this may be why =)
+      $this->definition['element type'] = 'span';
+    }
+    return views_trim_text($alter, $value);
+  }
+
+  /**
+   * Render this field as a link, with the info from a fieldset set by
+   * the user.
+   */
+  function render_as_link($alter, $text, $tokens) {
+    $value = '';
+
+    if (!empty($alter['prefix'])) {
+      $value .= filter_xss_admin(strtr($alter['prefix'], $tokens));
+    }
+
+    $options = array(
+      'html' => TRUE,
+      'absolute' => !empty($alter['absolute']) ? TRUE : FALSE,
+    );
+
+    // $path will be run through check_url() by l() so we do not need to
+    // sanitize it ourselves.
+    $path = $alter['path'];
+
+    // strip_tags() removes <front>, so check whether its different to front.
+    if ($path != '<front>') {
+      // Use strip tags as there should never be HTML in the path.
+      // However, we need to preserve special characters like " that
+      // were removed by check_plain().
+      $path = strip_tags(decode_entities(strtr($path, $tokens)));
+
+      if (!empty($alter['path_case']) && $alter['path_case'] != 'none') {
+        $path = $this->case_transform($path, $this->options['alter']['path_case']);
+      }
+
+      if (!empty($alter['replace_spaces'])) {
+        $path = str_replace(' ', '-', $path);
+      }
+    }
+
+    // Parse the URL and move any query and fragment parameters out of the path.
+    $url = parse_url($path);
+
+    // Seriously malformed URLs may return FALSE or empty arrays.
+    if (empty($url)) {
+      return $text;
+    }
+
+    // If the path is empty do not build a link around the given text and return
+    // it as is.
+    // http://www.example.com URLs will not have a $url['path'], so check host as well.
+    if (empty($url['path']) && empty($url['host']) && empty($url['fragment'])) {
+      return $text;
+    }
+
+    // If no scheme is provided in the $path, assign the default 'http://'.
+    // This allows a url of 'www.example.com' to be converted to 'http://www.example.com'.
+    // Only do this on for external URLs.
+    if ($alter['external']){
+      if (!isset($url['scheme'])) {
+        // There is no scheme, add the default 'http://' to the $path.
+        $path = "http://$path";
+        // Reset the $url array to include the new scheme.
+        $url = parse_url($path);
+      }
+    }
+
+    if (isset($url['query'])) {
+      $path = strtr($path, array('?' . $url['query'] => ''));
+      $query = drupal_get_query_array($url['query']);
+      // Remove query parameters that were assigned a query string replacement
+      // token for which there is no value available.
+      foreach ($query as $param => $val) {
+        if ($val == '%' . $param) {
+          unset($query[$param]);
+        }
+      }
+      $options['query'] = $query;
+    }
+    if (isset($url['fragment'])) {
+      $path = strtr($path, array('#' . $url['fragment'] => ''));
+      // If the path is empty we want to have a fragment for the current site.
+      if ($path == '') {
+        $options['external'] = TRUE;
+      }
+      $options['fragment'] = $url['fragment'];
+    }
+
+    $alt = strtr($alter['alt'], $tokens);
+    // Set the title attribute of the link only if it improves accessibility
+    if ($alt && $alt != $text) {
+      $options['attributes']['title'] = decode_entities($alt);
+    }
+
+    $class = strtr($alter['link_class'], $tokens);
+    if ($class) {
+      $options['attributes']['class'] = array($class);
+    }
+
+    if (!empty($alter['rel']) && $rel = strtr($alter['rel'], $tokens)) {
+      $options['attributes']['rel'] = $rel;
+    }
+
+    $target = check_plain(trim(strtr($alter['target'],$tokens)));
+    if (!empty($target)) {
+      $options['attributes']['target'] = $target;
+    }
+
+    // Allow the addition of arbitrary attributes to links. Additional attributes
+    // currently can only be altered in preprocessors and not within the UI.
+    if (isset($alter['link_attributes']) && is_array($alter['link_attributes'])) {
+      foreach ($alter['link_attributes'] as $key => $attribute) {
+        if (!isset($options['attributes'][$key])) {
+          $options['attributes'][$key] = strtr($attribute, $tokens);
+        }
+      }
+    }
+
+    // If the query and fragment were programatically assigned overwrite any
+    // parsed values.
+    if (isset($alter['query'])) {
+      // Convert the query to a string, perform token replacement, and then
+      // convert back to an array form for l().
+      $options['query'] = drupal_http_build_query($alter['query']);
+      $options['query'] = strtr($options['query'], $tokens);
+      $options['query'] = drupal_get_query_array($options['query']);
+    }
+    if (isset($alter['alias'])) {
+      // Alias is a boolean field, so no token.
+      $options['alias'] = $alter['alias'];
+    }
+    if (isset($alter['fragment'])) {
+      $options['fragment'] = strtr($alter['fragment'], $tokens);
+    }
+    if (isset($alter['language'])) {
+      $options['language'] = $alter['language'];
+    }
+
+    // If the url came from entity_uri(), pass along the required options.
+    if (isset($alter['entity'])) {
+      $options['entity'] = $alter['entity'];
+    }
+    if (isset($alter['entity_type'])) {
+      $options['entity_type'] = $alter['entity_type'];
+    }
+
+    $value .= l($text, $path, $options);
+
+    if (!empty($alter['suffix'])) {
+      $value .= filter_xss_admin(strtr($alter['suffix'], $tokens));
+    }
+
+    return $value;
+  }
+
+  /**
+   * Get the 'render' tokens to use for advanced rendering.
+   *
+   * This runs through all of the fields and arguments that
+   * are available and gets their values. This will then be
+   * used in one giant str_replace().
+   */
+  function get_render_tokens($item) {
+    $tokens = array();
+    if (!empty($this->view->build_info['substitutions'])) {
+      $tokens = $this->view->build_info['substitutions'];
+    }
+    $count = 0;
+    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+      $token = '%' . ++$count;
+      if (!isset($tokens[$token])) {
+        $tokens[$token] = '';
+      }
+
+      // Use strip tags as there should never be HTML in the path.
+      // However, we need to preserve special characters like " that
+      // were removed by check_plain().
+      $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(decode_entities($this->view->args[$count - 1])) : '';
+    }
+
+    // Get flattened set of tokens for any array depth in $_GET parameters.
+    $tokens += $this->get_token_values_recursive($_GET);
+
+    // Now add replacements for our fields.
+    foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
+      if (isset($handler->last_render)) {
+        $tokens["[$field]"] = $handler->last_render;
+      }
+      else {
+        $tokens["[$field]"] = '';
+      }
+      if (!empty($item)) {
+        $this->add_self_tokens($tokens, $item);
+      }
+
+      // We only use fields up to (and including) this one.
+      if ($field == $this->options['id']) {
+        break;
+      }
+    }
+
+    // Store the tokens for the row so we can reference them later if necessary.
+    $this->view->style_plugin->render_tokens[$this->view->row_index] = $tokens;
+    $this->last_tokens = $tokens;
+
+    return $tokens;
+  }
+
+  /**
+   * Recursive function to add replacements for nested query string parameters.
+   *
+   * E.g. if you pass in the following array:
+   *   array(
+   *     'foo' => array(
+   *       'a' => 'value',
+   *       'b' => 'value',
+   *     ),
+   *     'bar' => array(
+   *       'a' => 'value',
+   *       'b' => array(
+   *         'c' => value,
+   *       ),
+   *     ),
+   *   );
+   *
+   * Would yield the following array of tokens:
+   *   array(
+   *     '%foo_a' => 'value'
+   *     '%foo_b' => 'value'
+   *     '%bar_a' => 'value'
+   *     '%bar_b_c' => 'value'
+   *   );
+   *
+   * @param $array
+   *   An array of values.
+   *
+   * @param $parent_keys
+   *   An array of parent keys. This will represent the array depth.
+   *
+   * @return
+   *   An array of available tokens, with nested keys representative of the array structure.
+   */
+  function get_token_values_recursive(array $array, array $parent_keys = array()) {
+    $tokens = array();
+
+    foreach ($array as $param => $val) {
+      if (is_array($val)) {
+         // Copy parent_keys array, so we don't afect other elements of this iteration.
+         $child_parent_keys = $parent_keys;
+         $child_parent_keys[] = $param;
+         // Get the child tokens.
+         $child_tokens = $this->get_token_values_recursive($val, $child_parent_keys);
+         // Add them to the current tokens array.
+         $tokens += $child_tokens;
+      }
+      else {
+        // Create a token key based on array element structure.
+        $token_string = !empty($parent_keys) ? implode('_', $parent_keys) . '_' . $param : $param;
+        $tokens['%' . $token_string] = strip_tags(decode_entities($val));
+      }
+    }
+
+    return $tokens;
+  }
+
+  /**
+   * Add any special tokens this field might use for itself.
+   *
+   * This method is intended to be overridden by items that generate
+   * fields as a list. For example, the field that displays all terms
+   * on a node might have tokens for the tid and the term.
+   *
+   * By convention, tokens should follow the format of [token-subtoken]
+   * where token is the field ID and subtoken is the field. If the
+   * field ID is terms, then the tokens might be [terms-tid] and [terms-name].
+   */
+  function add_self_tokens(&$tokens, $item) { }
+
+  /**
+   * Document any special tokens this field might use for itself.
+   *
+   * @see add_self_tokens()
+   */
+  function document_self_tokens(&$tokens) { }
+
+  /**
+   * Call out to the theme() function, which probably just calls render() but
+   * allows sites to override output fairly easily.
+   */
+  function theme($values) {
+    return theme($this->theme_functions(),
+      array(
+        'view' => $this->view,
+        'field' => $this,
+        'row' => $values
+      ));
+  }
+
+  function theme_functions() {
+    $themes = array();
+    $hook = 'views_view_field';
+
+    $display = $this->view->display[$this->view->current_display];
+
+    if (!empty($display)) {
+      $themes[] = $hook . '__' . $this->view->name  . '__' . $display->id . '__' . $this->options['id'];
+      $themes[] = $hook . '__' . $this->view->name  . '__' . $display->id;
+      $themes[] = $hook . '__' . $display->id . '__' . $this->options['id'];
+      $themes[] = $hook . '__' . $display->id;
+      if ($display->id != $display->display_plugin) {
+        $themes[] = $hook . '__' . $this->view->name  . '__' . $display->display_plugin . '__' . $this->options['id'];
+        $themes[] = $hook . '__' . $this->view->name  . '__' . $display->display_plugin;
+        $themes[] = $hook . '__' . $display->display_plugin . '__' . $this->options['id'];
+        $themes[] = $hook . '__' . $display->display_plugin;
+      }
+    }
+    $themes[] = $hook . '__' . $this->view->name . '__' . $this->options['id'];
+    $themes[] = $hook . '__' . $this->view->name;
+    $themes[] = $hook . '__' . $this->options['id'];
+    $themes[] = $hook;
+
+    return $themes;
+  }
+
+  function ui_name($short = FALSE) {
+    return $this->get_field(parent::ui_name($short));
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_broken extends views_handler_field {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query($group_by = FALSE) { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+/**
+ * Render a numeric value as a size.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_file_size extends views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['file_size_display'] = array('default' => 'formatted');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['file_size_display'] = array(
+      '#title' => t('File size display'),
+      '#type' => 'select',
+      '#options' => array(
+        'formatted' => t('Formatted (in KB or MB)'),
+        'bytes' => t('Raw bytes'),
+      ),
+    );
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if ($value) {
+      switch ($this->options['file_size_display']) {
+        case 'bytes':
+          return $value;
+        case 'formatted':
+        default:
+          return format_size($value);
+      }
+    }
+    else {
+      return '';
+    }
+  }
+}
+
+/**
+ * A handler to run a field through simple XSS filtering.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_xss extends views_handler_field {
+  function render($values) {
+    $value = $this->get_value($values);
+    return $this->sanitize_value($value, 'xss');
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/field/MachineNameField.php b/lib/Drupal/views/Plugins/views/field/MachineNameField.php
new file mode 100644
index 0000000..32949c5
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/MachineNameField.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\MachineNameField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Field handler whichs allows to show machine name content as human name.
+ * @ingroup views_field_handlers
+ *
+ * Definition items:
+ * - options callback: The function to call in order to generate the value options. If omitted, the options 'Yes' and 'No' will be used.
+ * - options arguments: An array of arguments to pass to the options callback.
+ */
+class MachineNameField extends FieldPlugin {
+  /**
+   * @var array Stores the available options.
+   */
+  var $value_options;
+
+  function get_value_options() {
+    if (isset($this->value_options)) {
+      return;
+    }
+
+    if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) {
+      if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) {
+        $this->value_options = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']);
+      }
+      else {
+        $this->value_options = call_user_func($this->definition['options callback']);
+      }
+    }
+    else {
+      $this->value_options = array();
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['machine_name'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['machine_name'] = array(
+      '#title' => t('Output machine name'),
+      '#description' => t('Display field as machine name.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['machine_name']),
+    );
+  }
+
+  function pre_render(&$values) {
+    $this->get_value_options();
+  }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+    if (!empty($this->options['machine_name']) || !isset($this->value_options[$value])) {
+      $result = check_plain($value);
+    }
+    else {
+      $result = $this->value_options[$value];
+    }
+
+    return $result;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/MarkupField.php b/lib/Drupal/views/Plugins/views/field/MarkupField.php
new file mode 100644
index 0000000..06e17a0
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/MarkupField.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\MarkupField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to run a field through check_markup, using a companion
+ * format field.
+ *
+ * - format: (REQUIRED) Either a string format id to use for this field or an
+ *           array('field' => {$field}) where $field is the field in this table
+ *           used to control the format such as the 'format' field in the node,
+ *           which goes with the 'body' field.
+ *
+ * @ingroup views_field_handlers
+ */
+class MarkupField extends FieldPlugin {
+  /**
+   * Constructor; calls to base object constructor.
+   */
+  function construct() {
+    parent::construct();
+
+    $this->format = $this->definition['format'];
+
+    $this->additional_fields = array();
+    if (is_array($this->format)) {
+      $this->additional_fields['format'] = $this->format;
+    }
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (is_array($this->format)) {
+      $format = $this->get_value($values, 'format');
+    }
+    else {
+      $format = $this->format;
+    }
+    if ($value) {
+      $value = str_replace('<!--break-->', '', $value);
+      return check_markup($value, $format, '');
+    }
+  }
+
+  function element_type($none_supported = FALSE, $default_empty = FALSE, $inline = FALSE) {
+    if ($inline) {
+      return 'span';
+    }
+
+    if (isset($this->definition['element type'])) {
+      return $this->definition['element type'];
+    }
+
+    return 'div';
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/Mathfield.php b/lib/Drupal/views/Plugins/views/field/Mathfield.php
new file mode 100644
index 0000000..7cbd25d
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/Mathfield.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\Mathfield.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Render a mathematical expression as a numeric value
+ *
+ * Definition terms:
+ * - float: If true this field contains a decimal value. If unset this field
+ *   will be assumed to be integer.
+ *
+ * @ingroup views_field_handlers
+ */
+class Mathfield extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['expression'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['expression'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Expression'),
+      '#description' => t('Enter mathematical expressions such as 2 + 2 or sqrt(5). You may assign variables and create mathematical functions and evaluate them. Use the ; to separate these. For example: f(x) = x + 2; f(2).'),
+      '#default_value' => $this->options['expression'],
+    );
+
+    // Create a place for the help
+    $form['expression_help'] = array();
+    parent::options_form($form, $form_state);
+
+    // Then move the existing help:
+    $form['expression_help'] = $form['alter']['help'];
+    unset($form['expression_help']['#states']);
+    unset($form['alter']['help']);
+  }
+
+  function render($values) {
+    ctools_include('math-expr');
+    $tokens = array_map('floatval', $this->get_render_tokens(array()));
+    $value = strtr($this->options['expression'], $tokens);
+    $expressions = explode(';', $value);
+    $math = new ctools_math_expr;
+    foreach ($expressions as $expression) {
+      if ($expression !== '') {
+        $value = $math->evaluate($expression);
+      }
+    }
+
+    // The rest is directly from views_handler_field_numeric but because it
+    // does not allow the value to be passed in, it is copied.
+    if (!empty($this->options['set_precision'])) {
+      $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']);
+    }
+    else {
+      $remainder = abs($value) - intval(abs($value));
+      $value = $value > 0 ? floor($value) : ceil($value);
+      $value = number_format($value, 0, '', $this->options['separator']);
+      if ($remainder) {
+        // The substr may not be locale safe.
+        $value .= $this->options['decimal'] . substr($remainder, 2);
+      }
+    }
+
+    // Check to see if hiding should happen before adding prefix and suffix.
+    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
+      return '';
+    }
+
+    // Should we format as a plural.
+    if (!empty($this->options['format_plural']) && ($value != 0 || !$this->options['empty_zero'])) {
+      $value = format_plural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']);
+    }
+
+    return $this->sanitize_value($this->options['prefix'] . $value . $this->options['suffix']);
+  }
+
+  function query() { }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/NumericField.php b/lib/Drupal/views/Plugins/views/field/NumericField.php
new file mode 100644
index 0000000..d1a10e4
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/NumericField.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\NumericField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Render a field as a numeric value
+ *
+ * Definition terms:
+ * - float: If true this field contains a decimal value. If unset this field
+ *          will be assumed to be integer.
+ *
+ * @ingroup views_field_handlers
+ */
+class NumericField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['set_precision'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['precision'] = array('default' => 0);
+    $options['decimal'] = array('default' => '.', 'translatable' => TRUE);
+    $options['separator'] = array('default' => ',', 'translatable' => TRUE);
+    $options['format_plural'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['format_plural_singular'] = array('default' => '1');
+    $options['format_plural_plural'] = array('default' => '@count');
+    $options['prefix'] = array('default' => '', 'translatable' => TRUE);
+    $options['suffix'] = array('default' => '', 'translatable' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    if (!empty($this->definition['float'])) {
+      $form['set_precision'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Round'),
+        '#description' => t('If checked, the number will be rounded.'),
+        '#default_value' => $this->options['set_precision'],
+      );
+      $form['precision'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Precision'),
+        '#default_value' => $this->options['precision'],
+        '#description' => t('Specify how many digits to print after the decimal point.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[set_precision]"]' => array('checked' => TRUE),
+          ),
+        ),
+        '#size' => 2,
+      );
+      $form['decimal'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Decimal point'),
+        '#default_value' => $this->options['decimal'],
+        '#description' => t('What single character to use as a decimal point.'),
+        '#size' => 2,
+      );
+    }
+    $form['separator'] = array(
+      '#type' => 'select',
+      '#title' => t('Thousands marker'),
+      '#options' => array(
+        '' => t('- None -'),
+        ',' => t('Comma'),
+        ' ' => t('Space'),
+        '.' => t('Decimal'),
+        '\'' => t('Apostrophe'),
+      ),
+      '#default_value' => $this->options['separator'],
+      '#description' => t('What single character to use as the thousands separator.'),
+      '#size' => 2,
+    );
+    $form['format_plural'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Format plural'),
+      '#description' => t('If checked, special handling will be used for plurality.'),
+      '#default_value' => $this->options['format_plural'],
+    );
+    $form['format_plural_singular'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Singular form'),
+      '#default_value' => $this->options['format_plural_singular'],
+      '#description' => t('Text to use for the singular form.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[format_plural]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    $form['format_plural_plural'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Plural form'),
+      '#default_value' => $this->options['format_plural_plural'],
+      '#description' => t('Text to use for the plural form, @count will be replaced with the value.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[format_plural]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    $form['prefix'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Prefix'),
+      '#default_value' => $this->options['prefix'],
+      '#description' => t('Text to put before the number, such as currency symbol.'),
+    );
+    $form['suffix'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Suffix'),
+      '#default_value' => $this->options['suffix'],
+      '#description' => t('Text to put after the number, such as currency symbol.'),
+    );
+
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (!empty($this->options['set_precision'])) {
+      $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']);
+    }
+    else {
+      $remainder = abs($value) - intval(abs($value));
+      $value = $value > 0 ? floor($value) : ceil($value);
+      $value = number_format($value, 0, '', $this->options['separator']);
+      if ($remainder) {
+        // The substr may not be locale safe.
+        $value .= $this->options['decimal'] . substr($remainder, 2);
+      }
+    }
+
+    // Check to see if hiding should happen before adding prefix and suffix.
+    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
+      return '';
+    }
+
+    // Should we format as a plural.
+    if (!empty($this->options['format_plural'])) {
+      $value = format_plural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']);
+    }
+
+    return $this->sanitize_value($this->options['prefix'], 'xss')
+      . $this->sanitize_value($value)
+      . $this->sanitize_value($this->options['suffix'], 'xss');
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/PrerenderListField.php b/lib/Drupal/views/Plugins/views/field/PrerenderListField.php
new file mode 100644
index 0000000..58071b1
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/PrerenderListField.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\PrerenderListField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Field handler to provide a list of items.
+ *
+ * The items are expected to be loaded by a child object during pre_render,
+ * and 'my field' is expected to be the pointer to the items in the list.
+ *
+ * Items to render should be in a list in $this->items
+ *
+ * @ingroup views_field_handlers
+ */
+class PrerenderListField extends FieldPlugin {
+  /**
+   * Stores all items which are used to render the items.
+   * It should be keyed first by the id of the base table, for example nid.
+   * The second key is the id of the thing which is displayed multiple times
+   * per row, for example the tid.
+   *
+   * @var array
+   */
+  var $items = array();
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['type'] = array('default' => 'separator');
+    $options['separator'] = array('default' => ', ');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Display type'),
+      '#options' => array(
+        'ul' => t('Unordered list'),
+        'ol' => t('Ordered list'),
+        'separator' => t('Simple separator'),
+      ),
+      '#default_value' => $this->options['type'],
+    );
+
+    $form['separator'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Separator'),
+      '#default_value' => $this->options['separator'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[type]"]' => array('value' => 'separator'),
+        ),
+      ),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  /**
+   * Render the field.
+   *
+   * This function is deprecated, but left in for older systems that have not
+   * yet or won't update their prerender list fields. If a render_item method
+   * exists, this will not get used by advanced_render.
+   */
+  function render($values) {
+    $field = $this->get_value($values);
+    if (!empty($this->items[$field])) {
+      if ($this->options['type'] == 'separator') {
+        return implode($this->sanitize_value($this->options['separator']), $this->items[$field]);
+      }
+      else {
+        return theme('item_list',
+          array(
+            'items' => $this->items[$field],
+            'title' => NULL,
+            'type' => $this->options['type']
+          ));
+      }
+    }
+  }
+
+  /**
+   * Render all items in this field together.
+   *
+   * When using advanced render, each possible item in the list is rendered
+   * individually. Then the items are all pasted together.
+   */
+  function render_items($items) {
+    if (!empty($items)) {
+      if ($this->options['type'] == 'separator') {
+        return implode($this->sanitize_value($this->options['separator'], 'xss_admin'), $items);
+      }
+      else {
+        return theme('item_list',
+          array(
+            'items' => $items,
+            'title' => NULL,
+            'type' => $this->options['type']
+          ));
+      }
+    }
+  }
+
+  /**
+   * Return an array of items for the field.
+   *
+   * Items should be stored in the result array, if possible, as an array
+   * with 'value' as the actual displayable value of the item, plus
+   * any items that might be found in the 'alter' options array for
+   * creating links, such as 'path', 'fragment', 'query' etc, such a thing
+   * is to be made. Additionally, items that might be turned into tokens
+   * should also be in this array.
+   */
+  function get_items($values) {
+    // Only the parent get_value returns a single field.
+    $field = parent::get_value($values);
+    if (!empty($this->items[$field])) {
+      return $this->items[$field];
+    }
+
+    return array();
+  }
+
+  /**
+   * Get the value that's supposed to be rendered.
+   *
+   * @param $values
+   *   An object containing all retrieved values.
+   * @param $field
+   *   Optional name of the field where the value is stored.
+   * @param $raw
+   *   Use the raw data and not the data defined in pre_render
+   */
+  function get_value($values, $field = NULL, $raw = FALSE) {
+    if ($raw) {
+      return parent::get_value($values, $field);
+    }
+    $item = $this->get_items($values);
+    $item = (array) $item;
+    if (isset($field) && isset($item[$field])) {
+      return $item[$field];
+    }
+    return $item;
+  }
+
+  /**
+   * Determine if advanced rendering is allowed.
+   *
+   * By default, advanced rendering will NOT be allowed if the class
+   * inheriting from this does not implement a 'render_items' method.
+   */
+  function allow_advanced_render() {
+    // Note that the advanced render bits also use the presence of
+    // this method to determine if it needs to render items as a list.
+    return method_exists($this, 'render_item');
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/SerializedField.php b/lib/Drupal/views/Plugins/views/field/SerializedField.php
new file mode 100644
index 0000000..d5490cc
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/SerializedField.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\SerializedField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Field handler to show data of serialized fields.
+ *
+ * @ingroup views_field_handlers
+ */
+class SerializedField extends FieldPlugin {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['format'] = array('default' => 'unserialized');
+    $options['key'] = array('default' => '');
+    return $options;
+  }
+
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['format'] = array(
+      '#type' => 'select',
+      '#title' => t('Display format'),
+      '#description' => t('How should the serialized data be displayed. You can choose a custom array/object key or a print_r on the full output.'),
+      '#options' => array(
+        'unserialized' => t('Full data (unserialized)'),
+        'serialized' => t('Full data (serialized)'),
+        'key' => t('A certain key'),
+      ),
+      '#default_value' => $this->options['format'],
+    );
+    $form['key'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Which key should be displayed'),
+      '#default_value' => $this->options['key'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[format]"]' => array('value' => 'key'),
+        ),
+      ),
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    // Require a key if the format is key.
+    if ($form_state['values']['options']['format'] == 'key' && $form_state['values']['options']['key'] == '') {
+      form_error($form['key'], t('You have to enter a key if you want to display a key of the data.'));
+    }
+  }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+
+    if ($this->options['format'] == 'unserialized') {
+      return check_plain(print_r(unserialize($value), TRUE));
+    }
+    elseif ($this->options['format'] == 'key' && !empty($this->options['key'])) {
+      $value = (array) unserialize($value);
+      return check_plain($value[$this->options['key']]);
+    }
+
+    return $value;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/TimeIntervalField.php b/lib/Drupal/views/Plugins/views/field/TimeIntervalField.php
new file mode 100644
index 0000000..f367afc
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/TimeIntervalField.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\TimeIntervalField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * A handler to provide proper displays for time intervals.
+ *
+ * @ingroup views_field_handlers
+ */
+class TimeIntervalField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['granularity'] = array('default' => 2);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['granularity'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Granularity'),
+      '#description' => t('How many different units to display in the string.'),
+      '#default_value' => $this->options['granularity'],
+    );
+  }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+    return format_interval($value, isset($this->options['granularity']) ? $this->options['granularity'] : 2);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/field/UrlField.php b/lib/Drupal/views/Plugins/views/field/UrlField.php
new file mode 100644
index 0000000..319a4d7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/field/UrlField.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\field\UrlField.
+ */
+
+namespace Drupal\views\Plugins\views\field;
+
+/**
+ * Field handler to provide simple renderer that turns a URL into a clickable link.
+ *
+ * @ingroup views_field_handlers
+ */
+class UrlField extends FieldPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['display_as_link'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide link to the page being visited.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['display_as_link'] = array(
+      '#title' => t('Display as link'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['display_as_link']),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (!empty($this->options['display_as_link'])) {
+      return l($this->sanitize_value($value), $value, array('html' => TRUE));
+    }
+    else {
+      return $this->sanitize_value($value, 'url');
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/BooleanOperatorFilter.php b/lib/Drupal/views/Plugins/views/filter/BooleanOperatorFilter.php
new file mode 100644
index 0000000..5b8303c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/BooleanOperatorFilter.php
@@ -0,0 +1,178 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\BooleanOperatorFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Simple filter to handle matching of boolean values
+ *
+ * Definition items:
+ * - label: (REQUIRED) The label for the checkbox.
+ * - type: For basic 'true false' types, an item can specify the following:
+ *    - true-false: True/false (this is the default)
+ *    - yes-no: Yes/No
+ *    - on-off: On/Off
+ *    - enabled-disabled: Enabled/Disabled
+ * - accept null: Treat a NULL value as false.
+ * - use equal: If you use this flag the query will use = 1 instead of <> 0.
+ *   This might be helpful for performance reasons.
+ *
+ * @ingroup views_filter_handlers
+ */
+class BooleanOperatorFilter extends FilterPlugin {
+  // exposed filter options
+  var $always_multiple = TRUE;
+  // Don't display empty space where the operator would be.
+  var $no_operator = TRUE;
+  // Whether to accept NULL as a false value or not
+  var $accept_null = FALSE;
+
+  function construct() {
+    $this->value_value = t('True');
+    if (isset($this->definition['label'])) {
+      $this->value_value = $this->definition['label'];
+    }
+    if (isset($this->definition['accept null'])) {
+      $this->accept_null = (bool) $this->definition['accept null'];
+    }
+    else if (isset($this->definition['accept_null'])) {
+      $this->accept_null = (bool) $this->definition['accept_null'];
+    }
+    $this->value_options = NULL;
+    parent::construct();
+  }
+
+  /**
+   * Return the possible options for this filter.
+   *
+   * Child classes should override this function to set the possible values
+   * for the filter.  Since this is a boolean filter, the array should have
+   * two possible keys: 1 for "True" and 0 for "False", although the labels
+   * can be whatever makes sense for the filter.  These values are used for
+   * configuring the filter, when the filter is exposed, and in the admin
+   * summary of the filter.  Normally, this should be static data, but if it's
+   * dynamic for some reason, child classes should use a guard to reduce
+   * database hits as much as possible.
+   */
+  function get_value_options() {
+    if (isset($this->definition['type'])) {
+      if ($this->definition['type'] == 'yes-no') {
+        $this->value_options = array(1 => t('Yes'), 0 => t('No'));
+      }
+      if ($this->definition['type'] == 'on-off') {
+        $this->value_options = array(1 => t('On'), 0 => t('Off'));
+      }
+      if ($this->definition['type'] == 'enabled-disabled') {
+        $this->value_options = array(1 => t('Enabled'), 0 => t('Disabled'));
+      }
+    }
+
+    // Provide a fallback if the above didn't set anything.
+    if (!isset($this->value_options)) {
+      $this->value_options = array(1 => t('True'), 0 => t('False'));
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['value']['default'] = FALSE;
+
+    return $options;
+  }
+
+  function operator_form(&$form, &$form_state) {
+    $form['operator'] = array();
+  }
+
+  function value_form(&$form, &$form_state) {
+    if (empty($this->value_options)) {
+      // Initialize the array of possible values for this filter.
+      $this->get_value_options();
+    }
+    if (!empty($form_state['exposed'])) {
+      // Exposed filter: use a select box to save space.
+      $filter_form_type = 'select';
+    }
+    else {
+      // Configuring a filter: use radios for clarity.
+      $filter_form_type = 'radios';
+    }
+    $form['value'] = array(
+      '#type' => $filter_form_type,
+      '#title' => $this->value_value,
+      '#options' => $this->value_options,
+      '#default_value' => $this->value,
+    );
+    if (!empty($this->options['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value;
+      }
+      // If we're configuring an exposed filter, add an <Any> option.
+      if (empty($form_state['exposed']) || empty($this->options['expose']['required'])) {
+        $any_label = config('views.settings')->get('views_exposed_filter_any_label') == 'old_any' ? '<Any>' : t('- Any -');
+        if ($form['value']['#type'] != 'select') {
+          $any_label = check_plain($any_label);
+        }
+        $form['value']['#options'] = array('All' => $any_label) + $form['value']['#options'];
+      }
+    }
+  }
+
+  function value_validate($form, &$form_state) {
+    if ($form_state['values']['options']['value'] == 'All' && !empty($form_state['values']['options']['expose']['required'])) {
+      form_set_error('value', t('You must select a value unless this is an non-required exposed filter.'));
+    }
+  }
+
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+    if (empty($this->value_options)) {
+      $this->get_value_options();
+    }
+    // Now that we have the valid options for this filter, just return the
+    // human-readable label based on the current value.  The value_options
+    // array is keyed with either 0 or 1, so if the current value is not
+    // empty, use the label for 1, and if it's empty, use the label for 0.
+    return $this->value_options[!empty($this->value)];
+  }
+
+  function expose_options() {
+    parent::expose_options();
+    $this->options['expose']['operator_id'] = '';
+    $this->options['expose']['label'] = $this->value_value;
+    $this->options['expose']['required'] = TRUE;
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $field = "$this->table_alias.$this->real_field";
+
+    if (empty($this->value)) {
+      if ($this->accept_null) {
+        $or = db_or()
+          ->condition($field, 0, '=')
+          ->condition($field, NULL, 'IS NULL');
+        $this->query->add_where($this->options['group'], $or);
+      }
+      else {
+        $this->query->add_where($this->options['group'], $field, 0, '=');
+      }
+    }
+    else {
+      if (!empty($this->definition['use equal'])) {
+        $this->query->add_where($this->options['group'], $field, 1, '=');
+      }
+      else {
+        $this->query->add_where($this->options['group'], $field, 0, '<>');
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/BooleanOperatorStringFilter.php b/lib/Drupal/views/Plugins/views/filter/BooleanOperatorStringFilter.php
new file mode 100644
index 0000000..921ec27
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/BooleanOperatorStringFilter.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\BooleanOperatorStringFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Simple filter to handle matching of boolean values.
+ *
+ * This handler checks to see if a string field is empty (equal to '') or not.
+ * It is otherwise identical to the parent operator.
+ *
+ * Definition items:
+ * - label: (REQUIRED) The label for the checkbox.
+ *
+ * @ingroup views_filter_handlers
+ */
+class BooleanOperatorStringFilter extends BooleanOperatorFilter {
+  function query() {
+    $this->ensure_my_table();
+    $where = "$this->table_alias.$this->real_field ";
+
+    if (empty($this->value)) {
+      $where .= "= ''";
+      if ($this->accept_null) {
+        $where = '(' . $where . " OR $this->table_alias.$this->real_field IS NULL)";
+      }
+    }
+    else {
+      $where .= "<> ''";
+    }
+    $this->query->add_where($this->options['group'], $where);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/CombineFilter.php b/lib/Drupal/views/Plugins/views/filter/CombineFilter.php
new file mode 100644
index 0000000..3d57ea7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/CombineFilter.php
@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\CombineFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Filter handler which allows to search on multiple fields.
+ *
+ * @ingroup views_field_handlers
+ */
+class CombineFilter extends StringFilter {
+  /**
+   * @var views_plugin_query_default
+   */
+  var $query;
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['fields'] = array('default' => array());
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $this->view->init_style();
+
+    // Allow to choose all fields as possible
+    if ($this->view->style_plugin->uses_fields()) {
+      $options = array();
+      foreach ($this->view->display_handler->get_handlers('field') as $name => $field) {
+        $options[$name] = $field->ui_name(TRUE);
+      }
+      if ($options) {
+        $form['fields'] = array(
+          '#type' => 'select',
+          '#title' => t('Choose fields to combine for filtering'),
+          '#description' => t("This filter doesn't work for very special field handlers."),
+          '#multiple' => TRUE,
+          '#options' => $options,
+          '#default_value' => $this->options['fields'],
+        );
+      }
+      else {
+        form_set_error('', t('You have to add some fields to be able to use this filter.'));
+      }
+    }
+  }
+
+  function query() {
+    $this->view->_build('field');
+    $fields = array();
+    // Only add the fields if they have a proper field and table alias.
+    foreach ($this->options['fields'] as $id) {
+      $field = $this->view->field[$id];
+      // Always add the table of the selected fields to be sure a table alias exists.
+      $field->ensure_my_table();
+      if (!empty($field->field_alias) && !empty($field->field_alias)) {
+        $fields[] = "$field->table_alias.$field->real_field";
+      }
+    }
+    if ($fields) {
+      $count = count($fields);
+      $seperated_fields = array();
+      foreach ($fields as $key => $field) {
+        $seperated_fields[] = $field;
+        if ($key < $count-1) {
+          $seperated_fields[] = "' '";
+        }
+      }
+      $expression = implode(', ', $seperated_fields);
+      $expression = "CONCAT_WS(' ', $expression)";
+
+      $info = $this->operators();
+      if (!empty($info[$this->operator]['method'])) {
+        $this->{$info[$this->operator]['method']}($expression);
+      }
+    }
+  }
+
+  // By default things like op_equal uses add_where, that doesn't support
+  // complex expressions, so override all operators.
+
+  function op_equal($field) {
+    $placeholder = $this->placeholder();
+    $operator = $this->operator();
+    $this->query->add_where_expression($this->options['group'], "$field $operator $placeholder", array($placeholder => $this->value));
+  }
+
+  function op_contains($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'));
+  }
+
+  function op_starts($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => db_like($this->value) . '%'));
+  }
+
+  function op_not_starts($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => db_like($this->value) . '%'));
+  }
+
+  function op_ends($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value)));
+  }
+
+  function op_not_ends($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value)));
+  }
+
+  function op_not($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'));
+  }
+
+  function op_regex($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "$field RLIKE $placeholder", array($placeholder => $this->value));
+  }
+
+  function op_empty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_where_expression($this->options['group'], "$field $operator");
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/DateFilter.php b/lib/Drupal/views/Plugins/views/filter/DateFilter.php
new file mode 100644
index 0000000..3b73fe7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/DateFilter.php
@@ -0,0 +1,157 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\DateFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Filter to handle dates stored as a timestamp.
+ *
+ * @ingroup views_filter_handlers
+ */
+class DateFilter extends NumericFilter {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    // value is already set up properly, we're just adding our new field to it.
+    $options['value']['contains']['type']['default'] = 'date';
+
+    return $options;
+  }
+
+  /**
+   * Add a type selector to the value form
+   */
+  function value_form(&$form, &$form_state) {
+    if (empty($form_state['exposed'])) {
+      $form['value']['type'] = array(
+        '#type' => 'radios',
+        '#title' => t('Value type'),
+        '#options' => array(
+          'date' => t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'),
+          'offset' => t('An offset from the current time such as "!example1" or "!example2"', array('!example1' => '+1 day', '!example2' => '-2 hours -30 minutes')),
+        ),
+        '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date',
+      );
+    }
+    parent::value_form($form, $form_state);
+  }
+
+  function options_validate(&$form, &$form_state) {
+    parent::options_validate($form, $form_state);
+
+    if (!empty($this->options['exposed']) && empty($form_state['values']['options']['expose']['required'])) {
+      // Who cares what the value is if it's exposed and non-required.
+      return;
+    }
+
+    $this->validate_valid_time($form['value'], $form_state['values']['options']['operator'], $form_state['values']['options']['value']);
+  }
+
+  function exposed_validate(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    if (empty($this->options['expose']['required'])) {
+      // Who cares what the value is if it's exposed and non-required.
+      return;
+    }
+
+    $value = &$form_state['values'][$this->options['expose']['identifier']];
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) {
+      $operator = $form_state['values'][$this->options['expose']['operator_id']];
+    }
+    else {
+      $operator = $this->operator;
+    }
+
+    $this->validate_valid_time($this->options['expose']['identifier'], $operator, $value);
+
+  }
+
+  /**
+   * Validate that the time values convert to something usable.
+   */
+  function validate_valid_time(&$form, $operator, $value) {
+    $operators = $this->operators();
+
+    if ($operators[$operator]['values'] == 1) {
+      $convert = strtotime($value['value']);
+      if (!empty($form['value']) && ($convert == -1 || $convert === FALSE)) {
+        form_error($form['value'], t('Invalid date format.'));
+      }
+    }
+    elseif ($operators[$operator]['values'] == 2) {
+      $min = strtotime($value['min']);
+      if ($min == -1 || $min === FALSE) {
+        form_error($form['min'], t('Invalid date format.'));
+      }
+      $max = strtotime($value['max']);
+      if ($max == -1 || $max === FALSE) {
+        form_error($form['max'], t('Invalid date format.'));
+      }
+    }
+  }
+
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // Store this because it will get overwritten.
+    $type = $this->value['type'];
+    $rc = parent::accept_exposed_input($input);
+
+    // Don't filter if value(s) are empty.
+    $operators = $this->operators();
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) {
+      $operator = $input[$this->options['expose']['operator_id']];
+    }
+    else {
+      $operator = $this->operator;
+    }
+
+    if ($operators[$operator]['values'] == 1) {
+      if ($this->value['value'] == '') {
+        return FALSE;
+      }
+    }
+    else {
+      if ($this->value['min'] == '' || $this->value['max'] == '') {
+        return FALSE;
+      }
+    }
+
+    // restore what got overwritten by the parent.
+    $this->value['type'] = $type;
+    return $rc;
+  }
+
+  function op_between($field) {
+    $a = intval(strtotime($this->value['min'], 0));
+    $b = intval(strtotime($this->value['max'], 0));
+
+    if ($this->value['type'] == 'offset') {
+      $a = '***CURRENT_TIME***' . sprintf('%+d', $a); // keep sign
+      $b = '***CURRENT_TIME***' . sprintf('%+d', $b); // keep sign
+    }
+    // This is safe because we are manually scrubbing the values.
+    // It is necessary to do it this way because $a and $b are formulas when using an offset.
+    $operator = strtoupper($this->operator);
+    $this->query->add_where_expression($this->options['group'], "$field $operator $a AND $b");
+  }
+
+  function op_simple($field) {
+    $value = intval(strtotime($this->value['value'], 0));
+    if (!empty($this->value['type']) && $this->value['type'] == 'offset') {
+      $value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign
+    }
+    // This is safe because we are manually scrubbing the value.
+    // It is necessary to do it this way because $value is a formula when using an offset.
+    $this->query->add_where_expression($this->options['group'], "$field $this->operator $value");
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/EqualityFilter.php b/lib/Drupal/views/Plugins/views/filter/EqualityFilter.php
new file mode 100644
index 0000000..a4d414e
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/EqualityFilter.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\EqualityFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Simple filter to handle equal to / not equal to filters
+ *
+ * @ingroup views_filter_handlers
+ */
+class EqualityFilter extends FilterPlugin {
+  // exposed filter options
+  var $always_multiple = TRUE;
+
+  /**
+   * Provide simple equality operator
+   */
+  function operator_options() {
+    return array(
+      '=' => t('Is equal to'),
+      '!=' => t('Is not equal to'),
+    );
+  }
+
+  /**
+   * Provide a simple textfield for equality
+   */
+  function value_form(&$form, &$form_state) {
+    $form['value'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Value'),
+      '#size' => 30,
+      '#default_value' => $this->value,
+    );
+
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if (!isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value;
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/FilterPlugin.php b/lib/Drupal/views/Plugins/views/filter/FilterPlugin.php
new file mode 100644
index 0000000..c7515af
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/FilterPlugin.php
@@ -0,0 +1,723 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\FilterPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_filter_handlers Views filter handlers
+ * @{
+ * Handlers to tell Views how to filter queries.
+ *
+ * Definition items:
+ * - allow empty: If true, the 'IS NULL' and 'IS NOT NULL' operators become
+ *   available as standard operators.
+ *
+ * Object flags:
+ *  You can set some specific behavior by setting up the following flags on
+ *  your custom class.
+ *
+ * - always_multiple:
+ *    Disable the possibility to force a single value.
+ * - no_operator:
+ *    Disable the possibility to use operators.
+ * - always_required:
+ *    Disable the possibility to allow a exposed input to be optional.
+ */
+
+/**
+ * Base class for filters.
+ *
+ * @ingroup views_filter_handlers
+ */
+class FilterPlugin extends Plugin {
+  /**
+   * Contains the actual value of the field,either configured in the views ui
+   * or entered in the exposed filters.
+   */
+  var $value = NULL;
+
+  /**
+   * Contains the operator which is used on the query.
+   */
+  var $operator = '=';
+
+  /**
+   * @var bool
+   * Disable the possibility to force a single value.
+   */
+  var $always_multiple = FALSE;
+
+  /**
+   * @var bool
+   * Disable the possibility to use operators.
+   */
+  var $no_operator = FALSE;
+
+  /**
+   * @var bool
+   * Disable the possibility to allow a exposed input to be optional.
+   */
+  var $always_required = FALSE;
+
+  /**
+   * Provide some extra help to get the operator/value easier to use.
+   *
+   * This likely has to be overridden by filters which are more complex
+   * than simple operator/value.
+   */
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $this->operator = $this->options['operator'];
+    $this->value = $this->options['value'];
+
+    // Compatibility: The new UI changed several settings.
+    if (!empty($options['exposed']) && !empty($options['expose']['optional']) && !isset($options['expose']['required'])) {
+      $this->options['expose']['required'] = !$options['expose']['optional'];
+    }
+    if (!empty($options['exposed']) && !empty($options['expose']['single']) && !isset($options['expose']['multiple'])) {
+      $this->options['expose']['multiple'] = !$options['expose']['single'];
+    }
+    if (!empty($options['exposed']) && !empty($options['expose']['operator']) && !isset($options['expose']['operator_id'])) {
+      $this->options['expose']['operator_id'] = $options['expose']['operator_id'] = $options['expose']['operator'];
+    }
+
+    // If there are relationships in the view, allow empty should be true
+    // so that we can do IS NULL checks on items. Not all filters respect
+    // allow empty, but string and numeric do and that covers enough.
+    if ($this->view->display_handler->get_option('relationships')) {
+      $this->definition['allow empty'] = TRUE;
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator'] = array('default' => '=');
+    $options['value'] = array('default' => '');
+    $options['group'] = array('default' => '1');
+    $options['exposed'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['expose'] = array(
+      'contains' => array(
+        'operator_id' => array('default' => FALSE),
+        'label' => array('default' => '', 'translatable' => TRUE),
+        'use_operator' => array('default' => FALSE, 'bool' => TRUE),
+        'operator' => array('default' => ''),
+        'identifier' => array('default' => ''),
+        'required' => array('default' => FALSE, 'bool' => TRUE),
+        'remember' => array('default' => FALSE, 'bool' => TRUE),
+        'multiple' => array('default' => FALSE, 'bool' => TRUE),
+      ),
+    );
+
+    return $options;
+  }
+
+  /**
+   * Display the filter on the administrative summary
+   */
+  function admin_summary() {
+    return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value);
+  }
+
+  /**
+   * Determine if a filter can be exposed.
+   */
+  function can_expose() { return TRUE; }
+
+  /**
+   * Provide the basic form which calls through to subforms.
+   * If overridden, it is best to call through to the parent,
+   * or to at least make sure all of the functions in this form
+   * are called.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    if ($this->can_expose()) {
+      $this->show_expose_button($form, $form_state);
+    }
+    $form['clear_markup_start'] = array(
+      '#markup' => '<div class="clearfix">',
+    );
+    // Add the subform from operator_form().
+    $this->show_operator_form($form, $form_state);
+    // Add the subform from value_form().
+    $this->show_value_form($form, $form_state);
+    $form['clear_markup_end'] = array(
+      '#markup' => '</div>',
+    );
+    if ($this->can_expose()) {
+      // Add the subform from expose_form().
+      $this->show_expose_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Simple validate handler
+   */
+  function options_validate(&$form, &$form_state) {
+    $this->operator_validate($form, $form_state);
+    $this->value_validate($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_validate($form, $form_state);
+    }
+  }
+
+  /**
+   * Simple submit handler
+   */
+  function options_submit(&$form, &$form_state) {
+    unset($form_state['values']['expose_button']); // don't store this.
+    $this->operator_submit($form, $form_state);
+    $this->value_submit($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_submit($form, $form_state);
+    }
+  }
+
+  /**
+   * Shortcut to display the operator form.
+   */
+  function show_operator_form(&$form, &$form_state) {
+    $this->operator_form($form, $form_state);
+    $form['operator']['#prefix'] = '<div class="views-group-box views-left-30">';
+    $form['operator']['#suffix'] = '</div>';
+  }
+
+  /**
+   * Options form subform for setting the operator.
+   *
+   * This may be overridden by child classes, and it must
+   * define $form['operator'];
+   *
+   * @see options_form()
+   */
+  function operator_form(&$form, &$form_state) {
+    $options = $this->operator_options();
+    if (!empty($options)) {
+      $form['operator'] = array(
+        '#type' => count($options) < 10 ? 'radios' : 'select',
+        '#title' => t('Operator'),
+        '#default_value' => $this->operator,
+        '#options' => $options,
+      );
+    }
+  }
+
+  /**
+   * Provide a list of options for the default operator form.
+   * Should be overridden by classes that don't override operator_form
+   */
+  function operator_options() { return array(); }
+
+  /**
+   * Validate the operator form.
+   */
+  function operator_validate($form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function operator_submit($form, &$form_state) { }
+
+  /**
+   * Shortcut to display the value form.
+   */
+  function show_value_form(&$form, &$form_state) {
+    $this->value_form($form, $form_state);
+    if (empty($this->no_operator)) {
+      $form['value']['#prefix'] = '<div class="views-group-box views-right-70">' . (isset($form['value']['#prefix']) ? $form['value']['#prefix'] : '');
+      $form['value']['#suffix'] = (isset($form['value']['#suffix']) ? $form['value']['#suffix'] : '') . '</div>';
+    }
+  }
+
+  /**
+   * Options form subform for setting options.
+   *
+   * This should be overridden by all child classes and it must
+   * define $form['value']
+   *
+   * @see options_form()
+   */
+  function value_form(&$form, &$form_state) { $form['value'] = array(); }
+
+  /**
+   * Validate the options form.
+   */
+  function value_validate($form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function value_submit($form, &$form_state) { }
+
+  /**
+   * Shortcut to display the expose/hide button.
+   */
+  function show_expose_button(&$form, &$form_state) {
+    $form['expose_button'] = array(
+      '#prefix' => '<div class="views-expose clearfix">',
+      '#suffix' => '</div>',
+      // Should always come after the description and the relationship.
+      '#weight' => -200,
+    );
+
+    // Add a checkbox for JS users, which will have behavior attached to it
+    // so it can replace the button.
+    $form['expose_button']['checkbox'] = array(
+      '#theme_wrappers' => array('container'),
+      '#attributes' => array('class' => array('js-only')),
+    );
+    $form['expose_button']['checkbox']['checkbox'] = array(
+      '#title' => t('Expose this filter to visitors, to allow them to change it'),
+      '#type' => 'checkbox',
+    );
+
+    // Then add the button itself.
+    if (empty($this->options['exposed'])) {
+      $form['expose_button']['markup'] = array(
+        '#markup' => '<div class="description exposed-description">' . t('This filter is not exposed. Expose it to allow the users to change it.') . '</div>',
+      );
+      $form['expose_button']['button'] = array(
+        '#limit_validation_errors' => array(),
+        '#type' => 'submit',
+        '#value' => t('Expose filter'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0;
+    }
+    else {
+      $form['expose_button']['markup'] = array(
+        '#markup' => '<div class="description exposed-description">' . t('This filter is exposed. If you hide it, users will not be able to change it.') . '</div>',
+      );
+      $form['expose_button']['button'] = array(
+        '#limit_validation_errors' => array(),
+        '#type' => 'submit',
+        '#value' => t('Hide filter'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1;
+    }
+  }
+
+  /**
+   * Options form subform for exposed filter options.
+   *
+   * @see options_form()
+   */
+  function expose_form(&$form, &$form_state) {
+    $form['#theme'] = 'views_ui_expose_filter_form';
+    // #flatten will move everything from $form['expose'][$key] to $form[$key]
+    // prior to rendering. That's why the pre_render for it needs to run first,
+    // so that when the next pre_render (the one for fieldsets) runs, it gets
+    // the flattened data.
+    array_unshift($form['#pre_render'], 'views_ui_pre_render_flatten_data');
+    $form['expose']['#flatten'] = TRUE;
+
+    if (empty($this->always_required)) {
+      $form['expose']['required'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Required'),
+        '#default_value' => $this->options['expose']['required'],
+      );
+    }
+    else {
+      $form['expose']['required'] = array(
+        '#type' => 'value',
+        '#value' => TRUE,
+      );
+    }
+    $form['expose']['label'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['label'],
+      '#title' => t('Label'),
+      '#size' => 40,
+    );
+
+    if (!empty($form['operator']['#type'])) {
+       // Increase the width of the left (operator) column.
+      $form['operator']['#prefix'] = '<div class="views-group-box views-left-40">';
+      $form['operator']['#suffix'] = '</div>';
+      $form['value']['#prefix'] = '<div class="views-group-box views-right-60">';
+      $form['value']['#suffix'] = '</div>';
+
+      $form['expose']['use_operator'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Expose operator'),
+        '#description' => t('Allow the user to choose the operator.'),
+        '#default_value' => !empty($this->options['expose']['use_operator']),
+      );
+      $form['expose']['operator_id'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $this->options['expose']['operator_id'],
+        '#title' => t('Operator identifier'),
+        '#size' => 40,
+        '#description' => t('This will appear in the URL after the ? to identify this operator.'),
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[expose][use_operator]"]' => array('checked' => TRUE),
+          ),
+        ),
+        '#fieldset' => 'more',
+      );
+    }
+    else {
+      $form['expose']['operator_id'] = array(
+        '#type' => 'value',
+        '#value' => '',
+      );
+    }
+
+    if (empty($this->always_multiple)) {
+      $form['expose']['multiple'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Allow multiple selections'),
+        '#description' => t('Enable to allow users to select multiple items.'),
+        '#default_value' => $this->options['expose']['multiple'],
+      );
+    }
+    $form['expose']['remember'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remember the last selection'),
+      '#description' => t('Enable to remember the last selection made by the user.'),
+      '#default_value' => $this->options['expose']['remember'],
+    );
+
+    $form['expose']['identifier'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['identifier'],
+      '#title' => t('Filter identifier'),
+      '#size' => 40,
+      '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
+      '#fieldset' => 'more',
+    );
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function expose_validate($form, &$form_state) {
+    if (empty($form_state['values']['options']['expose']['identifier'])) {
+      form_error($form['expose']['identifier'], t('The identifier is required if the filter is exposed.'));
+    }
+
+    if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') {
+      form_error($form['expose']['identifier'], t('This identifier is not allowed.'));
+    }
+
+    if (!$this->view->display_handler->is_identifier_unique($form_state['id'], $form_state['values']['options']['expose']['identifier'])) {
+      form_error($form['expose']['identifier'], t('This identifier is used by another handler.'));
+    }
+  }
+
+  /**
+   * Provide default options for exposed filters.
+   */
+  function expose_options() {
+    $this->options['expose'] = array(
+      'use_operator' => FALSE,
+      'operator' => $this->options['id'] . '_op',
+      'identifier' => $this->options['id'],
+      'label' => $this->definition['title'],
+      'remember' => FALSE,
+      'multiple' => FALSE,
+      'required' => FALSE,
+    );
+  }
+
+  /**
+   * Render our chunk of the exposed filter form when selecting
+   *
+   * You can override this if it doesn't do what you expect.
+   */
+  function exposed_form(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    // Build the exposed form, when its based on an operator.
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) {
+      $operator = $this->options['expose']['operator_id'];
+      $this->operator_form($form, $form_state);
+      $form[$operator] = $form['operator'];
+
+      if (isset($form[$operator]['#title'])) {
+        unset($form[$operator]['#title']);
+      }
+
+      $this->exposed_translate($form[$operator], 'operator');
+
+      unset($form['operator']);
+    }
+
+    // Build the form and set the value based on the identifier.
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = $this->options['expose']['identifier'];
+      $this->value_form($form, $form_state);
+      $form[$value] = $form['value'];
+
+      if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
+        unset($form[$value]['#title']);
+      }
+
+      $this->exposed_translate($form[$value], 'value');
+
+      if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) {
+        unset($form[$value]['#default_value']);
+      }
+
+      if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
+        $form[$value]['#default_value'] = 'All';
+      }
+
+      if ($value != 'value') {
+        unset($form['value']);
+      }
+    }
+  }
+
+  /**
+   * Make some translations to a form item to make it more suitable to
+   * exposing.
+   */
+  function exposed_translate(&$form, $type) {
+    if (!isset($form['#type'])) {
+      return;
+    }
+
+    if ($form['#type'] == 'radios') {
+      $form['#type'] = 'select';
+    }
+    // Checkboxes don't work so well in exposed forms due to GET conversions.
+    if ($form['#type'] == 'checkboxes') {
+      if (empty($form['#no_convert']) || empty($this->options['expose']['multiple'])) {
+        $form['#type'] = 'select';
+      }
+      if (!empty($this->options['expose']['multiple'])) {
+        $form['#multiple'] = TRUE;
+      }
+    }
+    if (empty($this->options['expose']['multiple']) && isset($form['#multiple'])) {
+      unset($form['#multiple']);
+      $form['#size'] = NULL;
+    }
+
+    // Cleanup in case the translated element's (radios or checkboxes) display value contains html.
+    if ($form['#type'] == 'select') {
+      $this->prepare_filter_select_options($form['#options']);
+    }
+
+    if ($type == 'value' && empty($this->always_required) && empty($this->options['expose']['required']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
+      $any_label = config('views.settings')->get('views_exposed_filter_any_label') == 'old_any' ? t('<Any>') : t('- Any -');
+      $form['#options'] = array('All' => $any_label) + $form['#options'];
+      $form['#default_value'] = 'All';
+    }
+
+    if (!empty($this->options['expose']['required'])) {
+      $form['#required'] = TRUE;
+    }
+  }
+
+
+
+  /**
+   * Sanitizes the HTML select element's options.
+   *
+   * The function is recursive to support optgroups.
+   */
+  function prepare_filter_select_options(&$options) {
+    foreach ($options as $value => $label) {
+      // Recurse for optgroups.
+      if (is_array($label)) {
+        $this->prepare_filter_select_options($options[$value]);
+      }
+      // FAPI has some special value to allow hierarchy.
+      // @see _form_options_flatten
+      elseif (is_object($label)) {
+        $this->prepare_filter_select_options($options[$value]->option);
+      }
+      else {
+        $options[$value] = strip_tags(decode_entities($label));
+      }
+    }
+  }
+
+  /**
+   * Tell the renderer about our exposed form. This only needs to be
+   * overridden for particularly complex forms. And maybe not even then.
+   *
+   * @return array|null
+   *   An array with the following keys:
+   *   - operator: The $form key of the operator. Set to NULL if no operator.
+   *   - value: The $form key of the value. Set to NULL if no value.
+   *   - label: The label to use for this piece.
+   */
+  function exposed_info() {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    return array(
+      'operator' => $this->options['expose']['operator_id'],
+      'value' => $this->options['expose']['identifier'],
+      'label' => $this->options['expose']['label'],
+    );
+  }
+
+  /**
+   * Check to see if input from the exposed filters should change
+   * the behavior of this filter.
+   */
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id']])) {
+      $this->operator = $input[$this->options['expose']['operator_id']];
+    }
+
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = $input[$this->options['expose']['identifier']];
+
+      // Various ways to check for the absence of non-required input.
+      if (empty($this->options['expose']['required'])) {
+        if (($this->operator == 'empty' || $this->operator == 'not empty') && $value === '') {
+          $value = ' ';
+        }
+
+        if ($this->operator != 'empty' && $this->operator != 'not empty') {
+          if ($value == 'All' || $value === array()) {
+            return FALSE;
+          }
+        }
+
+        if (!empty($this->always_multiple) && $value === '') {
+          return FALSE;
+        }
+      }
+
+
+      if (isset($value)) {
+        $this->value = $value;
+        if (empty($this->always_multiple) && empty($this->options['expose']['multiple'])) {
+          $this->value = array($value);
+        }
+      }
+      else {
+        return FALSE;
+      }
+    }
+
+    return TRUE;
+  }
+
+  function store_exposed_input($input, $status) {
+    if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
+      return TRUE;
+    }
+
+    if (empty($this->options['expose']['remember'])) {
+      return;
+    }
+
+    // Figure out which display id is responsible for the filters, so we
+    // know where to look for session stored values.
+    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+
+    // shortcut test.
+    $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']);
+
+    // false means that we got a setting that means to recuse ourselves,
+    // so we should erase whatever happened to be there.
+    if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) {
+      $session = &$_SESSION['views'][$this->view->name][$display_id];
+      if ($operator && isset($session[$this->options['expose']['operator_id']])) {
+        unset($session[$this->options['expose']['operator_id']]);
+      }
+
+      if (isset($session[$this->options['expose']['identifier']])) {
+        unset($session[$this->options['expose']['identifier']]);
+      }
+    }
+
+    if ($status) {
+      if (!isset($_SESSION['views'][$this->view->name][$display_id])) {
+        $_SESSION['views'][$this->view->name][$display_id] = array();
+      }
+
+      $session = &$_SESSION['views'][$this->view->name][$display_id];
+
+      if ($operator && isset($input[$this->options['expose']['operator_id']])) {
+        $session[$this->options['expose']['operator_id']] = $input[$this->options['expose']['operator_id']];
+      }
+
+      $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
+    }
+  }
+
+  /**
+   * Add this filter to the query.
+   *
+   * Due to the nature of fapi, the value and the operator have an unintended
+   * level of indirection. You will find them in $this->operator
+   * and $this->value respectively.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator);
+  }
+
+  /**
+   * Can this filter be used in OR groups?
+   *
+   * Some filters have complicated where clauses that cannot be easily used
+   * with OR groups. Some filters must also use HAVING which also makes
+   * them not groupable. These filters will end up in a special group
+   * if OR grouping is in use.
+   *
+   * @return bool
+   */
+   function can_group() {
+     return TRUE;
+   }
+}
+
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_broken extends views_handler_filter {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query($group_by = FALSE) { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/filter/GroupByNumericFilter.php b/lib/Drupal/views/Plugins/views/filter/GroupByNumericFilter.php
new file mode 100644
index 0000000..f9a693b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/GroupByNumericFilter.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\GroupByNumericFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Simple filter to handle greater than/less than filters
+ *
+ * @ingroup views_filter_handlers
+ */
+class GroupByNumericFilter extends NumericFilter {
+  function query() {
+    $this->ensure_my_table();
+    $field = $this->get_field();
+
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+  function op_between($field) {
+    $placeholder_min = $this->placeholder();
+    $placeholder_max = $this->placeholder();
+    if ($this->operator == 'between') {
+      $this->query->add_having_expression($this->options['group'], "$field >= $placeholder_min", array($placeholder_min => $this->value['min']));
+      $this->query->add_having_expression($this->options['group'], "$field <= $placeholder_max", array($placeholder_max => $this->value['max']));
+    }
+    else {
+      $this->query->add_having_expression($this->options['group'], "$field <= $placeholder_min OR $field >= $placeholder_max", array($placeholder_min => $this->value['min'], $placeholder_max => $this->value['max']));
+    }
+  }
+
+  function op_simple($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_having_expression($this->options['group'], "$field $this->operator $placeholder", array($placeholder => $this->value['value']));
+  }
+
+  function op_empty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_having_expression($this->options['group'], "$field $operator");
+  }
+
+  function ui_name($short = FALSE) {
+    return $this->get_field(parent::ui_name($short));
+  }
+
+  function can_group() { return FALSE; }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/InOperatorFilter.php b/lib/Drupal/views/Plugins/views/filter/InOperatorFilter.php
new file mode 100644
index 0000000..ea24d41
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/InOperatorFilter.php
@@ -0,0 +1,430 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\InOperatorFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Simple filter to handle matching of multiple options selectable via checkboxes
+ *
+ * Definition items:
+ * - options callback: The function to call in order to generate the value options. If omitted, the options 'Yes' and 'No' will be used.
+ * - options arguments: An array of arguments to pass to the options callback.
+ *
+ * @ingroup views_filter_handlers
+ */
+class InOperatorFilter extends FilterPlugin {
+  var $value_form_type = 'checkboxes';
+
+  /**
+   * @var array
+   * Stores all operations which are available on the form.
+   */
+  var $value_options = NULL;
+
+  function construct() {
+    parent::construct();
+    $this->value_title = t('Options');
+    $this->value_options = NULL;
+  }
+
+  /**
+   * Child classes should be used to override this function and set the
+   * 'value options', unless 'options callback' is defined as a valid function
+   * or static public method to generate these values.
+   *
+   * This can use a guard to be used to reduce database hits as much as
+   * possible.
+   *
+   * @return
+   *   Return the stored values in $this->value_options if someone expects it.
+   */
+  function get_value_options() {
+    if (isset($this->value_options)) {
+      return;
+    }
+
+    if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) {
+      if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) {
+        $this->value_options = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']);
+      }
+      else {
+        $this->value_options = call_user_func($this->definition['options callback']);
+      }
+    }
+    else {
+      $this->value_options = array(t('Yes'), t('No'));
+    }
+
+    return $this->value_options;
+  }
+
+  function expose_options() {
+    parent::expose_options();
+    $this->options['expose']['reduce'] = FALSE;
+  }
+
+  function expose_form(&$form, &$form_state) {
+    parent::expose_form($form, $form_state);
+    $form['expose']['reduce'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Limit list to selected items'),
+      '#description' => t('If checked, the only items presented to the user will be the ones selected here.'),
+      '#default_value' => !empty($this->options['expose']['reduce']), // safety
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator']['default'] = 'in';
+    $options['value']['default'] = array();
+    $options['expose']['contains']['reduce'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * This kind of construct makes it relatively easy for a child class
+   * to add or remove functionality by overriding this function and
+   * adding/removing items from this array.
+   */
+  function operators() {
+    $operators = array(
+      'in' => array(
+        'title' => t('Is one of'),
+        'short' => t('in'),
+        'short_single' => t('='),
+        'method' => 'op_simple',
+        'values' => 1,
+      ),
+      'not in' => array(
+        'title' => t('Is not one of'),
+        'short' => t('not in'),
+        'short_single' => t('<>'),
+        'method' => 'op_simple',
+        'values' => 1,
+      ),
+    );
+    // if the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += array(
+        'empty' => array(
+          'title' => t('Is empty (NULL)'),
+          'method' => 'op_empty',
+          'short' => t('empty'),
+          'values' => 0,
+        ),
+        'not empty' => array(
+          'title' => t('Is not empty (NOT NULL)'),
+          'method' => 'op_empty',
+          'short' => t('not empty'),
+          'values' => 0,
+        ),
+      );
+    }
+
+    return $operators;
+  }
+
+  /**
+   * Build strings from the operators() for 'select' options
+   */
+  function operator_options($which = 'title') {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      $options[$id] = $info[$which];
+    }
+
+    return $options;
+  }
+
+  function operator_values($values = 1) {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      if (isset($info['values']) && $info['values'] == $values) {
+        $options[] = $id;
+      }
+    }
+
+    return $options;
+  }
+
+  function value_form(&$form, &$form_state) {
+    $form['value'] = array();
+    $options = array();
+
+    if (empty($form_state['exposed'])) {
+      // Add a select all option to the value form.
+      $options = array('all' => t('Select all'));
+    }
+
+    $this->get_value_options();
+    $options += $this->value_options;
+    $default_value = (array) $this->value;
+
+    $which = 'all';
+    if (!empty($form['operator'])) {
+      $source = ':input[name="options[operator]"]';
+    }
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+
+      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
+        // exposed and locked.
+        $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none';
+      }
+      else {
+        $source = ':input[name="' . $this->options['expose']['operator_id'] . '"]';
+      }
+
+      if (!empty($this->options['expose']['reduce'])) {
+        $options = $this->reduce_value_options();
+
+        if (!empty($this->options['expose']['multiple']) && empty($this->options['expose']['required'])) {
+          $default_value = array();
+        }
+      }
+
+      if (empty($this->options['expose']['multiple'])) {
+        if (empty($this->options['expose']['required']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) {
+          $default_value = 'All';
+        }
+        elseif (empty($default_value)) {
+          $keys = array_keys($options);
+          $default_value = array_shift($keys);
+        }
+        else {
+          $copy = $default_value;
+          $default_value = array_shift($copy);
+        }
+      }
+    }
+
+    if ($which == 'all' || $which == 'value') {
+      $form['value'] = array(
+        '#type' => $this->value_form_type,
+        '#title' => $this->value_title,
+        '#options' => $options,
+        '#default_value' => $default_value,
+        // These are only valid for 'select' type, but do no harm to checkboxes.
+        '#multiple' => TRUE,
+        '#size' => count($options) > 8 ? 8 : count($options),
+      );
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $default_value;
+      }
+
+      if ($which == 'all') {
+        if (empty($form_state['exposed']) && (in_array($this->value_form_type, array('checkbox', 'checkboxes', 'radios', 'select')))) {
+          $form['value']['#prefix'] = '<div id="edit-options-value-wrapper">';
+          $form['value']['#suffix'] = '</div>';
+        }
+        // Setup #states for all operators with one value.
+        foreach ($this->operator_values(1) as $operator) {
+          $form['value']['#states']['visible'][] = array(
+            $source => array('value' => $operator),
+          );
+        }
+      }
+    }
+  }
+
+  /**
+   * When using exposed filters, we may be required to reduce the set.
+   */
+  function reduce_value_options($input = NULL) {
+    if (!isset($input)) {
+      $input = $this->value_options;
+    }
+
+    // Because options may be an array of strings, or an array of mixed arrays
+    // and strings (optgroups) or an array of objects, we have to
+    // step through and handle each one individually.
+    $options = array();
+    foreach ($input as $id => $option) {
+      if (is_array($option)) {
+        $options[$id] = $this->reduce_value_options($option);
+        continue;
+      }
+      elseif (is_object($option)) {
+        $keys = array_keys($option->option);
+        $key = array_shift($keys);
+        if (isset($this->options['value'][$key])) {
+          $options[$id] = $option;
+        }
+      }
+      elseif (isset($this->options['value'][$id])) {
+        $options[$id] = $option;
+      }
+    }
+    return $options;
+  }
+
+  function accept_exposed_input($input) {
+    // A very special override because the All state for this type of
+    // filter could have a default:
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // If this is non-multiple and non-required, then this filter will
+    // participate, but using the default settings, *if* 'limit is true.
+    if (empty($this->options['expose']['multiple']) && empty($this->options['expose']['required']) && !empty($this->options['expose']['limit'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if ($input[$identifier] == 'All') {
+        return TRUE;
+      }
+    }
+
+    return parent::accept_exposed_input($input);
+  }
+
+  function value_submit($form, &$form_state) {
+    // Drupal's FAPI system automatically puts '0' in for any checkbox that
+    // was not set, and the key to the checkbox if it is set.
+    // Unfortunately, this means that if the key to that checkbox is 0,
+    // we are unable to tell if that checkbox was set or not.
+
+    // Luckily, the '#value' on the checkboxes form actually contains
+    // *only* a list of checkboxes that were set, and we can use that
+    // instead.
+
+    $form_state['values']['options']['value'] = $form['value']['#value'];
+  }
+
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+    $info = $this->operators();
+
+    $this->get_value_options();
+
+    if (!is_array($this->value)) {
+      return;
+    }
+
+    $operator = check_plain($info[$this->operator]['short']);
+    $values = '';
+    if (in_array($this->operator, $this->operator_values(1))) {
+      // Remove every element which is not known.
+      foreach ($this->value as $value) {
+        if (!isset($this->value_options[$value])) {
+          unset($this->value[$value]);
+        }
+      }
+      // Choose different kind of ouput for 0, a single and multiple values.
+      if (count($this->value) == 0) {
+        $values = t('Unknown');
+      }
+      else if (count($this->value) == 1) {
+        // If any, use the 'single' short name of the operator instead.
+        if (isset($info[$this->operator]['short_single'])) {
+          $operator = check_plain($info[$this->operator]['short_single']);
+        }
+
+        $keys = $this->value;
+        $value = array_shift($keys);
+        if (isset($this->value_options[$value])) {
+          $values = check_plain($this->value_options[$value]);
+        }
+        else {
+          $values = '';
+        }
+      }
+      else {
+        foreach ($this->value as $value) {
+          if ($values !== '') {
+            $values .= ', ';
+          }
+          if (drupal_strlen($values) > 8) {
+            $values .= '...';
+            break;
+          }
+          if (isset($this->value_options[$value])) {
+            $values .= check_plain($this->value_options[$value]);
+          }
+        }
+      }
+    }
+
+    return $operator . (($values !== '') ? ' ' . $values : '');
+  }
+
+  function query() {
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}();
+    }
+  }
+
+  function op_simple() {
+    if (empty($this->value)) {
+      return;
+    }
+    $this->ensure_my_table();
+
+    // We use array_values() because the checkboxes keep keys and that can cause
+    // array addition problems.
+    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", array_values($this->value), $this->operator);
+  }
+
+  function op_empty() {
+    $this->ensure_my_table();
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", NULL, $operator);
+  }
+
+  function validate() {
+    $this->get_value_options();
+    $errors = array();
+
+    // If the operator is an operator which doesn't require a value, there is
+    // no need for additional validation.
+    if (in_array($this->operator, $this->operator_values(0))) {
+      return array();
+    }
+
+    if (!in_array($this->operator, $this->operator_values(1))) {
+      $errors[] = t('The operator is invalid on filter: @filter.', array('@filter' => $this->ui_name(TRUE)));
+    }
+    if (is_array($this->value)) {
+      if (!isset($this->value_options)) {
+        // Don't validate if there are none value options provided, for example for special handlers.
+        return $errors;
+      }
+      if ($this->options['exposed'] && !$this->options['expose']['required'] && empty($this->value)) {
+        // Don't validate if the field is exposed and no default value is provided.
+        return $errors;
+      }
+
+      // Some filter_in_operator usage uses optgroups forms, so flatten it.
+      $flat_options = form_options_flatten($this->value_options, TRUE);
+
+      // Remove every element which is not known.
+      foreach ($this->value as $value) {
+        if (!isset($flat_options[$value])) {
+          unset($this->value[$value]);
+        }
+      }
+      // Choose different kind of ouput for 0, a single and multiple values.
+      if (count($this->value) == 0) {
+        $errors[] = t('No valid values found on filter: @filter.', array('@filter' => $this->ui_name(TRUE)));
+      }
+    }
+    elseif (!empty($this->value) && ($this->operator == 'in' || $this->operator == 'not in')) {
+      $errors[] = t('The value @value is not an array for @operator on filter: @filter', array('@value' => views_var_export($this->value), '@operator' => $this->operator, '@filter' => $this->ui_name(TRUE)));
+    }
+    return $errors;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/ManyToOneFilter.php b/lib/Drupal/views/Plugins/views/filter/ManyToOneFilter.php
new file mode 100644
index 0000000..158e1b1
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/ManyToOneFilter.php
@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\ManyToOneFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+/**
+ * Complex filter to handle filtering for many to one relationships,
+ * such as terms (many terms per node) or roles (many roles per user).
+ *
+ * The construct method needs to be overridden to provide a list of options;
+ * alternately, the value_form and admin_summary methods need to be overriden
+ * to provide something that isn't just a select list.
+ *
+ * @ingroup views_filter_handlers
+ */
+class ManyToOneFilter extends InOperatorFilter {
+  /**
+   * @var views_many_to_one_helper
+   *
+   * Stores the Helper object which handles the many_to_one complexity.
+   */
+  var $helper = NULL;
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    $this->helper = new views_many_to_one_helper($this);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator']['default'] = 'or';
+    $options['value']['default'] = array();
+
+    if (isset($this->helper)) {
+      $this->helper->option_definition($options);
+    }
+    else {
+      $helper = new views_many_to_one_helper($this);
+      $helper->option_definition($options);
+    }
+
+    return $options;
+  }
+
+  function operators() {
+    $operators = array(
+      'or' => array(
+        'title' => t('Is one of'),
+        'short' => t('or'),
+        'short_single' => t('='),
+        'method' => 'op_helper',
+        'values' => 1,
+        'ensure_my_table' => 'helper',
+      ),
+      'and' => array(
+        'title' => t('Is all of'),
+        'short' => t('and'),
+        'short_single' => t('='),
+        'method' => 'op_helper',
+        'values' => 1,
+        'ensure_my_table' => 'helper',
+      ),
+      'not' => array(
+        'title' => t('Is none of'),
+        'short' => t('not'),
+        'short_single' => t('<>'),
+        'method' => 'op_helper',
+        'values' => 1,
+        'ensure_my_table' => 'helper',
+      ),
+    );
+    // if the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += array(
+        'empty' => array(
+          'title' => t('Is empty (NULL)'),
+          'method' => 'op_empty',
+          'short' => t('empty'),
+          'values' => 0,
+        ),
+        'not empty' => array(
+          'title' => t('Is not empty (NOT NULL)'),
+          'method' => 'op_empty',
+          'short' => t('not empty'),
+          'values' => 0,
+        ),
+      );
+    }
+
+    return $operators;
+  }
+
+  var $value_form_type = 'select';
+  function value_form(&$form, &$form_state) {
+    parent::value_form($form, $form_state);
+
+    if (empty($form_state['exposed'])) {
+      $this->helper->options_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Override ensure_my_table so we can control how this joins in.
+   * The operator actually has influence over joining.
+   */
+  function ensure_my_table() {
+    // Defer to helper if the operator specifies it.
+    $info = $this->operators();
+    if (isset($info[$this->operator]['ensure_my_table']) && $info[$this->operator]['ensure_my_table'] == 'helper') {
+      return $this->helper->ensure_my_table();
+    }
+
+    return parent::ensure_my_table();
+  }
+
+  function op_helper() {
+    if (empty($this->value)) {
+      return;
+    }
+    $this->helper->add_filter();
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/NumericFilter.php b/lib/Drupal/views/Plugins/views/filter/NumericFilter.php
new file mode 100644
index 0000000..61d0182
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/NumericFilter.php
@@ -0,0 +1,335 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\NumericFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+use Drupal\Core\Database\Database;
+
+/**
+ * Simple filter to handle greater than/less than filters
+ *
+ * @ingroup views_filter_handlers
+ */
+class NumericFilter extends FilterPlugin {
+  var $always_multiple = TRUE;
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['value'] = array(
+      'contains' => array(
+        'min' => array('default' => ''),
+        'max' => array('default' => ''),
+        'value' => array('default' => ''),
+      ),
+    );
+
+    return $options;
+  }
+
+  function operators() {
+    $operators = array(
+      '<' => array(
+        'title' => t('Is less than'),
+        'method' => 'op_simple',
+        'short' => t('<'),
+        'values' => 1,
+      ),
+      '<=' => array(
+        'title' => t('Is less than or equal to'),
+        'method' => 'op_simple',
+        'short' => t('<='),
+        'values' => 1,
+      ),
+      '=' => array(
+        'title' => t('Is equal to'),
+        'method' => 'op_simple',
+        'short' => t('='),
+        'values' => 1,
+      ),
+      '!=' => array(
+        'title' => t('Is not equal to'),
+        'method' => 'op_simple',
+        'short' => t('!='),
+        'values' => 1,
+      ),
+      '>=' => array(
+        'title' => t('Is greater than or equal to'),
+        'method' => 'op_simple',
+        'short' => t('>='),
+        'values' => 1,
+      ),
+      '>' => array(
+        'title' => t('Is greater than'),
+        'method' => 'op_simple',
+        'short' => t('>'),
+        'values' => 1,
+      ),
+      'between' => array(
+        'title' => t('Is between'),
+        'method' => 'op_between',
+        'short' => t('between'),
+        'values' => 2,
+      ),
+      'not between' => array(
+        'title' => t('Is not between'),
+        'method' => 'op_between',
+        'short' => t('not between'),
+        'values' => 2,
+      ),
+    );
+
+    // if the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += array(
+        'empty' => array(
+          'title' => t('Is empty (NULL)'),
+          'method' => 'op_empty',
+          'short' => t('empty'),
+          'values' => 0,
+        ),
+        'not empty' => array(
+          'title' => t('Is not empty (NOT NULL)'),
+          'method' => 'op_empty',
+          'short' => t('not empty'),
+          'values' => 0,
+        ),
+      );
+    }
+
+    // Add regexp support for MySQL.
+    if (Database::getConnection()->databaseType() == 'mysql') {
+      $operators += array(
+        'regular_expression' => array(
+          'title' => t('Regular expression'),
+          'short' => t('regex'),
+          'method' => 'op_regex',
+          'values' => 1,
+        ),
+      );
+    }
+
+    return $operators;
+  }
+
+  /**
+   * Provide a list of all the numeric operators
+   */
+  function operator_options($which = 'title') {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      $options[$id] = $info[$which];
+    }
+
+    return $options;
+  }
+
+  function operator_values($values = 1) {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      if ($info['values'] == $values) {
+        $options[] = $id;
+      }
+    }
+
+    return $options;
+  }
+  /**
+   * Provide a simple textfield for equality
+   */
+  function value_form(&$form, &$form_state) {
+    $form['value']['#tree'] = TRUE;
+
+    // We have to make some choices when creating this as an exposed
+    // filter form. For example, if the operator is locked and thus
+    // not rendered, we can't render dependencies; instead we only
+    // render the form items we need.
+    $which = 'all';
+    if (!empty($form['operator'])) {
+      $source = ':input[name="options[operator]"]';
+    }
+
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+
+      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
+        // exposed and locked.
+        $which = in_array($this->operator, $this->operator_values(2)) ? 'minmax' : 'value';
+      }
+      else {
+        $source = ':input[name="' . $this->options['expose']['operator_id'] . '"]';
+      }
+    }
+
+    if ($which == 'all') {
+      $form['value']['value'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['value'],
+      );
+      // Setup #states for all operators with one value.
+      foreach ($this->operator_values(1) as $operator) {
+        $form['value']['value']['#states']['visible'][] = array(
+          $source => array('value' => $operator),
+        );
+      }
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['value'])) {
+        $form_state['input'][$identifier]['value'] = $this->value['value'];
+      }
+    }
+    elseif ($which == 'value') {
+      // When exposed we drop the value-value and just do value if
+      // the operator is locked.
+      $form['value'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['value'],
+      );
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value['value'];
+      }
+    }
+
+    if ($which == 'all' || $which == 'minmax') {
+      $form['value']['min'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Min') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['min'],
+      );
+      $form['value']['max'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
+        '#size' => 30,
+        '#default_value' => $this->value['max'],
+      );
+      if ($which == 'all') {
+        $states = array();
+        // Setup #states for all operators with two values.
+        foreach ($this->operator_values(2) as $operator) {
+          $states['#states']['visible'][] = array(
+            $source => array('value' => $operator),
+          );
+        }
+        $form['value']['min'] += $states;
+        $form['value']['max'] += $states;
+      }
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min'])) {
+        $form_state['input'][$identifier]['min'] = $this->value['min'];
+      }
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max'])) {
+        $form_state['input'][$identifier]['max'] = $this->value['max'];
+      }
+
+      if (!isset($form['value'])) {
+        // Ensure there is something in the 'value'.
+        $form['value'] = array(
+          '#type' => 'value',
+          '#value' => NULL
+        );
+      }
+    }
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $field = "$this->table_alias.$this->real_field";
+
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+
+  function op_between($field) {
+    if ($this->operator == 'between') {
+      $this->query->add_where($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'BETWEEN');
+    }
+    else {
+      $this->query->add_where($this->options['group'], db_or()->condition($field, $this->value['min'], '<=')->condition($field, $this->value['max'], '>='));
+    }
+  }
+
+  function op_simple($field) {
+    $this->query->add_where($this->options['group'], $field, $this->value['value'], $this->operator);
+  }
+
+  function op_empty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_where($this->options['group'], $field, NULL, $operator);
+  }
+
+  function op_regex($field) {
+    $this->query->add_where($this->options['group'], $field, $this->value, 'RLIKE');
+  }
+
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+
+    $options = $this->operator_options('short');
+    $output = check_plain($options[$this->operator]);
+    if (in_array($this->operator, $this->operator_values(2))) {
+      $output .= ' ' . t('@min and @max', array('@min' => $this->value['min'], '@max' => $this->value['max']));
+    }
+    elseif (in_array($this->operator, $this->operator_values(1))) {
+      $output .= ' ' . check_plain($this->value['value']);
+    }
+    return $output;
+  }
+
+  /**
+   * Do some minor translation of the exposed input
+   */
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // rewrite the input value so that it's in the correct format so that
+    // the parent gets the right data.
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = &$input[$this->options['expose']['identifier']];
+      if (!is_array($value)) {
+        $value = array(
+          'value' => $value,
+        );
+      }
+    }
+
+    $rc = parent::accept_exposed_input($input);
+
+    if (empty($this->options['expose']['required'])) {
+      // We have to do some of our own checking for non-required filters.
+      $info = $this->operators();
+      if (!empty($info[$this->operator]['values'])) {
+        switch ($info[$this->operator]['values']) {
+          case 1:
+            if ($value['value'] === '') {
+              return FALSE;
+            }
+            break;
+          case 2:
+            if ($value['min'] === '' && $value['max'] === '') {
+              return FALSE;
+            }
+            break;
+        }
+      }
+    }
+
+    return $rc;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/filter/StringFilter.php b/lib/Drupal/views/Plugins/views/filter/StringFilter.php
new file mode 100644
index 0000000..8f85b70
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/filter/StringFilter.php
@@ -0,0 +1,342 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\filter\StringFilter.
+ */
+
+namespace Drupal\views\Plugins\views\filter;
+
+use Drupal\Core\Database\Database;
+
+/**
+ * Basic textfield filter to handle string filtering commands
+ * including equality, like, not like, etc.
+ *
+ * @ingroup views_filter_handlers
+ */
+class StringFilter extends FilterPlugin {
+  // exposed filter options
+  var $always_multiple = TRUE;
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['expose']['contains']['required'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * This kind of construct makes it relatively easy for a child class
+   * to add or remove functionality by overriding this function and
+   * adding/removing items from this array.
+   */
+  function operators() {
+    $operators = array(
+      '=' => array(
+        'title' => t('Is equal to'),
+        'short' => t('='),
+        'method' => 'op_equal',
+        'values' => 1,
+      ),
+      '!=' => array(
+        'title' => t('Is not equal to'),
+        'short' => t('!='),
+        'method' => 'op_equal',
+        'values' => 1,
+      ),
+      'contains' => array(
+        'title' => t('Contains'),
+        'short' => t('contains'),
+        'method' => 'op_contains',
+        'values' => 1,
+      ),
+      'word' => array(
+        'title' => t('Contains any word'),
+        'short' => t('has word'),
+        'method' => 'op_word',
+        'values' => 1,
+      ),
+      'allwords' => array(
+        'title' => t('Contains all words'),
+        'short' => t('has all'),
+        'method' => 'op_word',
+        'values' => 1,
+      ),
+      'starts' => array(
+        'title' => t('Starts with'),
+        'short' => t('begins'),
+        'method' => 'op_starts',
+        'values' => 1,
+      ),
+      'not_starts' => array(
+        'title' => t('Does not start with'),
+        'short' => t('not_begins'),
+        'method' => 'op_not_starts',
+        'values' => 1,
+      ),
+      'ends' => array(
+        'title' => t('Ends with'),
+        'short' => t('ends'),
+        'method' => 'op_ends',
+        'values' => 1,
+      ),
+      'not_ends' => array(
+        'title' => t('Does not end with'),
+        'short' => t('not_ends'),
+        'method' => 'op_not_ends',
+        'values' => 1,
+      ),
+      'not' => array(
+        'title' => t('Does not contain'),
+        'short' => t('!has'),
+        'method' => 'op_not',
+        'values' => 1,
+      ),
+      'shorterthan' => array(
+        'title' => t('Length is shorter than'),
+        'short' => t('shorter than'),
+        'method' => 'op_shorter',
+        'values' => 1,
+      ),
+      'longerthan' => array(
+        'title' => t('Length is longer than'),
+        'short' => t('longer than'),
+        'method' => 'op_longer',
+        'values' => 1,
+      ),
+    );
+    // if the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += array(
+        'empty' => array(
+          'title' => t('Is empty (NULL)'),
+          'method' => 'op_empty',
+          'short' => t('empty'),
+          'values' => 0,
+        ),
+        'not empty' => array(
+          'title' => t('Is not empty (NOT NULL)'),
+          'method' => 'op_empty',
+          'short' => t('not empty'),
+          'values' => 0,
+        ),
+      );
+    }
+    // Add regexp support for MySQL.
+    if (Database::getConnection()->databaseType() == 'mysql') {
+      $operators += array(
+        'regular_expression' => array(
+          'title' => t('Regular expression'),
+          'short' => t('regex'),
+          'method' => 'op_regex',
+          'values' => 1,
+        ),
+      );
+    }
+
+    return $operators;
+  }
+
+  /**
+   * Build strings from the operators() for 'select' options
+   */
+  function operator_options($which = 'title') {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      $options[$id] = $info[$which];
+    }
+
+    return $options;
+  }
+
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+
+    $options = $this->operator_options('short');
+    $output = '';
+    if(!empty($options[$this->operator])) {
+      $output = check_plain($options[$this->operator]);
+    }
+    if (in_array($this->operator, $this->operator_values(1))) {
+      $output .= ' ' . check_plain($this->value);
+    }
+    return $output;
+  }
+
+  function operator_values($values = 1) {
+    $options = array();
+    foreach ($this->operators() as $id => $info) {
+      if (isset($info['values']) && $info['values'] == $values) {
+        $options[] = $id;
+      }
+    }
+
+    return $options;
+  }
+
+  /**
+   * Provide a simple textfield for equality
+   */
+  function value_form(&$form, &$form_state) {
+    // We have to make some choices when creating this as an exposed
+    // filter form. For example, if the operator is locked and thus
+    // not rendered, we can't render dependencies; instead we only
+    // render the form items we need.
+    $which = 'all';
+    if (!empty($form['operator'])) {
+      $source = ':input[name="options[operator]"]';
+    }
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+
+      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
+        // exposed and locked.
+        $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none';
+      }
+      else {
+        $source = ':input[name="' . $this->options['expose']['operator_id'] . '"]';
+      }
+    }
+
+    if ($which == 'all' || $which == 'value') {
+      $form['value'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Value'),
+        '#size' => 30,
+        '#default_value' => $this->value,
+      );
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value;
+      }
+
+      if ($which == 'all') {
+        // Setup #states for all operators with one value.
+        foreach ($this->operator_values(1) as $operator) {
+          $form['value']['#states']['visible'][] = array(
+            $source => array('value' => $operator),
+          );
+        }
+      }
+    }
+
+    if (!isset($form['value'])) {
+      // Ensure there is something in the 'value'.
+      $form['value'] = array(
+        '#type' => 'value',
+        '#value' => NULL
+      );
+    }
+  }
+
+  function operator() {
+    return $this->operator == '=' ? 'LIKE' : 'NOT LIKE';
+  }
+
+  /**
+   * Add this filter to the query.
+   *
+   * Due to the nature of fapi, the value and the operator have an unintended
+   * level of indirection. You will find them in $this->operator
+   * and $this->value respectively.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $field = "$this->table_alias.$this->real_field";
+
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+
+  function op_equal($field) {
+    $this->query->add_where($this->options['group'], $field, $this->value, $this->operator());
+  }
+
+  function op_contains($field) {
+    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'LIKE');
+  }
+
+  function op_word($field) {
+    $where = $this->operator == 'word' ? db_or() : db_and();
+
+    // Don't filter on empty strings.
+    if (empty($this->value)) {
+      return;
+    }
+
+    preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER);
+    foreach ($matches as $match) {
+      $phrase = false;
+      // Strip off phrase quotes
+      if ($match[2]{0} == '"') {
+        $match[2] = substr($match[2], 1, -1);
+        $phrase = true;
+      }
+      $words = trim($match[2], ',?!();:-');
+      $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
+      foreach ($words as $word) {
+        $placeholder = $this->placeholder();
+        $where->condition($field, '%' . db_like(trim($word, " ,!?")) . '%', 'LIKE');
+      }
+    }
+
+    if (!$where) {
+      return;
+    }
+
+    // previously this was a call_user_func_array but that's unnecessary
+    // as views will unpack an array that is a single arg.
+    $this->query->add_where($this->options['group'], $where);
+  }
+
+  function op_starts($field) {
+    $this->query->add_where($this->options['group'], $field, db_like($this->value) . '%', 'LIKE');
+  }
+
+  function op_not_starts($field) {
+    $this->query->add_where($this->options['group'], $field, db_like($this->value) . '%', 'NOT LIKE');
+  }
+
+  function op_ends($field) {
+    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value), 'LIKE');
+  }
+
+  function op_not_ends($field) {
+    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value), 'NOT LIKE');
+  }
+
+  function op_not($field) {
+    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'NOT LIKE');
+  }
+
+  function op_shorter($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "LENGTH($field) < $placeholder", array($placeholder => $this->value));
+  }
+
+  function op_longer($field) {
+    $placeholder = $this->placeholder();
+    $this->query->add_where_expression($this->options['group'], "LENGTH($field) > $placeholder", array($placeholder => $this->value));
+  }
+
+  function op_regex($field) {
+    $this->query->add_where($this->options['group'], $field, $this->value, 'RLIKE');
+  }
+
+  function op_empty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_where($this->options['group'], $field, NULL, $operator);
+  }
+
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/ArgumentPlugin.php b/lib/Drupal/views/Plugins/views/handler/ArgumentPlugin.php
new file mode 100644
index 0000000..e701621
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/ArgumentPlugin.php
@@ -0,0 +1,1272 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\ArgumentPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+use Drupal\views\Plugins\Plugin;
+
+/**
+ * @defgroup views_argument_handlers Views argument handlers
+ * Handlers to tell Views how to contextually filter queries.
+ * @{
+ */
+
+/**
+ * Base class for arguments.
+ *
+ * The basic argument works for very simple arguments such as nid and uid
+ *
+ * Definition terms for this handler:
+ * - name field: The field to use for the name to use in the summary, which is
+ *               the displayed output. For example, for the node: nid argument,
+ *               the argument itself is the nid, but node.title is displayed.
+ * - name table: The table to use for the name, should it not be in the same
+ *               table as the argument.
+ * - empty field name: For arguments that can have no value, such as taxonomy
+ *                     which can have "no term", this is the string which
+ *                     will be displayed for this lack of value. Be sure to use
+ *                     t().
+ * - validate type: A little used string to allow an argument to restrict
+ *                  which validator is available to just one. Use the
+ *                  validator ID. This probably should not be used at all,
+ *                  and may disappear or change.
+ * - numeric: If set to TRUE this field is numeric and will use %d instead of
+ *            %s in queries.
+ *
+ * @ingroup views_argument_handlers
+ */
+class ArgumentPlugin extends Plugin {
+  var $validator = NULL;
+  var $argument = NULL;
+  var $value = NULL;
+
+  /**
+   * The table to use for the name, should it not be in the same table as the argument.
+   * @var string
+   */
+  var $name_table;
+
+  /**
+   * The field to use for the name to use in the summary, which is
+   * the displayed output. For example, for the node: nid argument,
+   * the argument itself is the nid, but node.title is displayed.
+   * @var string
+   */
+  var $name_field;
+
+  /**
+   * Constructor
+   */
+  function construct() {
+    parent::construct();
+
+    if (!empty($this->definition['name field'])) {
+      $this->name_field = $this->definition['name field'];
+    }
+    if (!empty($this->definition['name table'])) {
+      $this->name_table = $this->definition['name table'];
+    }
+  }
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Compatibility: The new UI changed several settings.
+    if (!empty($options['wildcard']) && !isset($options['exception']['value'])) {
+      $this->options['exception']['value'] = $options['wildcard'];
+    }
+    if (!empty($options['wildcard_substitution']) && !isset($options['exception']['title'])) {
+      // Enable the checkbox if the title is filled in.
+      $this->options['exception']['title_enable'] = 1;
+      $this->options['exception']['title'] = $options['wildcard_substitution'];
+    }
+
+    if (!isset($options['summary']['format']) && !empty($options['style_plugin'])) {
+      $this->options['summary']['format'] = $options['style_plugin'];
+    }
+
+    // Setup default value.
+    $options['style_options'] = isset($options['style_options']) ? $options['style_options'] : array();
+
+    if (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary asc') {
+      $this->options['default_action'] = 'summary';
+      $this->options['summary']['sort_order'] = 'asc';
+      $this->options['summary']['number_of_records'] = 0;
+      $this->options['summary_options'] = $options['style_options'];
+    }
+    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary desc') {
+      $this->options['default_action'] = 'summary';
+      $this->options['summary']['sort_order'] = 'desc';
+      $this->options['summary']['number_of_records'] = 0;
+      $this->options['summary_options'] = $options['style_options'];
+    }
+    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary asc by count') {
+      $this->options['default_action'] = 'summary';
+      $this->options['summary']['sort_order'] = 'asc';
+      $this->options['summary']['number_of_records'] = 1;
+      $this->options['summary_options'] = $options['style_options'];
+    }
+    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary desc by count') {
+      $this->options['default_action'] = 'summary';
+      $this->options['summary']['sort_order'] = 'desc';
+      $this->options['summary']['number_of_records'] = 1;
+      $this->options['summary_options'] = $options['style_options'];
+    }
+
+    if (!empty($options['title']) && !isset($options['title_enable'])) {
+      $this->options['title_enable'] = 1;
+    }
+    if (!empty($options['breadcrumb']) && !isset($options['breadcrumb_enable'])) {
+      $this->options['breadcrumb_enable'] = 1;
+    }
+
+    if (!empty($options['validate_type']) && !isset($options['validate']['type'])) {
+      $this->options['validate']['type'] = $options['validate_type'];
+      $this->options['specify_validation'] = 1;
+    }
+    if (!empty($options['validate_fail']) && !isset($options['validate']['fail'])) {
+      $this->options['validate']['fail'] = $options['validate_fail'];
+      $this->options['specify_validation'] = 1;
+    }
+  }
+
+  /**
+   * Give an argument the opportunity to modify the breadcrumb, if it wants.
+   * This only gets called on displays where a breadcrumb is actually used.
+   *
+   * The breadcrumb will be in the form of an array, with the keys being
+   * the path and the value being the already sanitized title of the path.
+   */
+  function set_breadcrumb(&$breadcrumb) { }
+
+  /**
+   * Determine if the argument can generate a breadcrumb
+   *
+   * @return TRUE/FALSE
+   */
+  function uses_breadcrumb() {
+    $info = $this->default_actions($this->options['default_action']);
+    return !empty($info['breadcrumb']);
+  }
+
+  function is_exception($arg = NULL) {
+    if (!isset($arg)) {
+      $arg = isset($this->argument) ? $this->argument : NULL;
+    }
+    return !empty($this->options['exception']['value']) && $this->options['exception']['value'] === $arg;
+  }
+
+  function exception_title() {
+    // If title overriding is off for the exception, return the normal title.
+    if (empty($this->options['exception']['title_enable'])) {
+      return $this->get_title();
+    }
+    return $this->options['exception']['title'];
+  }
+
+  /**
+   * Determine if the argument needs a style plugin.
+   *
+   * @return TRUE/FALSE
+   */
+  function needs_style_plugin() {
+    $info = $this->default_actions($this->options['default_action']);
+    $validate_info = $this->default_actions($this->options['validate']['fail']);
+    return !empty($info['style plugin']) || !empty($validate_info['style plugin']);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['default_action'] = array('default' => 'ignore');
+    $options['exception'] = array(
+      'contains' => array(
+        'value' => array('default' => 'all'),
+        'title_enable' => array('default' => FALSE, 'bool' => TRUE),
+        'title' => array('default' => t('All'), 'translatable' => TRUE),
+      ),
+    );
+    $options['title_enable'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['title'] = array('default' => '', 'translatable' => TRUE);
+    $options['breadcrumb_enable'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE);
+    $options['default_argument_type'] = array('default' => 'fixed', 'export' => 'export_plugin');
+    $options['default_argument_options'] = array('default' => array(), 'export' => FALSE);
+    $options['default_argument_skip_url'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['summary_options'] = array('default' => array(), 'export' => FALSE);
+    $options['summary'] = array(
+      'contains' => array(
+        'sort_order' => array('default' => 'asc'),
+        'number_of_records' => array('default' => 0),
+        'format' => array('default' => 'default_summary', 'export' => 'export_summary'),
+      ),
+    );
+    $options['specify_validation'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['validate'] = array(
+      'contains' => array(
+        'type' => array('default' => 'none', 'export' => 'export_validation'),
+        'fail' => array('default' => 'not found'),
+      ),
+    );
+    $options['validate_options'] = array('default' => array(), 'export' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $argument_text = $this->view->display_handler->get_argument_text();
+
+    $form['#pre_render'][] = 'views_ui_pre_render_move_argument_options';
+
+    $form['description'] = array(
+      '#markup' => $argument_text['description'],
+      '#theme_wrappers' => array('container'),
+      '#attributes' => array('class' => array('description')),
+    );
+
+    $form['no_argument'] = array(
+      '#type' => 'fieldset',
+      '#title' => $argument_text['filter value not present'],
+    );
+    // Everything in the fieldset is floated, so the last element needs to
+    // clear those floats.
+    $form['no_argument']['clearfix'] = array(
+      '#weight' => 1000,
+      '#markup' => '<div class="clearfix"></div>',
+    );
+    $form['default_action'] = array(
+      '#type' => 'radios',
+      '#process' => array('views_ui_process_container_radios'),
+      '#default_value' => $this->options['default_action'],
+      '#fieldset' => 'no_argument',
+    );
+
+    $form['exception'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Exceptions'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#fieldset' => 'no_argument',
+    );
+    $form['exception']['value'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Exception value'),
+      '#size' => 20,
+      '#default_value' => $this->options['exception']['value'],
+      '#description' => t('If this value is received, the filter will be ignored; i.e, "all values"'),
+    );
+    $form['exception']['title_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Override title'),
+      '#default_value' => $this->options['exception']['title_enable'],
+    );
+    $form['exception']['title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Override title'),
+      '#title_display' => 'invisible',
+      '#size' => 20,
+      '#default_value' => $this->options['exception']['title'],
+      '#description' => t('Override the view and other argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[exception][title_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $options = array();
+    $defaults = $this->default_actions();
+    $validate_options = array();
+    foreach ($defaults as $id => $info) {
+      $options[$id] = $info['title'];
+      if (empty($info['default only'])) {
+        $validate_options[$id] = $info['title'];
+      }
+      if (!empty($info['form method'])) {
+        $this->{$info['form method']}($form, $form_state);
+      }
+    }
+    $form['default_action']['#options'] = $options;
+
+    $form['argument_present'] = array(
+      '#type' => 'fieldset',
+      '#title' => $argument_text['filter value present'],
+    );
+    $form['title_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Override title'),
+      '#default_value' => $this->options['title_enable'],
+      '#fieldset' => 'argument_present',
+    );
+    $form['title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Provide title'),
+      '#title_display' => 'invisible',
+      '#default_value' => $this->options['title'],
+      '#description' => t('Override the view and other argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[title_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'argument_present',
+    );
+
+    $form['breadcrumb_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Override breadcrumb'),
+      '#default_value' => $this->options['breadcrumb_enable'],
+      '#fieldset' => 'argument_present',
+    );
+    $form['breadcrumb'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Provide breadcrumb'),
+      '#title_display' => 'invisible',
+      '#default_value' => $this->options['breadcrumb'],
+      '#description' => t('Enter a breadcrumb name you would like to use. See "Title" for percent substitutions.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[breadcrumb_enable]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'argument_present',
+    );
+
+    $form['specify_validation'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Specify validation criteria'),
+      '#default_value' => $this->options['specify_validation'],
+      '#fieldset' => 'argument_present',
+    );
+
+    $form['validate'] = array(
+      '#type' => 'container',
+      '#fieldset' => 'argument_present',
+    );
+    // @todo The mockup wanted to use "Validate using" here, but it doesn't
+    // work well with many options (they'd need to be changed as well)
+    $form['validate']['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Validator'),
+      '#default_value' => $this->options['validate']['type'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[specify_validation]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $validate_types = array('none' => t('- Basic validation -'));
+    $plugins = views_fetch_plugin_data('argument validator');
+    foreach ($plugins as $id => $info) {
+      if (!empty($info['no ui'])) {
+        continue;
+      }
+
+      $valid = TRUE;
+      if (!empty($info['type'])) {
+        $valid = FALSE;
+        if (empty($this->definition['validate type'])) {
+          continue;
+        }
+        foreach ((array) $info['type'] as $type) {
+          if ($type == $this->definition['validate type']) {
+            $valid = TRUE;
+            break;
+          }
+        }
+      }
+
+      // If we decide this validator is ok, add it to the list.
+      if ($valid) {
+        $plugin = $this->get_plugin('argument validator', $id);
+        if ($plugin) {
+          if ($plugin->access() || $this->options['validate']['type'] == $id) {
+            $form['validate']['options'][$id] = array(
+              '#prefix' => '<div id="edit-options-validate-options-' . $id . '-wrapper">',
+              '#suffix' => '</div>',
+              '#type' => 'item',
+              // Even if the plugin has no options add the key to the form_state.
+              '#input' => TRUE, // trick it into checking input to make #process run
+              '#states' => array(
+                'visible' => array(
+                  ':input[name="options[specify_validation]"]' => array('checked' => TRUE),
+                  ':input[name="options[validate][type]"]' => array('value' => $id),
+                ),
+              ),
+              '#id' => 'edit-options-validate-options-' . $id,
+            );
+            $plugin->options_form($form['validate']['options'][$id], $form_state);
+            $validate_types[$id] = $info['title'];
+          }
+        }
+      }
+    }
+
+    asort($validate_types);
+    $form['validate']['type']['#options'] = $validate_types;
+
+    $form['validate']['fail'] = array(
+      '#type' => 'select',
+      '#title' => t('Action to take if filter value does not validate'),
+      '#default_value' => $this->options['validate']['fail'],
+      '#options' => $validate_options,
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[specify_validation]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'argument_present',
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    if (empty($form_state['values']['options'])) {
+      return;
+    }
+
+    // Let the plugins do validation.
+    $default_id = $form_state['values']['options']['default_argument_type'];
+    $plugin = $this->get_plugin('argument default', $default_id);
+    if ($plugin) {
+      $plugin->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]);
+    }
+
+    // summary plugin
+    $summary_id = $form_state['values']['options']['summary']['format'];
+    $plugin = $this->get_plugin('style', $summary_id);
+    if ($plugin) {
+      $plugin->options_validate($form['summary']['options'][$summary_id], $form_state, $form_state['values']['options']['summary']['options'][$summary_id]);
+    }
+
+    $validate_id = $form_state['values']['options']['validate']['type'];
+    $plugin = $this->get_plugin('argument validator', $validate_id);
+    if ($plugin) {
+      $plugin->options_validate($form['validate']['options'][$default_id], $form_state, $form_state['values']['options']['validate']['options'][$validate_id]);
+    }
+
+  }
+
+  function options_submit(&$form, &$form_state) {
+    if (empty($form_state['values']['options'])) {
+      return;
+    }
+
+    // Let the plugins make submit modifications if necessary.
+    $default_id = $form_state['values']['options']['default_argument_type'];
+    $plugin = $this->get_plugin('argument default', $default_id);
+    if ($plugin) {
+      $options = &$form_state['values']['options']['argument_default'][$default_id];
+      $plugin->options_submit($form['argument_default'][$default_id], $form_state, $options);
+      // Copy the now submitted options to their final resting place so they get saved.
+      $form_state['values']['options']['default_argument_options'] = $options;
+    }
+
+    // summary plugin
+    $summary_id = $form_state['values']['options']['summary']['format'];
+    $plugin = $this->get_plugin('style', $summary_id);
+    if ($plugin) {
+      $options = &$form_state['values']['options']['summary']['options'][$summary_id];
+      $plugin->options_submit($form['summary']['options'][$summary_id], $form_state, $options);
+      // Copy the now submitted options to their final resting place so they get saved.
+      $form_state['values']['options']['summary_options'] = $options;
+    }
+
+    $validate_id = $form_state['values']['options']['validate']['type'];
+    $plugin = $this->get_plugin('argument validator', $validate_id);
+    if ($plugin) {
+      $options = &$form_state['values']['options']['validate']['options'][$validate_id];
+      $plugin->options_submit($form['validate']['options'][$validate_id], $form_state, $options);
+      // Copy the now submitted options to their final resting place so they get saved.
+      $form_state['values']['options']['validate_options'] = $options;
+    }
+
+    // Clear out the content of title if it's not enabled.
+    $options =& $form_state['values']['options'];
+    if (empty($options['title_enable'])) {
+      $options['title'] = '';
+    }
+  }
+
+  /**
+   * Provide a list of default behaviors for this argument if the argument
+   * is not present.
+   *
+   * Override this method to provide additional (or fewer) default behaviors.
+   */
+  function default_actions($which = NULL) {
+    $defaults = array(
+      'ignore' => array(
+        'title' => t('Display all results for the specified field'),
+        'method' => 'default_ignore',
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
+      'default' => array(
+        'title' => t('Provide default value'),
+        'method' => 'default_default',
+        'form method' => 'default_argument_form',
+        'has default argument' => TRUE,
+        'default only' => TRUE, // this can only be used for missing argument, not validation failure
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
+      'not found' => array(
+        'title' => t('Hide view'),
+        'method' => 'default_not_found',
+        'hard fail' => TRUE, // This is a hard fail condition
+      ),
+      'summary' => array(
+        'title' => t('Display a summary'),
+        'method' => 'default_summary',
+        'form method' => 'default_summary_form',
+        'style plugin' => TRUE,
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
+      'empty' => array(
+        'title' => t('Display contents of "No results found"'),
+        'method' => 'default_empty',
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
+      'access denied' => array(
+        'title' => t('Display "Access Denied"'),
+        'method' => 'default_access_denied',
+        'breadcrumb' => FALSE, // generate a breadcrumb to here
+      ),
+    );
+
+    if ($this->view->display_handler->has_path()) {
+      $defaults['not found']['title'] = t('Show "Page not found"');
+    }
+
+    if ($which) {
+      if (!empty($defaults[$which])) {
+        return $defaults[$which];
+      }
+    }
+    else {
+      return $defaults;
+    }
+  }
+
+  /**
+   * Provide a form for selecting the default argument when the
+   * default action is set to provide default argument.
+   */
+  function default_argument_form(&$form, &$form_state) {
+    $plugins = views_fetch_plugin_data('argument default');
+    $options = array();
+
+    $form['default_argument_skip_url'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Skip default argument for view URL'),
+      '#default_value' => $this->options['default_argument_skip_url'],
+      '#description' => t('Select whether to include this default argument when constructing the URL for this view. Skipping default arguments is useful e.g. in the case of feeds.')
+    );
+
+    $form['default_argument_type'] = array(
+      '#prefix' => '<div id="edit-options-default-argument-type-wrapper">',
+      '#suffix' => '</div>',
+      '#type' => 'select',
+      '#id' => 'edit-options-default-argument-type',
+      '#title' => t('Type'),
+      '#default_value' => $this->options['default_argument_type'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'default'),
+        ),
+      ),
+      // Views custom key, moves this element to the appropriate container
+      // under the radio button.
+      '#argument_option' => 'default',
+    );
+
+    foreach ($plugins as $id => $info) {
+      if (!empty($info['no ui'])) {
+        continue;
+      }
+      $plugin = $this->get_plugin('argument default', $id);
+      if ($plugin) {
+        if ($plugin->access() || $this->options['default_argument_type'] == $id) {
+          $form['argument_default']['#argument_option'] = 'default';
+          $form['argument_default'][$id] = array(
+            '#prefix' => '<div id="edit-options-argument-default-options-' . $id . '-wrapper">',
+            '#suffix' => '</div>',
+            '#id' => 'edit-options-argument-default-options-' . $id,
+            '#type' => 'item',
+            // Even if the plugin has no options add the key to the form_state.
+            '#input' => TRUE,
+            '#states' => array(
+              'visible' => array(
+                ':input[name="options[default_action]"]' => array('value' => 'default'),
+                ':input[name="options[default_argument_type]"]' => array('value' => $id),
+              ),
+            ),
+          );
+          $options[$id] = $info['title'];
+          $plugin->options_form($form['argument_default'][$id], $form_state);
+        }
+      }
+    }
+
+    asort($options);
+    $form['default_argument_type']['#options'] = $options;
+  }
+
+  /**
+   * Provide a form for selecting further summary options when the
+   * default action is set to display one.
+   */
+  function default_summary_form(&$form, &$form_state) {
+    $style_plugins = views_fetch_plugin_data('style');
+    $summary_plugins = array();
+    $format_options = array();
+    foreach ($style_plugins as $key => $plugin) {
+      if (isset($plugin['type']) && $plugin['type'] == 'summary') {
+        $summary_plugins[$key] = $plugin;
+        $format_options[$key] = $plugin['title'];
+      }
+    }
+
+    $form['summary'] = array(
+      // Views custom key, moves this element to the appropriate container
+      // under the radio button.
+      '#argument_option' => 'summary',
+    );
+    $form['summary']['sort_order'] = array(
+      '#type' => 'radios',
+      '#title' => t('Sort order'),
+      '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')),
+      '#default_value' => $this->options['summary']['sort_order'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'summary'),
+        ),
+      ),
+    );
+    $form['summary']['number_of_records'] = array(
+      '#type' => 'radios',
+      '#title' => t('Sort by'),
+      '#default_value' => $this->options['summary']['number_of_records'],
+      '#options' => array(
+        0 => $this->get_sort_name(),
+        1 => t('Number of records')
+      ),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'summary'),
+        ),
+      ),
+    );
+
+    $form['summary']['format'] = array(
+      '#type' => 'radios',
+      '#title' => t('Format'),
+      '#options' => $format_options,
+      '#default_value' => $this->options['summary']['format'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[default_action]"]' => array('value' => 'summary'),
+        ),
+      ),
+    );
+
+    foreach ($summary_plugins as $id => $info) {
+      if (empty($info['uses options'])) {
+        continue;
+      }
+      $plugin = $this->get_plugin('style', $id);
+      if ($plugin) {
+        $form['summary']['options'][$id] = array(
+          '#prefix' => '<div id="edit-options-summary-options-' . $id . '-wrapper">',
+          '#suffix' => '</div>',
+          '#id' => 'edit-options-summary-options-' . $id,
+          '#type' => 'item',
+          '#input' => TRUE, // trick it into checking input to make #process run
+          '#states' => array(
+            'visible' => array(
+              ':input[name="options[default_action]"]' => array('value' => 'summary'),
+              ':input[name="options[summary][format]"]' => array('value' => $id),
+            ),
+          ),
+        );
+        $options[$id] = $info['title'];
+        $plugin->options_form($form['summary']['options'][$id], $form_state);
+      }
+    }
+  }
+
+  /**
+   * Handle the default action, which means our argument wasn't present.
+   *
+   * Override this method only with extreme care.
+   *
+   * @return
+   *   A boolean value; if TRUE, continue building this view. If FALSE,
+   *   building the view will be aborted here.
+   */
+  function default_action($info = NULL) {
+    if (!isset($info)) {
+      $info = $this->default_actions($this->options['default_action']);
+    }
+
+    if (!$info) {
+      return FALSE;
+    }
+
+    if (!empty($info['method args'])) {
+      return call_user_func_array(array(&$this, $info['method']), $info['method args']);
+    }
+    else {
+      return $this->{$info['method']}();
+    }
+  }
+
+  /**
+   * How to act if validation failes
+   */
+  function validate_fail() {
+    $info = $this->default_actions($this->options['validate']['fail']);
+    return $this->default_action($info);
+  }
+  /**
+   * Default action: ignore.
+   *
+   * If an argument was expected and was not given, in this case, simply
+   * ignore the argument entirely.
+   */
+  function default_ignore() {
+    return TRUE;
+  }
+
+  /**
+   * Default action: not found.
+   *
+   * If an argument was expected and was not given, in this case, report
+   * the view as 'not found' or hide it.
+   */
+  function default_not_found() {
+    // Set a failure condition and let the display manager handle it.
+    $this->view->build_info['fail'] = TRUE;
+    return FALSE;
+  }
+
+  /**
+   * Default action: access denied.
+   *
+   * If an argument was expected and was not given, in this case, report
+   * the view as 'access denied'.
+   */
+  function default_access_denied() {
+    $this->view->build_info['denied'] = TRUE;
+    return FALSE;
+  }
+
+  /**
+   * Default action: empty
+   *
+   * If an argument was expected and was not given, in this case, display
+   * the view's empty text
+   */
+  function default_empty() {
+    // We return with no query; this will force the empty text.
+    $this->view->built = TRUE;
+    $this->view->executed = TRUE;
+    $this->view->result = array();
+    return FALSE;
+  }
+
+  /**
+   * This just returns true. The view argument builder will know where
+   * to find the argument from.
+   */
+  function default_default() {
+    return TRUE;
+  }
+
+  /**
+   * Determine if the argument is set to provide a default argument.
+   */
+  function has_default_argument() {
+    $info = $this->default_actions($this->options['default_action']);
+    return !empty($info['has default argument']);
+  }
+
+  /**
+   * Get a default argument, if available.
+   */
+  function get_default_argument() {
+    $plugin = $this->get_plugin('argument default');
+    if ($plugin) {
+      return $plugin->get_argument();
+    }
+  }
+
+  /**
+   * Process the summary arguments for display.
+   *
+   * For example, the validation plugin may want to alter an argument for use in
+   * the URL.
+   */
+  function process_summary_arguments(&$args) {
+    if ($this->options['validate']['type'] != 'none') {
+      if (isset($this->validator) || $this->validator = $this->get_plugin('argument validator')) {
+        $this->validator->process_summary_arguments($args);
+      }
+    }
+  }
+
+  /**
+   * Default action: summary.
+   *
+   * If an argument was expected and was not given, in this case, display
+   * a summary query.
+   */
+  function default_summary() {
+    $this->view->build_info['summary'] = TRUE;
+    $this->view->build_info['summary_level'] = $this->options['id'];
+
+    // Change the display style to the summary style for this
+    // argument.
+    $this->view->plugin_name = $this->options['summary']['format'];
+    $this->view->style_options = $this->options['summary_options'];
+
+    // Clear out the normal primary field and whatever else may have
+    // been added and let the summary do the work.
+    $this->query->clear_fields();
+    $this->summary_query();
+
+    $by = $this->options['summary']['number_of_records'] ? 'num_records' : NULL;
+    $this->summary_sort($this->options['summary']['sort_order'], $by);
+
+    // Summaries have their own sorting and fields, so tell the View not
+    // to build these.
+    $this->view->build_sort = $this->view->build_fields = FALSE;
+    return TRUE;
+  }
+
+  /**
+   * Build the info for the summary query.
+   *
+   * This must:
+   * - add_groupby: group on this field in order to create summaries.
+   * - add_field: add a 'num_nodes' field for the count. Usually it will
+   *   be a count on $view->base_field
+   * - set_count_field: Reset the count field so we get the right paging.
+   *
+   * @return
+   *   The alias used to get the number of records (count) for this entry.
+   */
+  function summary_query() {
+    $this->ensure_my_table();
+    // Add the field.
+    $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
+
+    $this->summary_name_field();
+    return $this->summary_basics();
+  }
+
+  /**
+   * Add the name field, which is the field displayed in summary queries.
+   * This is often used when the argument is numeric.
+   */
+  function summary_name_field() {
+    // Add the 'name' field. For example, if this is a uid argument, the
+    // name field would be 'name' (i.e, the username).
+
+    if (isset($this->name_table)) {
+      // if the alias is different then we're probably added, not ensured,
+      // so look up the join and add it instead.
+      if ($this->table_alias != $this->name_table) {
+        $j = views_get_table_join($this->name_table, $this->table);
+        if ($j) {
+          $join = clone $j;
+          $join->left_table = $this->table_alias;
+          $this->name_table_alias = $this->query->add_table($this->name_table, $this->relationship, $join);
+        }
+      }
+      else {
+        $this->name_table_alias = $this->query->ensure_table($this->name_table, $this->relationship);
+      }
+    }
+    else {
+      $this->name_table_alias = $this->table_alias;
+    }
+
+    if (isset($this->name_field)) {
+      $this->name_alias = $this->query->add_field($this->name_table_alias, $this->name_field);
+    }
+    else {
+      $this->name_alias = $this->base_alias;
+    }
+  }
+
+  /**
+   * Some basic summary behavior that doesn't need to be repeated as much as
+   * code that goes into summary_query()
+   */
+  function summary_basics($count_field = TRUE) {
+    // Add the number of nodes counter
+    $distinct = ($this->view->display_handler->get_option('distinct') && empty($this->query->no_distinct));
+
+    $count_alias = $this->query->add_field($this->query->base_table, $this->query->base_field, 'num_records',
+                                           array('count' => TRUE, 'distinct' => $distinct));
+    $this->query->add_groupby($this->name_alias);
+
+    if ($count_field) {
+      $this->query->set_count_field($this->table_alias, $this->real_field);
+    }
+
+    $this->count_alias = $count_alias;
+  }
+
+  /**
+   * Sorts the summary based upon the user's selection. The base variant of
+   * this is usually adequte.
+   *
+   * @param $order
+   *   The order selected in the UI.
+   */
+  function summary_sort($order, $by = NULL) {
+    $this->query->add_orderby(NULL, NULL, $order, (!empty($by) ? $by : $this->name_alias));
+  }
+
+  /**
+   * Provide the argument to use to link from the summary to the next level;
+   * this will be called once per row of a summary, and used as part of
+   * $view->get_url().
+   *
+   * @param $data
+   *   The query results for the row.
+   */
+  function summary_argument($data) {
+    return $data->{$this->base_alias};
+  }
+
+  /**
+   * Provides the name to use for the summary. By default this is just
+   * the name field.
+   *
+   * @param $data
+   *   The query results for the row.
+   */
+  function summary_name($data) {
+    $value = $data->{$this->name_alias};
+    if (empty($value) && !empty($this->definition['empty field name'])) {
+      $value = $this->definition['empty field name'];
+    }
+    return check_plain($value);
+  }
+
+  /**
+   * Set up the query for this argument.
+   *
+   * The argument sent may be found at $this->argument.
+   */
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+    $this->query->add_where(0, "$this->table_alias.$this->real_field", $this->argument);
+  }
+
+  /**
+   * Get the title this argument will assign the view, given the argument.
+   *
+   * This usually needs to be overridden to provide a proper title.
+   */
+  function title() {
+    return check_plain($this->argument);
+  }
+
+  /**
+   * Called by the view object to get the title. This may be set by a
+   * validator so we don't necessarily call through to title().
+   */
+  function get_title() {
+    if (isset($this->validated_title)) {
+      return $this->validated_title;
+    }
+    else {
+      return $this->title();
+    }
+  }
+
+  /**
+   * Validate that this argument works. By default, all arguments are valid.
+   */
+  function validate_arg($arg) {
+    // By using % in URLs, arguments could be validated twice; this eases
+    // that pain.
+    if (isset($this->argument_validated)) {
+      return $this->argument_validated;
+    }
+
+    if ($this->is_exception($arg)) {
+      return $this->argument_validated = TRUE;
+    }
+
+    if ($this->options['validate']['type'] == 'none') {
+      return $this->argument_validated = $this->validate_argument_basic($arg);
+    }
+
+    $plugin = $this->get_plugin('argument validator');
+    if ($plugin) {
+      return $this->argument_validated = $plugin->validate_argument($arg);
+    }
+
+    // If the plugin isn't found, fall back to the basic validation path:
+    return $this->argument_validated = $this->validate_argument_basic($arg);
+  }
+
+  /**
+   * Called by the menu system to validate an argument.
+   *
+   * This checks to see if this is a 'soft fail', which means that if the
+   * argument fails to validate, but there is an action to take anyway,
+   * then validation cannot actually fail.
+   */
+  function validate_argument($arg) {
+    $validate_info = $this->default_actions($this->options['validate']['fail']);
+    if (empty($validate_info['hard fail'])) {
+      return TRUE;
+    }
+
+    $rc = $this->validate_arg($arg);
+
+    // If the validator has changed the validate fail condition to a
+    // soft fail, deal with that:
+    $validate_info = $this->default_actions($this->options['validate']['fail']);
+    if (empty($validate_info['hard fail'])) {
+      return TRUE;
+    }
+
+    return $rc;
+  }
+
+  /**
+   * Provide a basic argument validation.
+   *
+   * This can be overridden for more complex types; the basic
+   * validator only checks to see if the argument is not NULL
+   * or is numeric if the definition says it's numeric.
+   */
+  function validate_argument_basic($arg) {
+    if (!isset($arg) || $arg === '') {
+      return FALSE;
+    }
+
+    if (!empty($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
+  /**
+   * Set the input for this argument
+   *
+   * @return TRUE if it successfully validates; FALSE if it does not.
+   */
+  function set_argument($arg) {
+    $this->argument = $arg;
+    return $this->validate_arg($arg);
+  }
+
+  /**
+   * Get the value of this argument.
+   */
+  function get_value() {
+    // If we already processed this argument, we're done.
+    if (isset($this->argument)) {
+      return $this->argument;
+    }
+
+    // Otherwise, we have to pretend to process ourself to find the value.
+    $value = NULL;
+    // Find the position of this argument within the view.
+    $position = 0;
+    foreach ($this->view->argument as $id => $argument) {
+      if ($id == $this->options['id']) {
+        break;
+      }
+      $position++;
+    }
+
+    $arg = isset($this->view->args[$position]) ? $this->view->args[$position] : NULL;
+    $this->position = $position;
+
+    // Clone ourselves so that we don't break things when we're really
+    // processing the arguments.
+    $argument = clone $this;
+    if (!isset($arg) && $argument->has_default_argument()) {
+      $arg = $argument->get_default_argument();
+
+      // remember that this argument was computed, not passed on the URL.
+      $this->is_default = TRUE;
+    }
+    // Set the argument, which will also validate that the argument can be set.
+    if ($argument->set_argument($arg)) {
+      $value = $argument->argument;
+    }
+    unset($argument);
+    return $value;
+  }
+
+  /**
+   * Export handler for summary export.
+   *
+   * Arguments can have styles for the summary view. This special export
+   * handler makes sure this works properly.
+   */
+  function export_summary($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $name = $this->options['summary'][$option];
+    $options = $this->options['summary_options'];
+
+    $plugin = views_get_plugin('style', $name);
+    if ($plugin) {
+      $plugin->init($this->view, $this->view->display_handler->display, $options);
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['summary']['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['summary_options']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Export handler for validation export.
+   *
+   * Arguments use validation plugins. This special export handler makes sure
+   * this works properly.
+   */
+  function export_validation($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $name = $this->options['validate'][$option];
+    $options = $this->options['validate_options'];
+
+    $plugin = views_get_plugin('argument validator', $name);
+    if ($plugin) {
+      $plugin->init($this->view, $this->display, $options);
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['validate']['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['validate_options']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Generic plugin export handler.
+   *
+   * Since style and validation plugins have their own export handlers, this
+   * one is currently only used for default argument plugins.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    if ($option == 'default_argument_type') {
+      $type = 'argument default';
+      $option_name = 'default_argument_options';
+    }
+
+    $plugin = $this->get_plugin($type);
+    $name = $this->options[$option];
+
+    if ($plugin) {
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['$option_name']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Get the display or row plugin, if it exists.
+   */
+  function get_plugin($type = 'argument default', $name = NULL) {
+    $options = array();
+    switch ($type) {
+      case 'argument default':
+        $plugin_name = $this->options['default_argument_type'];
+        $options_name = 'default_argument_options';
+        break;
+      case 'argument validator':
+        $plugin_name = $this->options['validate']['type'];
+        $options_name = 'validate_options';
+        break;
+      case 'style':
+        $plugin_name = $this->options['summary']['format'];
+        $options_name = 'summary_options';
+    }
+
+    if (!$name) {
+      $name = $plugin_name;
+    }
+
+    // we only fetch the options if we're fetching the plugin actually
+    // in use.
+    if ($name == $plugin_name) {
+      $options = $this->options[$options_name];
+    }
+
+    $plugin = views_get_plugin($type, $name);
+    if ($plugin) {
+      // Style plugins expects different parameters as argument related plugins.
+      if ($type == 'style') {
+        $plugin->init($this->view, $this->view->display_handler->display, $options);
+      }
+      else {
+        $plugin->init($this->view, $this, $options);
+      }
+      return $plugin;
+    }
+  }
+
+  /**
+   * Return a description of how the argument would normally be sorted.
+   *
+   * Subclasses should override this to specify what the default sort order of
+   * their argument is (e.g. alphabetical, numeric, date).
+   */
+  function get_sort_name() {
+    return t('Default sort', array(), array('context' => 'Sort order'));
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_broken extends views_handler_argument {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query($group_by = FALSE) { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/handler/DateArgument.php b/lib/Drupal/views/Plugins/views/handler/DateArgument.php
new file mode 100644
index 0000000..4b23a90
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/DateArgument.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\DateArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Abstract argument handler for dates.
+ *
+ * Adds an option to set a default argument based on the current date.
+ *
+ * @param $arg_format
+ *   The format string to use on the current time when
+ *   creating a default date argument.
+ *
+ * Definitions terms:
+ * - many to one: If true, the "many to one" helper will be used.
+ * - invalid input: A string to give to the user for obviously invalid input.
+ *                  This is deprecated in favor of argument validators.
+ *
+ * @see views_many_to_one_helper()
+ *
+ * @ingroup views_argument_handlers
+ */
+class DateArgument extends ArgumentPlugin {
+  var $option_name = 'default_argument_date';
+  var $arg_format = 'Y-m-d';
+
+  /**
+   * Add an option to set the default value to the current date.
+   */
+  function default_argument_form(&$form, &$form_state) {
+    parent::default_argument_form($form, $form_state);
+    $form['default_argument_type']['#options'] += array('date' => t('Current date'));
+    $form['default_argument_type']['#options'] += array('node_created' => t("Current node's creation time"));
+    $form['default_argument_type']['#options'] += array('node_changed' => t("Current node's update time"));  }
+
+  /**
+   * Set the empty argument value to the current date,
+   * formatted appropriately for this argument.
+   */
+  function get_default_argument($raw = FALSE) {
+    if (!$raw && $this->options['default_argument_type'] == 'date') {
+      return date($this->arg_format, REQUEST_TIME);
+    }
+    else if (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) {
+      foreach (range(1, 3) as $i) {
+        $node = menu_get_object('node', $i);
+        if (!empty($node)) {
+          continue;
+        }
+      }
+
+      if (arg(0) == 'node' && is_numeric(arg(1))) {
+        $node = node_load(arg(1));
+      }
+
+      if (empty($node)) {
+        return parent::get_default_argument();
+      }
+      elseif ($this->options['default_argument_type'] == 'node_created') {
+        return date($this->arg_format, $node->created);
+      }
+      elseif ($this->options['default_argument_type'] == 'node_changed') {
+        return date($this->arg_format, $node->changed);
+      }
+    }
+
+    return parent::get_default_argument($raw);
+  }
+
+  /**
+   * The date handler provides some default argument types, which aren't argument default plugins,
+   * so addapt the export mechanism.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+
+    // Only use a special behaviour for the special argument types, else just
+    // use the default behaviour.
+    if ($option == 'default_argument_type') {
+      $type = 'argument default';
+      $option_name = 'default_argument_options';
+
+      $plugin = $this->get_plugin($type);
+      $name = $this->options[$option];
+      if (in_array($name, array('date', 'node_created', 'node_changed'))) {
+
+        // Write which plugin to use.
+        $output = $indent . $prefix . "['$option'] = '$name';\n";
+        return $output;
+      }
+    }
+    return parent::export_plugin($indent, $prefix, $storage, $option, $definition, $parents);
+  }
+
+
+  function get_sort_name() {
+    return t('Date', array(), array('context' => 'Sort order'));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/FormulaArgument.php b/lib/Drupal/views/Plugins/views/handler/FormulaArgument.php
new file mode 100644
index 0000000..78b6d1a
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/FormulaArgument.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\FormulaArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Abstract argument handler for simple formulae.
+ *
+ * Child classes of this object should implement summary_argument, at least.
+ *
+ * Definition terms:
+ * - formula: The formula to use for this handler.
+ *
+ * @ingroup views_argument_handlers
+ */
+class FormulaArgument extends ArgumentPlugin {
+  var $formula = NULL;
+  /**
+   * Constructor
+   */
+  function construct() {
+    parent::construct();
+
+    if (!empty($this->definition['formula'])) {
+      $this->formula = $this->definition['formula'];
+    }
+  }
+
+  function get_formula() {
+    return str_replace('***table***', $this->table_alias, $this->formula);
+  }
+
+  /**
+   * Build the summary query based on a formula
+   */
+  function summary_query() {
+    $this->ensure_my_table();
+    // Now that our table is secure, get our formula.
+    $formula = $this->get_formula();
+
+    // Add the field.
+    $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field);
+    $this->query->set_count_field(NULL, $formula, $this->field);
+
+    return $this->summary_basics(FALSE);
+  }
+
+  /**
+   * Build the query based upon the formula
+   */
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+    // Now that our table is secure, get our formula.
+    $placeholder = $this->placeholder();
+    $formula = $this->get_formula() .' = ' . $placeholder;
+    $placeholders = array(
+      $placeholder => $this->argument,
+    );
+    $this->query->add_where(0, $formula, $placeholders, 'formula');
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/GroupByNumericArgument.php b/lib/Drupal/views/Plugins/views/handler/GroupByNumericArgument.php
new file mode 100644
index 0000000..3ab3212
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/GroupByNumericArgument.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\GroupByNumericArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Simple handler for arguments using group by.
+ *
+ * @ingroup views_argument_handlers
+ */
+class GroupByNumericArgument extends ArgumentPlugin  {
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+    $field = $this->get_field();
+    $placeholder = $this->placeholder();
+
+    $this->query->add_having_expression(0, "$field = $placeholder", array($placeholder => $this->argument));
+  }
+
+  function ui_name($short = FALSE) {
+    return $this->get_field(parent::ui_name($short));
+  }
+
+  function get_sort_name() {
+    return t('Numerical', array(), array('context' => 'Sort order'));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/ManyToOneArgument.php b/lib/Drupal/views/Plugins/views/handler/ManyToOneArgument.php
new file mode 100644
index 0000000..25245d2
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/ManyToOneArgument.php
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\ManyToOneArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * An argument handler for use in fields that have a many to one relationship
+ * with the table(s) to the left. This adds a bunch of options that are
+ * reasonably common with this type of relationship.
+ * Definition terms:
+ * - numeric: If true, the field will be considered numeric. Probably should
+ *   always be set TRUE as views_handler_argument_string has many to one
+ *   capabilities.
+ * - zero is null: If true, a 0 will be handled as empty, so for example
+ *   a default argument can be provided or a summary can be shown.
+ *
+ * @ingroup views_argument_handlers
+ */
+class ManyToOneArgument extends ArgumentPlugin {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    $this->helper = new views_many_to_one_helper($this);
+
+    // Ensure defaults for these, during summaries and stuff:
+    $this->operator = 'or';
+    $this->value = array();
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    if (!empty($this->definition['numeric'])) {
+      $options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
+    }
+
+    $options['add_table'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['require_value'] = array('default' => FALSE, 'bool' => TRUE);
+
+    if (isset($this->helper)) {
+      $this->helper->option_definition($options);
+    }
+    else {
+      $helper = new views_many_to_one_helper($this);
+      $helper->option_definition($options);
+    }
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // allow + for or, , for and
+    if (!empty($this->definition['numeric'])) {
+      $form['break_phrase'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Allow multiple values'),
+        '#description' => t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'),
+        '#default_value' => !empty($this->options['break_phrase']),
+        '#fieldset' => 'more',
+      );
+    }
+
+    $form['add_table'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow multiple filter values to work together'),
+      '#description' => t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'),
+      '#default_value' => !empty($this->options['add_table']),
+      '#fieldset' => 'more',
+    );
+
+    $form['require_value'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Do not display items with no value in summary'),
+      '#default_value' => !empty($this->options['require_value']),
+      '#fieldset' => 'more',
+    );
+
+    $this->helper->options_form($form, $form_state);
+  }
+
+  /**
+   * Override ensure_my_table so we can control how this joins in.
+   * The operator actually has influence over joining.
+   */
+  function ensure_my_table() {
+    $this->helper->ensure_my_table();
+  }
+
+  function query($group_by = FALSE) {
+    $empty = FALSE;
+    if (isset($this->definition['zero is null']) && $this->definition['zero is null']) {
+      if (empty($this->argument)) {
+        $empty = TRUE;
+      }
+    }
+    else {
+      if (!isset($this->argument)) {
+        $empty = TRUE;
+      }
+    }
+    if ($empty) {
+      parent::ensure_my_table();
+      $this->query->add_where(0, "$this->table_alias.$this->real_field", NULL, 'IS NULL');
+      return;
+    }
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase($this->argument, $this);
+    }
+    else {
+      $this->value = array($this->argument);
+      $this->operator = 'or';
+    }
+
+    $this->helper->add_filter();
+  }
+
+  function title() {
+    if (!$this->argument) {
+      return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized');
+    }
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase($this->argument, $this);
+    }
+    else {
+      $this->value = array($this->argument);
+      $this->operator = 'or';
+    }
+
+    // @todo -- both of these should check definition for alternate keywords.
+
+    if (empty($this->value)) {
+      return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized');
+    }
+
+    if ($this->value === array(-1)) {
+      return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : t('Invalid input');
+    }
+
+    return implode($this->operator == 'or' ? ' + ' : ', ', $this->title_query());
+  }
+
+  function summary_query() {
+    $field = $this->table . '.' . $this->field;
+    $join = $this->get_join();
+
+    if (!empty($this->options['require_value'])) {
+      $join->type = 'INNER';
+    }
+
+    if (empty($this->options['add_table']) || empty($this->view->many_to_one_tables[$field])) {
+      $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $join);
+    }
+    else {
+      $this->table_alias = $this->helper->summary_join();
+    }
+
+    // Add the field.
+    $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
+
+    $this->summary_name_field();
+
+    return $this->summary_basics();
+  }
+
+  function summary_argument($data) {
+    $value = $data->{$this->base_alias};
+    if (empty($value)) {
+      $value = 0;
+    }
+
+    return $value;
+  }
+
+  /**
+   * Override for specific title lookups.
+   */
+  function title_query() {
+    return $this->value;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/NullArgument.php b/lib/Drupal/views/Plugins/views/handler/NullArgument.php
new file mode 100644
index 0000000..c1c467c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/NullArgument.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\NullArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Argument handler that ignores the argument.
+ *
+ * @ingroup views_argument_handlers
+ */
+class NullArgument extends ArgumentPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['must_not_be'] = array('default' => FALSE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Override options_form() so that only the relevant options
+   * are displayed to the user.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['must_not_be'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Fail basic validation if any argument is given'),
+      '#default_value' => !empty($this->options['must_not_be']),
+      '#description' => t('By checking this field, you can use this to make sure views with more arguments than necessary fail validation.'),
+      '#fieldset' => 'more',
+    );
+
+    unset($form['exception']);
+  }
+
+  /**
+   * Override default_actions() to remove actions that don't
+   * make sense for a null argument.
+   */
+  function default_actions($which = NULL) {
+    if ($which) {
+      if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) {
+        return parent::default_actions($which);
+      }
+      return;
+    }
+    $actions = parent::default_actions();
+    unset($actions['summary asc']);
+    unset($actions['summary desc']);
+    return $actions;
+  }
+
+  function validate_argument_basic($arg) {
+    if (!empty($this->options['must_not_be'])) {
+      return !isset($arg);
+    }
+
+    return parent::validate_argument_basic($arg);
+  }
+
+  /**
+   * Override the behavior of query() to prevent the query
+   * from being changed in any way.
+   */
+  function query($group_by = FALSE) {}
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/NumericArgument.php b/lib/Drupal/views/Plugins/views/handler/NumericArgument.php
new file mode 100644
index 0000000..d513c2b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/NumericArgument.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\NumericArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Basic argument handler for arguments that are numeric. Incorporates
+ * break_phrase.
+ *
+ * @ingroup views_argument_handlers
+ */
+class NumericArgument extends ArgumentPlugin {
+  /**
+   * The operator used for the query: or|and.
+   * @var string
+   */
+  var $operator;
+
+  /**
+   * The actual value which is used for querying.
+   * @var array
+   */
+  var $value;
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['not'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // allow + for or, , for and
+    $form['break_phrase'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow multiple values'),
+      '#description' => t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'),
+      '#default_value' => !empty($this->options['break_phrase']),
+      '#fieldset' => 'more',
+    );
+
+    $form['not'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Exclude'),
+      '#description' => t('If selected, the numbers entered for the filter will be excluded rather than limiting the view.'),
+      '#default_value' => !empty($this->options['not']),
+      '#fieldset' => 'more',
+    );
+  }
+
+  function title() {
+    if (!$this->argument) {
+      return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized');
+    }
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase($this->argument, $this);
+    }
+    else {
+      $this->value = array($this->argument);
+      $this->operator = 'or';
+    }
+
+    if (empty($this->value)) {
+      return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized');
+    }
+
+    if ($this->value === array(-1)) {
+      return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : t('Invalid input');
+    }
+
+    return implode($this->operator == 'or' ? ' + ' : ', ', $this->title_query());
+  }
+
+  /**
+   * Override for specific title lookups.
+   * @return array
+   *    Returns all titles, if it's just one title it's an array with one entry.
+   */
+  function title_query() {
+    return $this->value;
+  }
+
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase($this->argument, $this);
+    }
+    else {
+      $this->value = array($this->argument);
+    }
+
+    $placeholder = $this->placeholder();
+    $null_check = empty($this->options['not']) ? '' : "OR $this->table_alias.$this->real_field IS NULL";
+
+    if (count($this->value) > 1) {
+      $operator = empty($this->options['not']) ? 'IN' : 'NOT IN';
+      $this->query->add_where_expression(0, "$this->table_alias.$this->real_field $operator($placeholder) $null_check", array($placeholder => $this->value));
+    }
+    else {
+      $operator = empty($this->options['not']) ? '=' : '!=';
+      $this->query->add_where_expression(0, "$this->table_alias.$this->real_field $operator $placeholder $null_check", array($placeholder => $this->argument));
+    }
+  }
+
+  function get_sort_name() {
+    return t('Numerical', array(), array('context' => 'Sort order'));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/handler/StringArgument.php b/lib/Drupal/views/Plugins/views/handler/StringArgument.php
new file mode 100644
index 0000000..3f02697
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/handler/StringArgument.php
@@ -0,0 +1,280 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\handler\StringArgument.
+ */
+
+namespace Drupal\views\Plugins\views\handler;
+
+/**
+ * Basic argument handler to implement string arguments that may have length
+ * limits.
+ *
+ * @ingroup views_argument_handlers
+ */
+class StringArgument extends ArgumentPlugin {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (!empty($this->definition['many to one'])) {
+      $this->helper = new views_many_to_one_helper($this);
+
+      // Ensure defaults for these, during summaries and stuff:
+      $this->operator = 'or';
+      $this->value = array();
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['glossary'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['limit'] = array('default' => 0);
+    $options['case'] = array('default' => 'none');
+    $options['path_case'] = array('default' => 'none');
+    $options['transform_dash'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
+
+    if (!empty($this->definition['many to one'])) {
+      $options['add_table'] = array('default' => FALSE, 'bool' => TRUE);
+      $options['require_value'] = array('default' => FALSE, 'bool' => TRUE);
+    }
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['glossary'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Glossary mode'),
+      '#description' => t('Glossary mode applies a limit to the number of characters used in the filter value, which allows the summary view to act as a glossary.'),
+      '#default_value' => $this->options['glossary'],
+      '#fieldset' => 'more',
+    );
+
+    $form['limit'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Character limit'),
+      '#description' => t('How many characters of the filter value to filter against. If set to 1, all fields starting with the first letter in the filter value would be matched.'),
+      '#default_value' => $this->options['limit'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[glossary]"]' => array('checked' => TRUE),
+        ),
+      ),
+      '#fieldset' => 'more',
+    );
+
+    $form['case'] = array(
+      '#type' => 'select',
+      '#title' => t('Case'),
+      '#description' => t('When printing the title and summary, how to transform the case of the filter value.'),
+      '#options' => array(
+        'none' => t('No transform'),
+        'upper' => t('Upper case'),
+        'lower' => t('Lower case'),
+        'ucfirst' => t('Capitalize first letter'),
+        'ucwords' => t('Capitalize each word'),
+      ),
+      '#default_value' => $this->options['case'],
+      '#fieldset' => 'more',
+    );
+
+    $form['path_case'] = array(
+      '#type' => 'select',
+      '#title' => t('Case in path'),
+      '#description' => t('When printing url paths, how to transform the case of the filter value. Do not use this unless with Postgres as it uses case sensitive comparisons.'),
+      '#options' => array(
+        'none' => t('No transform'),
+        'upper' => t('Upper case'),
+        'lower' => t('Lower case'),
+        'ucfirst' => t('Capitalize first letter'),
+        'ucwords' => t('Capitalize each word'),
+      ),
+      '#default_value' => $this->options['path_case'],
+      '#fieldset' => 'more',
+    );
+
+    $form['transform_dash'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Transform spaces to dashes in URL'),
+      '#default_value' => $this->options['transform_dash'],
+      '#fieldset' => 'more',
+    );
+
+    if (!empty($this->definition['many to one'])) {
+      $form['add_table'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Allow multiple filter values to work together'),
+        '#description' => t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'),
+        '#default_value' => !empty($this->options['add_table']),
+        '#fieldset' => 'more',
+      );
+
+      $form['require_value'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Do not display items with no value in summary'),
+        '#default_value' => !empty($this->options['require_value']),
+        '#fieldset' => 'more',
+      );
+    }
+
+    // allow + for or, , for and
+    $form['break_phrase'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow multiple values'),
+      '#description' => t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'),
+      '#default_value' => !empty($this->options['break_phrase']),
+      '#fieldset' => 'more',
+    );
+  }
+
+  /**
+   * Build the summary query based on a string
+   */
+  function summary_query() {
+    if (empty($this->definition['many to one'])) {
+      $this->ensure_my_table();
+    }
+    else {
+      $this->table_alias = $this->helper->summary_join();
+    }
+
+    if (empty($this->options['glossary'])) {
+      // Add the field.
+      $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
+      $this->query->set_count_field($this->table_alias, $this->real_field);
+    }
+    else {
+      // Add the field.
+      $formula = $this->get_formula();
+      $this->base_alias = $this->query->add_field(NULL, $formula, $this->field . '_truncated');
+      $this->query->set_count_field(NULL, $formula, $this->field, $this->field . '_truncated');
+    }
+
+    $this->summary_name_field();
+    return $this->summary_basics(FALSE);
+  }
+
+  /**
+   * Get the formula for this argument.
+   *
+   * $this->ensure_my_table() MUST have been called prior to this.
+   */
+  function get_formula() {
+    return "SUBSTRING($this->table_alias.$this->real_field, 1, " . intval($this->options['limit']) . ")";
+  }
+
+  /**
+   * Build the query based upon the formula
+   */
+  function query($group_by = FALSE) {
+    $argument = $this->argument;
+    if (!empty($this->options['transform_dash'])) {
+      $argument = strtr($argument, '-', ' ');
+    }
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase_string($argument, $this);
+    }
+    else {
+      $this->value = array($argument);
+      $this->operator = 'or';
+    }
+
+    if (!empty($this->definition['many to one'])) {
+      if (!empty($this->options['glossary'])) {
+        $this->helper->formula = TRUE;
+      }
+      $this->helper->ensure_my_table();
+      $this->helper->add_filter();
+      return;
+    }
+
+    $this->ensure_my_table();
+    $formula = FALSE;
+    if (empty($this->options['glossary'])) {
+      $field = "$this->table_alias.$this->real_field";
+    }
+    else {
+      $formula = TRUE;
+      $field = $this->get_formula();
+    }
+
+    if (count($this->value) > 1) {
+      $operator = 'IN';
+      $argument = $this->value;
+    }
+    else {
+      $operator = '=';
+    }
+
+    if ($formula) {
+      $placeholder = $this->placeholder();
+      if ($operator == 'IN') {
+        $field .= " IN($placeholder)";
+      }
+      else {
+        $field .= ' = ' . $placeholder;
+      }
+      $placeholders = array(
+        $placeholder => $argument,
+      );
+      $this->query->add_where_expression(0, $field, $placeholders);
+    }
+    else {
+      $this->query->add_where(0, $field, $argument, $operator);
+    }
+  }
+
+  function summary_argument($data) {
+    $value = $this->case_transform($data->{$this->base_alias}, $this->options['path_case']);
+    if (!empty($this->options['transform_dash'])) {
+      $value = strtr($value, ' ', '-');
+    }
+    return $value;
+  }
+
+  function get_sort_name() {
+    return t('Alphabetical', array(), array('context' => 'Sort order'));
+  }
+
+  function title() {
+    $this->argument = $this->case_transform($this->argument, $this->options['case']);
+    if (!empty($this->options['transform_dash'])) {
+      $this->argument = strtr($this->argument, '-', ' ');
+    }
+
+    if (!empty($this->options['break_phrase'])) {
+      views_break_phrase_string($this->argument, $this);
+    }
+    else {
+      $this->value = array($this->argument);
+      $this->operator = 'or';
+    }
+
+    if (empty($this->value)) {
+      return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized');
+    }
+
+    if ($this->value === array(-1)) {
+      return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : t('Invalid input');
+    }
+
+    return implode($this->operator == 'or' ? ' + ' : ', ', $this->title_query());
+  }
+
+  /**
+   * Override for specific title lookups.
+   */
+  function title_query() {
+    return drupal_map_assoc($this->value, 'check_plain');
+  }
+
+  function summary_name($data) {
+    return $this->case_transform(parent::summary_name($data), $this->options['case']);
+  }
+
+}
diff --git a/lib/Drupal/views/Plugins/views/localization/CoreLocalization.php b/lib/Drupal/views/Plugins/views/localization/CoreLocalization.php
new file mode 100644
index 0000000..a21c362
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/localization/CoreLocalization.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\localization\CoreLocalization.
+ */
+
+namespace Drupal\views\Plugins\views\localization;
+
+/**
+ * Localization plugin to pass translatable strings through t().
+ *
+ * @ingroup views_localization_plugins
+ */
+class CoreLocalization extends LocalizationPlugin {
+
+  /**
+   * Translate a string.
+   *
+   * @param $string
+   *   The string to be translated.
+   * @param $keys
+   *   An array of keys to identify the string. Generally constructed from
+   *   view name, display_id, and a property, e.g., 'header'.
+   * @param $format
+   *   The input format of the string. This is optional.
+   */
+  function translate_string($string, $keys = array(), $format = '') {
+    return t($string);
+  }
+
+  /**
+   * Save a string for translation.
+   *
+   * @param $string
+   *   The string to be translated.
+   * @param $keys
+   *   An array of keys to identify the string. Generally constructed from
+   *   view name, display_id, and a property, e.g., 'header'.
+   * @param $format
+   *   The input format of the string. This is optional.
+   */
+  function save_string($string, $keys = array(), $format = '') {
+    $language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
+
+    // If the current language is 'en', we need to reset the language
+    // in order to trigger an update.
+    // TODO: add test for number of languages.
+    if ($language_interface->langcode == 'en') {
+      $changed = TRUE;
+      $languages = language_list();
+      $cached_language = $language_interface;
+      unset($languages['en']);
+      if (!empty($languages)) {
+        drupal_container()->set(LANGUAGE_TYPE_INTERFACE, current($languages));
+      }
+    }
+
+    t($string);
+
+    if (isset($cached_language)) {
+      drupal_container()->set(LANGUAGE_TYPE_INTERFACE, $cached_language);
+    }
+    return TRUE;
+  }
+
+  /**
+   * Delete a string.
+   *
+   * Deletion is not supported.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   */
+  function delete($source) {
+    return FALSE;
+  }
+
+  /**
+   * Collect strings to be exported to code.
+   *
+   * String identifiers are not supported so strings are anonymously in an array.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   */
+  function export($source) {
+    if (!empty($source['value'])) {
+      $this->export_strings[] = $source['value'];
+    }
+  }
+
+  /**
+   * Render any collected exported strings to code.
+   *
+   * @param $indent
+   *   An optional indentation for prettifying nested code.
+   */
+  function export_render($indent = '  ') {
+    $output = '';
+    if (!empty($this->export_strings)) {
+      $this->export_strings = array_unique($this->export_strings);
+      $output = $indent . '$translatables[\'' . $this->view->name . '\'] = array(' . "\n";
+      foreach ($this->export_strings as $string) {
+        $output .= $indent . "  t('" . str_replace("'", "\'", $string) . "'),\n";
+      }
+      $output .= $indent . ");\n";
+    }
+    return $output;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/localization/LocalizationNone.php b/lib/Drupal/views/Plugins/views/localization/LocalizationNone.php
new file mode 100644
index 0000000..58e8d08
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/localization/LocalizationNone.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\localization\LocalizationNone.
+ */
+
+namespace Drupal\views\Plugins\views\localization;
+
+/**
+ * Localization plugin for no localization.
+ *
+ * @ingroup views_localization_plugins
+ */
+class LocalizationNone extends LocalizationPlugin {
+  var $translate = FALSE;
+
+  /**
+   * Translate a string; simply return the string.
+   */
+  function translate($source) {
+    return $source['value'];
+  }
+
+  /**
+   * Save a string for translation; not supported.
+   */
+  function save($source) {
+    return FALSE;
+  }
+
+  /**
+   * Delete a string; not supported.
+   */
+  function delete($source) {
+    return FALSE;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/localization/LocalizationPlugin.php b/lib/Drupal/views/Plugins/views/localization/LocalizationPlugin.php
new file mode 100644
index 0000000..b9b9cd3
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/localization/LocalizationPlugin.php
@@ -0,0 +1,175 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\localization\LocalizationPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\localization;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_localization_plugins Views localization plugins
+ * @{
+ * @todo.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The base plugin to handle localization of Views strings.
+ */
+class LocalizationPlugin extends Plugin {
+  // Store for exported strings
+  var $export_strings = array();
+  var $translate = TRUE;
+
+  /**
+   * Initialize the plugin.
+   *
+   * @param $view
+   *   The view object.
+   */
+  function init(&$view) {
+    $this->view = &$view;
+  }
+
+  /**
+   * Translate a string / text with format
+   *
+   * The $source parameter is an array with the following elements:
+   * - value, source string
+   * - format, input format in case the text has some format to be applied
+   * - keys. An array of keys to identify the string. Generally constructed from
+   *   view name, display_id, and a property, e.g., 'header'.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   *
+   * @return string
+   *   Translated string / text
+   */
+  function translate($source) {
+    // Allow other modules to make changes to the string before and after translation
+    $source['pre_process'] = $this->invoke_translation_process($source, 'pre');
+    $source['translation'] = $this->translate_string($source['value'], $source['keys'], $source['format']);
+    $source['post_process'] = $this->invoke_translation_process($source, 'post');
+    return $source['translation'];
+  }
+
+  /**
+   * Translate a string.
+   *
+   * @param $string
+   *   The string to be translated.
+   * @param $keys
+   *   An array of keys to identify the string. Generally constructed from
+   *   view name, display_id, and a property, e.g., 'header'.
+   * @param $format
+   *   The input format of the string. This is optional.
+   */
+  function translate_string($string, $keys = array(), $format = '') {}
+
+  /**
+   * Save string source for translation.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   */
+  function save($source) {
+    // Allow other modules to make changes to the string before saving
+    $source['pre_process'] = $this->invoke_translation_process($source, 'pre');
+    $this->save_string($source['value'], $source['keys'], isset($source['format']) ? $source['format'] : '');
+  }
+
+  /**
+   * Save a string for translation
+   *
+   * @param $string
+   *   The string to be translated.
+   * @param $keys
+   *   An array of keys to identify the string. Generally constructed from
+   *   view name, display_id, and a property, e.g., 'header'.
+   * @param $format
+   *   The input format of the string. This is optional.
+   */
+  function save_string($string, $keys = array(), $format = '') {}
+
+  /**
+   * Delete a string.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   */
+  function delete($source) { }
+
+  /**
+   * Collect strings to be exported to code.
+   *
+   * @param $source
+   *   Full data for the string to be translated.
+   */
+  function export($source) { }
+
+  /**
+   * Render any collected exported strings to code.
+   *
+   * @param $indent
+   *   An optional indentation for prettifying nested code.
+   */
+  function export_render($indent = '  ') { }
+
+  /**
+   * Invoke hook_translation_pre_process() or hook_translation_post_process().
+   *
+   * Like node_invoke_nodeapi(), this function is needed to enable both passing
+   * by reference and fetching return values.
+   */
+  function invoke_translation_process(&$value, $op) {
+    $return = array();
+    $hook = 'translation_' . $op . '_process';
+    foreach (module_implements($hook) as $module) {
+      $function = $module . '_' . $hook;
+      $result = $function($value);
+      if (isset($result)) {
+        $return[$module] = $result;
+      }
+    }
+    return $return;
+  }
+
+  function process_locale_strings($op) {
+    $this->view->init_display();
+
+    foreach ($this->view->display as $display_id => $display) {
+      $translatable = array();
+      // Special handling for display title.
+      if (isset($display->display_title)) {
+        $translatable[] = array('value' => $display->display_title, 'keys' => array('display_title'));
+      }
+      // Unpack handlers.
+      if (is_object($this->view->display[$display_id]->handler)) {
+        $this->view->display[$display_id]->handler->unpack_translatables($translatable);
+      }
+      foreach ($translatable as $data) {
+        $data['keys'] = array_merge(array($this->view->name, $display_id), $data['keys']);
+        switch ($op) {
+          case 'save':
+            $this->save($data);
+            break;
+          case 'delete':
+            $this->delete($data);
+            break;
+          case 'export':
+            $this->export($data);
+            break;
+        }
+      }
+    }
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/pager/FullPager.php b/lib/Drupal/views/Plugins/views/pager/FullPager.php
new file mode 100644
index 0000000..5ce522b
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/pager/FullPager.php
@@ -0,0 +1,432 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\pager\FullPager.
+ */
+
+namespace Drupal\views\Plugins\views\pager;
+
+/**
+ * The plugin to handle full pager.
+ *
+ * @ingroup views_pager_plugins
+ */
+class FullPager extends PagerPlugin {
+  function summary_title() {
+    if (!empty($this->options['offset'])) {
+      return format_plural($this->options['items_per_page'], '@count item, skip @skip', 'Paged, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
+    }
+      return format_plural($this->options['items_per_page'], '@count item', 'Paged, @count items', array('@count' => $this->options['items_per_page']));
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['items_per_page'] = array('default' => 10);
+    $options['offset'] = array('default' => 0);
+    $options['id'] = array('default' => 0);
+    $options['total_pages'] = array('default' => '');
+    // Use the same default quantity that core uses by default.
+    $options['quantity'] = array('default' => 9);
+    $options['expose'] = array(
+      'contains' => array(
+        'items_per_page' => array('default' => FALSE, 'bool' => TRUE),
+        'items_per_page_label' => array('default' => 'Items per page', 'translatable' => TRUE),
+        'items_per_page_options' => array('default' => '5, 10, 20, 40, 60'),
+        'items_per_page_options_all' => array('default' => FALSE, 'bool' => TRUE),
+        'items_per_page_options_all_label' => array('default' => '- All -', 'translatable' => TRUE),
+
+        'offset' => array('default' => FALSE, 'bool' => TRUE),
+        'offset_label' => array('default' => 'Offset', 'translatable' => TRUE),
+      ),
+    );
+    $options['tags'] = array(
+      'contains' => array(
+        'first' => array('default' => '« first', 'translatable' => TRUE),
+        'previous' => array('default' => '‹ previous', 'translatable' => TRUE),
+        'next' => array('default' => 'next ›', 'translatable' => TRUE),
+        'last' => array('default' => 'last »', 'translatable' => TRUE),
+      ),
+    );
+    return $options;
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $pager_text = $this->display->handler->get_pager_text();
+    $form['items_per_page'] = array(
+      '#title' => $pager_text['items per page title'],
+      '#type' => 'textfield',
+      '#description' => $pager_text['items per page description'],
+      '#default_value' => $this->options['items_per_page'],
+    );
+
+    $form['offset'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Offset'),
+      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
+      '#default_value' => $this->options['offset'],
+    );
+
+    $form['id'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Pager ID'),
+      '#description' => t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."),
+      '#default_value' => $this->options['id'],
+    );
+
+    $form['total_pages'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Number of pages'),
+      '#description' => t('The total number of pages. Leave empty to show all pages.'),
+      '#default_value' => $this->options['total_pages'],
+    );
+
+    $form['quantity'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Number of pager links visible'),
+      '#description' => t('Specify the number of links to pages to display in the pager.'),
+      '#default_value' => $this->options['quantity'],
+    );
+
+    $form['tags'] = array (
+      '#type' => 'fieldset',
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+      '#tree' => TRUE,
+      '#title' => t('Tags'),
+      '#input' => TRUE,
+      '#description' => t('A lists of labels for the controls in the pager'),
+    );
+
+    $form['tags']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text for "first"-link'),
+      '#description' => t('Text for "first"-link'),
+      '#default_value' => $this->options['tags']['first'],
+    );
+
+    $form['tags']['previous'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text for "previous"-link'),
+      '#description' => t('Text for "previous"-link'),
+      '#default_value' => $this->options['tags']['previous'],
+    );
+
+    $form['tags']['next'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text for "next"-link'),
+      '#description' => t('Text for "next"-link'),
+      '#default_value' => $this->options['tags']['next'],
+    );
+
+    $form['tags']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text for "last"-link'),
+      '#description' => t('Text for "last"-link'),
+      '#default_value' => $this->options['tags']['last'],
+    );
+
+    $form['expose'] = array (
+      '#type' => 'fieldset',
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+      '#tree' => TRUE,
+      '#title' => t('Exposed options'),
+      '#input' => TRUE,
+      '#description' => t('Exposing this options allows users to define their values in a exposed form when view is displayed'),
+    );
+
+    $form['expose']['items_per_page'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Expose items per page'),
+      '#description' => t('When checked, users can determine how many items per page show in a view'),
+      '#default_value' => $this->options['expose']['items_per_page'],
+    );
+
+    $form['expose']['items_per_page_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Items per page label'),
+      '#required' => TRUE,
+      '#description' => t('Label to use in the exposed items per page form element.'),
+      '#default_value' => $this->options['expose']['items_per_page_label'],
+      '#states' => array(
+        'invisible' => array(
+          'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+
+    $form['expose']['items_per_page_options'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Exposed items per page options'),
+      '#required' => TRUE,
+      '#description' => t('Set between which values the user can choose when determining the items per page. Separated by comma.'),
+      '#default_value' => $this->options['expose']['items_per_page_options'],
+      '#states' => array(
+        'invisible' => array(
+          'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+
+
+    $form['expose']['items_per_page_options_all'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Include all items option'),
+      '#description' => t('If checked, an extra item will be included to items per page to display all items'),
+      '#default_value' => $this->options['expose']['items_per_page_options_all'],
+    );
+
+    $form['expose']['items_per_page_options_all_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('All items label'),
+      '#description' => t('Which label will be used to display all items'),
+      '#default_value' => $this->options['expose']['items_per_page_options_all_label'],
+      '#states' => array(
+        'invisible' => array(
+          'input[name="pager_options[expose][items_per_page_options_all]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+
+    $form['expose']['offset'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Expose Offset'),
+      '#description' => t('When checked, users can determine how many items should be skipped at the beginning.'),
+      '#default_value' => $this->options['expose']['offset'],
+    );
+
+    $form['expose']['offset_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Offset label'),
+      '#required' => TRUE,
+      '#description' => t('Label to use in the exposed offset form element.'),
+      '#default_value' => $this->options['expose']['offset_label'],
+      '#states' => array(
+        'invisible' => array(
+          'input[name="pager_options[expose][offset]"]' => array('checked' => FALSE),
+        ),
+      ),
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    // Only accept integer values.
+    $error = FALSE;
+    $exposed_options = $form_state['values']['pager_options']['expose']['items_per_page_options'];
+    if (strpos($exposed_options, '.') !== FALSE) {
+      $error = TRUE;
+    }
+    $options = explode(',',$exposed_options);
+    if (!$error && is_array($options)) {
+      foreach ($options as $option) {
+        if (!is_numeric($option) || intval($option) == 0) {
+          $error = TRUE;
+        }
+      }
+    }
+    else {
+      $error = TRUE;
+    }
+    if ($error) {
+      form_set_error('pager_options][expose][items_per_page_options', t('Please insert a list of integer numeric values separated by commas: e.g: 10, 20, 50, 100'));
+    }
+
+    // Take sure that the items_per_page is part of the expose settings.
+    if (!empty($form_state['values']['pager_options']['expose']['items_per_page']) && !empty($form_state['values']['pager_options']['items_per_page'])) {
+      $items_per_page = $form_state['values']['pager_options']['items_per_page'];
+      if (array_search($items_per_page, $options) === FALSE) {
+        form_set_error('pager_options][expose][items_per_page_options', t('Please insert the items per page (@items_per_page) from above.',
+          array('@items_per_page' => $items_per_page))
+        );
+      }
+    }
+  }
+
+  function query() {
+    if ($this->items_per_page_exposed()) {
+      if (!empty($_GET['items_per_page']) && $_GET['items_per_page'] > 0) {
+        $this->options['items_per_page'] = $_GET['items_per_page'];
+      }
+      elseif (!empty($_GET['items_per_page']) && $_GET['items_per_page'] == 'All' && $this->options['expose']['items_per_page_options_all']) {
+        $this->options['items_per_page'] = 0;
+      }
+    }
+    if ($this->offset_exposed()) {
+      if (isset($_GET['offset']) && $_GET['offset'] >= 0) {
+        $this->options['offset'] = $_GET['offset'];
+      }
+    }
+
+    $limit = $this->options['items_per_page'];
+    $offset = $this->current_page * $this->options['items_per_page'] + $this->options['offset'];
+    if (!empty($this->options['total_pages'])) {
+      if ($this->current_page >= $this->options['total_pages']) {
+        $limit = $this->options['items_per_page'];
+        $offset = $this->options['total_pages'] * $this->options['items_per_page'];
+      }
+    }
+
+    $this->view->query->set_limit($limit);
+    $this->view->query->set_offset($offset);
+  }
+
+  function render($input) {
+    $pager_theme = views_theme_functions('pager', $this->view, $this->display);
+    // The 0, 1, 3, 4 index are correct. See theme_pager documentation.
+    $tags = array(
+      0 => $this->options['tags']['first'],
+      1 => $this->options['tags']['previous'],
+      3 => $this->options['tags']['next'],
+      4 => $this->options['tags']['last'],
+    );
+    $output = theme($pager_theme, array(
+      'tags' => $tags,
+      'element' => $this->options['id'],
+      'parameters' => $input,
+      'quantity' => $this->options['quantity'],
+    ));
+    return $output;
+  }
+
+  /**
+   * Set the current page.
+   *
+   * @param $number
+   *   If provided, the page number will be set to this. If NOT provided,
+   *   the page number will be set from the global page array.
+   */
+  function set_current_page($number = NULL) {
+    if (isset($number)) {
+      $this->current_page = $number;
+      return;
+    }
+
+    // If the current page number was not specified, extract it from the global
+    // page array.
+    global $pager_page_array;
+
+    if (empty($pager_page_array)) {
+      $pager_page_array = array();
+    }
+
+    // Fill in missing values in the global page array, in case the global page
+    // array hasn't been initialized before.
+    $page = isset($_GET['page']) ? explode(',', $_GET['page']) : array();
+
+    for ($i = 0; $i <= $this->options['id'] || $i < count($pager_page_array); $i++) {
+      $pager_page_array[$i] = empty($page[$i]) ? 0 : $page[$i];
+    }
+
+    $this->current_page = intval($pager_page_array[$this->options['id']]);
+
+    if ($this->current_page < 0) {
+      $this->current_page = 0;
+    }
+  }
+
+  function get_pager_total() {
+    if ($items_per_page = intval($this->get_items_per_page())) {
+      return ceil($this->total_items / $items_per_page);
+    }
+    else {
+      return 1;
+    }
+  }
+
+  /**
+   * Update global paging info.
+   *
+   * This is called after the count query has been run to set the total
+   * items available and to update the current page if the requested
+   * page is out of range.
+   */
+  function update_page_info() {
+    if (!empty($this->options['total_pages'])) {
+      if (($this->options['total_pages'] * $this->options['items_per_page']) < $this->total_items) {
+        $this->total_items = $this->options['total_pages'] * $this->options['items_per_page'];
+      }
+    }
+
+    // Don't set pager settings for items per page = 0.
+    $items_per_page = $this->get_items_per_page();
+    if (!empty($items_per_page)) {
+      // Dump information about what we already know into the globals.
+      global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
+      // Set the limit.
+      $pager_limits[$this->options['id']] = $this->options['items_per_page'];
+      // Set the item count for the pager.
+      $pager_total_items[$this->options['id']] = $this->total_items;
+      // Calculate and set the count of available pages.
+      $pager_total[$this->options['id']] = $this->get_pager_total();
+
+      // See if the requested page was within range:
+      if ($this->current_page < 0) {
+        $this->current_page = 0;
+      }
+      else if ($this->current_page >= $pager_total[$this->options['id']]) {
+        // Pages are numbered from 0 so if there are 10 pages, the last page is 9.
+        $this->current_page = $pager_total[$this->options['id']] - 1;
+      }
+
+      // Put this number in to guarantee that we do not generate notices when the pager
+      // goes to look for it later.
+      $pager_page_array[$this->options['id']] = $this->current_page;
+    }
+  }
+
+  function uses_exposed() {
+    return $this->items_per_page_exposed() || $this->offset_exposed();
+  }
+
+  function items_per_page_exposed() {
+    return !empty($this->options['expose']['items_per_page']);
+  }
+
+  function offset_exposed() {
+    return !empty($this->options['expose']['offset']);
+  }
+
+  function exposed_form_alter(&$form, &$form_state) {
+    if ($this->items_per_page_exposed()) {
+      $options = explode(',', $this->options['expose']['items_per_page_options']);
+      $sanitized_options = array();
+      if (is_array($options)) {
+        foreach ($options as $option) {
+          $sanitized_options[intval($option)] = intval($option);
+        }
+        if (!empty($this->options['expose']['items_per_page_options_all']) && !empty($this->options['expose']['items_per_page_options_all_label'])) {
+          $sanitized_options['All'] = $this->options['expose']['items_per_page_options_all_label'];
+        }
+        $form['items_per_page'] = array(
+          '#type' => 'select',
+          '#title' => $this->options['expose']['items_per_page_label'],
+          '#options' => $sanitized_options,
+          '#default_value' => $this->get_items_per_page(),
+        );
+      }
+    }
+
+    if ($this->offset_exposed()) {
+      $form['offset'] = array(
+        '#type' => 'textfield',
+        '#size' => 10,
+        '#maxlength' => 10,
+        '#title' => $this->options['expose']['offset_label'],
+        '#default_value' => $this->get_offset(),
+      );
+    }
+  }
+
+  function exposed_form_validate(&$form, &$form_state) {
+    if (!empty($form_state['values']['offset']) && trim($form_state['values']['offset'])) {
+      if (!is_numeric($form_state['values']['offset']) || $form_state['values']['offset'] < 0) {
+        form_set_error('offset', t('Offset must be an number greather or equal than 0.'));
+      }
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/pager/MiniPager.php b/lib/Drupal/views/Plugins/views/pager/MiniPager.php
new file mode 100644
index 0000000..5990d2c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/pager/MiniPager.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\pager\MiniPager.
+ */
+
+namespace Drupal\views\Plugins\views\pager;
+
+/**
+ * The plugin to handle full pager.
+ *
+ * @ingroup views_pager_plugins
+ */
+class MiniPager extends PagerPlugin {
+  function summary_title() {
+    if (!empty($this->options['offset'])) {
+      return format_plural($this->options['items_per_page'], 'Mini pager, @count item, skip @skip', 'Mini pager, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
+    }
+      return format_plural($this->options['items_per_page'], 'Mini pager, @count item', 'Mini pager, @count items', array('@count' => $this->options['items_per_page']));
+  }
+
+  function render($input) {
+    $pager_theme = views_theme_functions('views_mini_pager', $this->view, $this->display);
+    return theme($pager_theme, array(
+      'parameters' => $input, 'element' => $this->options['id']));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/pager/PagerNone.php b/lib/Drupal/views/Plugins/views/pager/PagerNone.php
new file mode 100644
index 0000000..31138d1
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/pager/PagerNone.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\pager\PagerNone.
+ */
+
+namespace Drupal\views\Plugins\views\pager;
+
+/**
+ * Plugin for views without pagers.
+ *
+ * @ingroup views_pager_plugins
+ */
+class PagerNone extends PagerPlugin {
+
+  function init(&$view, &$display, $options = array()) {
+    parent::init($view, $display, $options);
+
+    // If the pager is set to none, then it should show all items.
+    $this->set_items_per_page(0);
+  }
+
+  function summary_title() {
+    if (!empty($this->options['offset'])) {
+      return t('All items, skip @skip', array('@skip' => $this->options['offset']));
+    }
+    return t('All items');
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['offset'] = array('default' => 0);
+
+    return $options;
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['offset'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Offset'),
+      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
+      '#default_value' => $this->options['offset'],
+    );
+  }
+
+  function use_pager() {
+    return FALSE;
+  }
+
+  function use_count_query() {
+    return FALSE;
+  }
+
+  function get_items_per_page() {
+    return 0;
+  }
+
+  function execute_count_query(&$count_query) {
+    // If we are displaying all items, never count. But we can update the count in post_execute.
+  }
+
+  function post_execute(&$result) {
+    $this->total_items = count($result);
+  }
+
+  function query() {
+    // The only query modifications we might do are offsets.
+    if (!empty($this->options['offset'])) {
+      $this->view->query->set_offset($this->options['offset']);
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/pager/PagerPlugin.php b/lib/Drupal/views/Plugins/views/pager/PagerPlugin.php
new file mode 100644
index 0000000..f7fc078
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/pager/PagerPlugin.php
@@ -0,0 +1,240 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\pager\PagerPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\pager;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_pager_plugins Views pager plugins
+ * @{
+ * @todo.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * The base plugin to handle pager.
+ */
+class PagerPlugin extends Plugin {
+  var $current_page = NULL;
+  var $total_items = 0;
+
+  /**
+   * Initialize the plugin.
+   *
+   * @param $view
+   *   The view object.
+   * @param $display
+   *   The display handler.
+   */
+  function init(&$view, &$display, $options = array()) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    $this->unpack_options($this->options, $options);
+  }
+
+  /**
+   * Get how many items per page this pager will display.
+   *
+   * All but the leanest pagers should probably return a value here, so
+   * most pagers will not need to override this method.
+   */
+  function get_items_per_page() {
+    return isset($this->options['items_per_page']) ? $this->options['items_per_page'] : 0;
+  }
+
+  /**
+   * Set how many items per page this pager will display.
+   *
+   * This is mostly used for things that will override the value.
+   */
+  function set_items_per_page($items) {
+    $this->options['items_per_page'] = $items;
+  }
+
+  /**
+   * Get the page offset, or how many items to skip.
+   *
+   * Even pagers that don't actually page can skip items at the beginning,
+   * so few pagers will need to override this method.
+   */
+  function get_offset() {
+    return isset($this->options['offset']) ? $this->options['offset'] : 0;
+  }
+
+  /**
+   * Set the page offset, or how many items to skip.
+   */
+  function set_offset($offset) {
+    $this->options['offset'] = $offset;
+  }
+
+  /**
+   * Get the current page.
+   *
+   * If NULL, we do not know what the current page is.
+   */
+  function get_current_page() {
+    return $this->current_page;
+  }
+
+  /**
+   * Set the current page.
+   *
+   * @param $number
+   *   If provided, the page number will be set to this. If NOT provided,
+   *   the page number will be set from the global page array.
+   */
+  function set_current_page($number = NULL) {
+    if (!is_numeric($number) || $number < 0) {
+      $number = 0;
+    }
+    $this->current_page = $number;
+  }
+
+  /**
+   * Get the total number of items.
+   *
+   * If NULL, we do not yet know what the total number of items are.
+   */
+  function get_total_items() {
+    return $this->total_items;
+  }
+
+  /**
+   * Get the pager id, if it exists
+   */
+  function get_pager_id() {
+    return isset($this->options['id']) ? $this->options['id'] : 0;
+  }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  /**
+   * Return a string to display as the clickable title for the
+   * pager plugin.
+   */
+  function summary_title() {
+    return t('Unknown');
+  }
+
+  /**
+   * Determine if this pager actually uses a pager.
+   *
+   * Only a couple of very specific pagers will set this to false.
+   */
+  function use_pager() {
+    return TRUE;
+  }
+
+  /**
+   * Determine if a pager needs a count query.
+   *
+   * If a pager needs a count query, a simple query
+   */
+  function use_count_query() {
+    return TRUE;
+  }
+
+  /**
+   * Execute the count query, which will be done just prior to the query
+   * itself being executed.
+   */
+  function execute_count_query(&$count_query) {
+    $this->total_items = $count_query->execute()->fetchField();
+    if (!empty($this->options['offset'])) {
+      $this->total_items -= $this->options['offset'];
+    }
+
+    $this->update_page_info();
+    return $this->total_items;
+  }
+
+  /**
+   * If there are pagers that need global values set, this method can
+   * be used to set them. It will be called when the count query is run.
+   */
+  function update_page_info() {
+
+  }
+
+  /**
+   * Modify the query for paging
+   *
+   * This is called during the build phase and can directly modify the query.
+   */
+  function query() { }
+
+  /**
+   * Perform any needed actions just prior to the query executing.
+   */
+  function pre_execute(&$query) { }
+
+  /**
+   * Perform any needed actions just after the query executing.
+   */
+  function post_execute(&$result) { }
+
+  /**
+   * Perform any needed actions just before rendering.
+   */
+  function pre_render(&$result) { }
+
+  /**
+   * Render the pager.
+   *
+   * Called during the view render process, this will render the
+   * pager.
+   *
+   * @param $input
+   *   Any extra GET parameters that should be retained, such as exposed
+   *   input.
+   */
+  function render($input) { }
+
+  /**
+   * Determine if there are more records available.
+   *
+   * This is primarily used to control the display of a more link.
+   */
+  function has_more_records() {
+    return $this->get_items_per_page()
+      && $this->total_items > (intval($this->current_page) + 1) * $this->get_items_per_page();
+  }
+
+  function exposed_form_alter(&$form, &$form_state) { }
+
+  function exposed_form_validate(&$form, &$form_state) { }
+
+  function exposed_form_submit(&$form, &$form_state, &$exclude) { }
+
+  function uses_exposed() {
+    return FALSE;
+  }
+
+  function items_per_page_exposed() {
+    return FALSE;
+  }
+
+  function offset_exposed() {
+    return FALSE;
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/pager/SomePager.php b/lib/Drupal/views/Plugins/views/pager/SomePager.php
new file mode 100644
index 0000000..a9dbbba
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/pager/SomePager.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\pager\SomePager.
+ */
+
+namespace Drupal\views\Plugins\views\pager;
+
+/**
+ * Plugin for views without pagers.
+ *
+ * @ingroup views_pager_plugins
+ */
+class SomePager extends PagerPlugin {
+  function summary_title() {
+    if (!empty($this->options['offset'])) {
+      return format_plural($this->options['items_per_page'], '@count item, skip @skip', '@count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
+    }
+      return format_plural($this->options['items_per_page'], '@count item', '@count items', array('@count' => $this->options['items_per_page']));
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['items_per_page'] = array('default' => 10);
+    $options['offset'] = array('default' => 0);
+
+    return $options;
+  }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $pager_text = $this->display->handler->get_pager_text();
+    $form['items_per_page'] = array(
+      '#title' => $pager_text['items per page title'],
+      '#type' => 'textfield',
+      '#description' => $pager_text['items per page description'],
+      '#default_value' => $this->options['items_per_page'],
+    );
+
+    $form['offset'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Offset'),
+      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
+      '#default_value' => $this->options['offset'],
+    );
+  }
+
+  function use_pager() {
+    return FALSE;
+  }
+
+  function use_count_query() {
+    return FALSE;
+  }
+
+  function query() {
+    $this->view->query->set_limit($this->options['items_per_page']);
+    $this->view->query->set_offset($this->options['offset']);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/query/QueryInterface.php b/lib/Drupal/views/Plugins/views/query/QueryInterface.php
new file mode 100644
index 0000000..298386c
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/query/QueryInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugin\Query\QueryInterface.
+ */
+
+namespace Drupal\views\Plugins\views\query;
+
+use Drupal\views\Plugins\views\PluginInterface;
+
+interface QueryInterface extends PluginInterface {
+
+}
diff --git a/lib/Drupal/views/Plugins/views/query/QueryPlugin.php b/lib/Drupal/views/Plugins/views/query/QueryPlugin.php
new file mode 100644
index 0000000..b015011
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/query/QueryPlugin.php
@@ -0,0 +1,174 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\query\QueryPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\Query;
+
+use Drupal\views\Plugins\views\Plugin;
+use Drupal\views\Plugins\views\Query\QueryInterface;
+
+abstract class QueryPlugin extends Plugin implements QueryInterface {
+  /**
+   * A pager plugin that should be provided by the display.
+   *
+   * @var views_plugin_pager
+   */
+  var $pager = NULL;
+
+  /**
+   * Constructor; Create the basic query object and fill with default values.
+   */
+  function init($base_table, $base_field, $options) {
+    $this->base_table = $base_table;
+    $this->base_field = $base_field;
+    $this->unpack_options($this->options, $options);
+  }
+
+  /**
+   * Generate a query and a countquery from all of the information supplied
+   * to the object.
+   *
+   * @param $get_count
+   *   Provide a countquery if this is true, otherwise provide a normal query.
+   */
+  function query($get_count = FALSE) { }
+
+  /**
+   * Let modules modify the query just prior to finalizing it.
+   *
+   * @param view $view
+   *   The view which is executed.
+   */
+  function alter(&$view) {  }
+
+  /**
+   * Builds the necessary info to execute the query.
+   *
+   * @param view $view
+   *   The view which is executed.
+   */
+  function build(&$view) { }
+
+  /**
+   * Executes the query and fills the associated view object with according
+   * values.
+   *
+   * Values to set: $view->result, $view->total_rows, $view->execute_time,
+   * $view->pager['current_page'].
+   *
+   * $view->result should contain an array of objects.
+   *
+   * @param view $view
+   *   The view which is executed.
+   */
+  function execute(&$view) {  }
+
+  /**
+   * Add a signature to the query, if such a thing is feasible.
+   *
+   * This signature is something that can be used when perusing query logs to
+   * discern where particular queries might be coming from.
+   *
+   * @param view $view
+   *   The view which is executed.
+   */
+  function add_signature(&$view) { }
+
+  /**
+   * Get aggregation info for group by queries.
+   *
+   * If NULL, aggregation is not allowed.
+   */
+  function get_aggregation_info() { }
+
+  /**
+   * Add settings for the ui.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+  }
+
+  function options_validate(&$form, &$form_state) { }
+
+  function options_submit(&$form, &$form_state) { }
+
+  function summary_title() {
+    return t('Settings');
+  }
+
+  /**
+   * Set a LIMIT on the query, specifying a maximum number of results.
+   */
+  function set_limit($limit) {
+    $this->limit = $limit;
+  }
+
+  /**
+   * Set an OFFSET on the query, specifying a number of results to skip
+   */
+  function set_offset($offset) {
+    $this->offset = $offset;
+  }
+
+  /**
+   * Render the pager, if necessary.
+   */
+  function render_pager($exposed_input) {
+    if (!empty($this->pager) && $this->pager->use_pager()) {
+      return $this->pager->render($exposed_input);
+    }
+
+    return '';
+  }
+
+  /**
+   * Create a new grouping for the WHERE or HAVING clause.
+   *
+   * @param $type
+   *   Either 'AND' or 'OR'. All items within this group will be added
+   *   to the WHERE clause with this logical operator.
+   * @param $group
+   *   An ID to use for this group. If unspecified, an ID will be generated.
+   * @param $where
+   *   'where' or 'having'.
+   *
+   * @return $group
+   *   The group ID generated.
+   */
+  function set_where_group($type = 'AND', $group = NULL, $where = 'where') {
+    // Set an alias.
+    $groups = &$this->$where;
+
+    if (!isset($group)) {
+      $group = empty($groups) ? 1 : max(array_keys($groups)) + 1;
+    }
+
+    // Create an empty group
+    if (empty($groups[$group])) {
+      $groups[$group] = array('conditions' => array(), 'args' => array());
+    }
+
+    $groups[$group]['type'] = strtoupper($type);
+    return $group;
+  }
+
+  /**
+   * Control how all WHERE and HAVING groups are put together.
+   *
+   * @param $type
+   *   Either 'AND' or 'OR'
+   */
+  function set_group_operator($type = 'AND') {
+    $this->group_operator = strtoupper($type);
+  }
+
+  /**
+   * Returns the according entity objects for the given query results.
+   */
+  function get_result_entities($results, $relationship = NULL) {
+    return FALSE;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/query/SqlQuery.php b/lib/Drupal/views/Plugins/views/query/SqlQuery.php
new file mode 100644
index 0000000..e18f1dc
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/query/SqlQuery.php
@@ -0,0 +1,1642 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\query\SqlQuery.
+ */
+
+namespace Drupal\views\Plugins\views\query;
+
+use Drupal\Core\Database\Database;
+use Drupal\views\Join;
+use Exception;
+
+class SqlQuery extends QueryPlugin {
+  /**
+   * A list of tables in the order they should be added, keyed by alias.
+   */
+  var $table_queue = array();
+
+  /**
+   * Holds an array of tables and counts added so that we can create aliases
+   */
+  var $tables = array();
+
+  /**
+   * Holds an array of relationships, which are aliases of the primary
+   * table that represent different ways to join the same table in.
+   */
+  var $relationships = array();
+
+  /**
+   * An array of sections of the WHERE query. Each section is in itself
+   * an array of pieces and a flag as to whether or not it should be AND
+   * or OR.
+   */
+  var $where = array();
+  /**
+   * An array of sections of the HAVING query. Each section is in itself
+   * an array of pieces and a flag as to whether or not it should be AND
+   * or OR.
+   */
+  var $having = array();
+  /**
+   * The default operator to use when connecting the WHERE groups. May be
+   * AND or OR.
+   */
+  var $group_operator = 'AND';
+
+  /**
+   * A simple array of order by clauses.
+   */
+  var $orderby = array();
+
+  /**
+   * A simple array of group by clauses.
+   */
+  var $groupby = array();
+
+
+  /**
+   * An array of fields.
+   */
+  var $fields = array();
+
+
+  /**
+   * The table header to use for tablesort. This matters because tablesort
+   * needs to modify the query and needs the header.
+   */
+  var $header = array();
+
+  /**
+   * A flag as to whether or not to make the primary field distinct.
+   */
+  var $distinct = FALSE;
+
+  var $has_aggregate = FALSE;
+
+  /**
+   * Should this query be optimized for counts, for example no sorts.
+   */
+  var $get_count_optimized = NULL;
+
+  /**
+   * The current used pager plugin.
+   *
+   * @var views_plugin_pager
+   */
+  var $pager = NULL;
+
+  /**
+   * 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();
+
+  /**
+   * Is the view marked as not distinct.
+   *
+   * @var bool
+   */
+  var $no_distinct;
+
+  /**
+   * Defines the distinct type.
+   * - FALSE if it's distinct by base field.
+   * - TRUE if it just adds the sql distinct keyword.
+   *
+   * @var bool
+   */
+  public $pure_distinct = FALSE;
+
+  /**
+   * Constructor; Create the basic query object and fill with default values.
+   */
+  function init($base_table = 'node', $base_field = 'nid', $options) {
+    parent::init($base_table, $base_field, $options);
+    $this->base_table = $base_table;  // Predefine these above, for clarity.
+    $this->base_field = $base_field;
+    $this->relationships[$base_table] = array(
+      'link' => NULL,
+      'table' => $base_table,
+      'alias' => $base_table,
+      'base' => $base_table
+    );
+
+    // init the table queue with our primary table.
+    $this->table_queue[$base_table] = array(
+      'alias' => $base_table,
+      'table' => $base_table,
+      'relationship' => $base_table,
+      'join' => NULL,
+    );
+
+    // init the tables with our primary table
+    $this->tables[$base_table][$base_table] = array(
+      'count' => 1,
+      'alias' => $base_table,
+    );
+
+    /**
+     * -- 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->count_field = array(
+      'table' => $base_table,
+      'field' => $base_field,
+      'alias' => $base_field,
+      'count' => TRUE,
+    );
+  }
+
+  // ----------------------------------------------------------------
+  // Utility methods to set flags and data.
+
+  /**
+   * Set the view to be distinct.
+   *
+   * There are either distinct per base field or distinct in the pure sql way,
+   * based on $pure_distinct.
+   *
+   * @param bool $value
+   *   Should the view by distincted.
+   * @param bool $pure_distinct
+   *   Should only the sql keyword be added.
+   */
+  function set_distinct($value = TRUE, $pure_distinct = FALSE) {
+    if (!(isset($this->no_distinct) && $value)) {
+      $this->distinct = $value;
+      $this->pure_distinct = $pure_distinct;
+    }
+  }
+
+  /**
+   * Set what field the query will count() on for paging.
+   */
+  function set_count_field($table, $field, $alias = NULL) {
+    if (empty($alias)) {
+      $alias = $table . '_' . $field;
+    }
+    $this->count_field = array(
+      'table' => $table,
+      'field' => $field,
+      'alias' => $alias,
+      'count' => TRUE,
+    );
+  }
+
+  /**
+   * Set the table header; used for click-sorting because it's needed
+   * info to modify the ORDER BY clause.
+   */
+  function set_header($header) {
+    $this->header = $header;
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['disable_sql_rewrite'] = array(
+      'default' => FALSE,
+      'translatable' => FALSE,
+      'bool' => TRUE,
+    );
+    $options['distinct'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+    $options['pure_distinct'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+    $options['slave'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
+    $options['query_comment'] = array(
+      'default' => '',
+    );
+    $options['query_tags'] = array(
+      'default' => array(),
+    );
+
+    return $options;
+  }
+
+  /**
+   * Add settings for the ui.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['disable_sql_rewrite'] = array(
+      '#title' => t('Disable SQL rewriting'),
+      '#description' => t('Disabling SQL rewriting will disable node_access checks as well as other modules that implement hook_query_alter().'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['disable_sql_rewrite']),
+      '#suffix' => '<div class="messages warning sql-rewrite-warning js-hide">' . t('WARNING: Disabling SQL rewriting means that node access security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Please use this option only if you understand and accept this security risk.') . '</div>',
+    );
+    $form['distinct'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Distinct'),
+      '#description' => t('This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.'),
+      '#default_value' => !empty($this->options['distinct']),
+    );
+    $form['pure_distinct'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Pure Distinct'),
+      '#description' => t('This will prevent views from adding the base column to the distinct field. If this is not selected and the base column is a primary key, then a non-pure distinct will not function properly because the primary key is always unique.'),
+      '#default_value' => !empty($this->options['pure_distinct']),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="query[options][distinct]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    $form['slave'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use Slave Server'),
+      '#description' => t('This will make the query attempt to connect to a slave server if available.  If no slave server is defined or available, it will fall back to the default server.'),
+      '#default_value' => !empty($this->options['slave']),
+    );
+    $form['query_comment'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Query Comment'),
+      '#description' => t('If set, this comment will be embedded in the query and passed to the SQL server. This can be helpful for logging or debugging.'),
+      '#default_value' => $this->options['query_comment'],
+    );
+    $form['query_tags'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Query Tags'),
+      '#description' => t('If set, these tags will be appended to the query and can be used to identify the query in a module. This can be helpful for altering queries.'),
+      '#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';
+  }
+
+  /**
+   * Special submit handling.
+   */
+  function options_submit(&$form, &$form_state) {
+    $element = array('#parents' => array('query', 'options', 'query_tags'));
+    $value = explode(',', drupal_array_get_nested_value($form_state['values'], $element['#parents']));
+    $value = array_filter(array_map('trim', $value));
+    form_set_value($element, $value, $form_state);
+  }
+
+  // ----------------------------------------------------------------
+  // Table/join adding
+
+  /**
+   * A relationship is an alternative endpoint to a series of table
+   * joins. Relationships must be aliases of the primary table and
+   * they must join either to the primary table or to a pre-existing
+   * relationship.
+   *
+   * An example of a relationship would be a nodereference table.
+   * If you have a nodereference named 'book_parent' which links to a
+   * parent node, you could set up a relationship 'node_book_parent'
+   * to 'node'. Then, anything that links to 'node' can link to
+   * 'node_book_parent' instead, thus allowing all properties of
+   * both nodes to be available in the query.
+   *
+   * @param $alias
+   *   What this relationship will be called, and is also the alias
+   *   for the table.
+   * @param Drupal\views\Join $join
+   *   A Join object (or derived object) to join the alias in.
+   * @param $base
+   *   The name of the 'base' table this relationship represents; this
+   *   tells the join search which path to attempt to use when finding
+   *   the path to this relationship.
+   * @param $link_point
+   *   If this relationship links to something other than the primary
+   *   table, specify that table here. For example, a 'track' node
+   *   might have a relationship to an 'album' node, which might
+   *   have a relationship to an 'artist' node.
+   */
+  function add_relationship($alias, Join $join, $base, $link_point = NULL) {
+    if (empty($link_point)) {
+      $link_point = $this->base_table;
+    }
+    elseif (!array_key_exists($link_point, $this->relationships)) {
+      return FALSE;
+    }
+
+    // Make sure $alias isn't already used; if it, start adding stuff.
+    $alias_base = $alias;
+    $count = 1;
+    while (!empty($this->relationships[$alias])) {
+      $alias = $alias_base . '_' . $count++;
+    }
+
+    // Make sure this join is adjusted for our relationship.
+    if ($link_point && isset($this->relationships[$link_point])) {
+      $join = $this->adjust_join($join, $link_point);
+    }
+
+    // Add the table directly to the queue to avoid accidentally marking
+    // it.
+    $this->table_queue[$alias] = array(
+      'table' => $join->table,
+      'num' => 1,
+      'alias' => $alias,
+      'join' => $join,
+      'relationship' => $link_point,
+    );
+
+    $this->relationships[$alias] = array(
+      'link' => $link_point,
+      'table' => $join->table,
+      'base' => $base,
+    );
+
+    $this->tables[$this->base_table][$alias] = array(
+      'count' => 1,
+      'alias' => $alias,
+    );
+
+    return $alias;
+  }
+
+  /**
+   * Add a table to the query, ensuring the path exists.
+   *
+   * This function will test to ensure that the path back to the primary
+   * table is valid and exists; if you do not wish for this testing to
+   * occur, use $query->queue_table() instead.
+   *
+   * @param $table
+   *   The name of the table to add. It needs to exist in the global table
+   *   array.
+   * @param $relationship
+   *   An alias of a table; if this is set, the path back to this table will
+   *   be tested prior to adding the table, making sure that all intermediary
+   *   tables exist and are properly aliased. If set to NULL the path to
+   *   the primary table will be ensured. If the path cannot be made, the
+   *   table will NOT be added.
+   * @param Drupal\views\Join $join
+   *   In some join configurations this table may actually join back through
+   *   a different method; this is most likely to be used when tracing
+   *   a hierarchy path. (node->parent->parent2->parent3). This parameter
+   *   will specify how this table joins if it is not the default.
+   * @param $alias
+   *   A specific alias to use, rather than the default alias.
+   *
+   * @return $alias
+   *   The alias of the table; this alias can be used to access information
+   *   about the table and should always be used to refer to the table when
+   *   adding parts to the query. Or FALSE if the table was not able to be
+   *   added.
+   */
+  function add_table($table, $relationship = NULL, Join $join = NULL, $alias = NULL) {
+    if (!$this->ensure_path($table, $relationship, $join)) {
+      return FALSE;
+    }
+
+    if ($join && $relationship) {
+      $join = $this->adjust_join($join, $relationship);
+    }
+
+    return $this->queue_table($table, $relationship, $join, $alias);
+  }
+
+  /**
+   * Add a table to the query without ensuring the path.
+   *
+   * This is a pretty internal function to Views and add_table() or
+   * ensure_table() should be used instead of this one, unless you are
+   * absolutely sure this is what you want.
+   *
+   * @param $table
+   *   The name of the table to add. It needs to exist in the global table
+   *   array.
+   * @param $relationship
+   *   The primary table alias this table is related to. If not set, the
+   *   primary table will be used.
+   * @param Drupal\views\Join $join
+   *   In some join configurations this table may actually join back through
+   *   a different method; this is most likely to be used when tracing
+   *   a hierarchy path. (node->parent->parent2->parent3). This parameter
+   *   will specify how this table joins if it is not the default.
+   * @param $alias
+   *   A specific alias to use, rather than the default alias.
+   *
+   * @return $alias
+   *   The alias of the table; this alias can be used to access information
+   *   about the table and should always be used to refer to the table when
+   *   adding parts to the query. Or FALSE if the table was not able to be
+   *   added.
+   */
+  function queue_table($table, $relationship = NULL, Join $join = NULL, $alias = NULL) {
+    // If the alias is set, make sure it doesn't already exist.
+    if (isset($this->table_queue[$alias])) {
+      return $alias;
+    }
+
+    if (empty($relationship)) {
+      $relationship = $this->base_table;
+    }
+
+    if (!array_key_exists($relationship, $this->relationships)) {
+      return FALSE;
+    }
+
+    if (!$alias && $join && $relationship && !empty($join->adjusted) && $table != $join->table) {
+      if ($relationship == $this->base_table) {
+        $alias = $table;
+      }
+      else {
+        $alias = $relationship . '_' . $table;
+      }
+    }
+
+    // Check this again to make sure we don't blow up existing aliases for already
+    // adjusted joins.
+    if (isset($this->table_queue[$alias])) {
+      return $alias;
+    }
+
+    $alias = $this->mark_table($table, $relationship, $alias);
+
+    // If no alias is specified, give it the default.
+    if (!isset($alias)) {
+      $alias = $this->tables[$relationship][$table]['alias'] . $this->tables[$relationship][$table]['count'];
+    }
+
+    // If this is a relationship based table, add a marker with
+    // the relationship as a primary table for the alias.
+    if ($table != $alias) {
+      $this->mark_table($alias, $this->base_table, $alias);
+    }
+
+    // If no join is specified, pull it from the table data.
+    if (!isset($join)) {
+      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
+      if (empty($join)) {
+        return FALSE;
+      }
+
+      $join = $this->adjust_join($join, $relationship);
+    }
+
+    $this->table_queue[$alias] = array(
+      'table' => $table,
+      'num' => $this->tables[$relationship][$table]['count'],
+      'alias' => $alias,
+      'join' => $join,
+      'relationship' => $relationship,
+    );
+
+    return $alias;
+  }
+
+  function mark_table($table, $relationship, $alias) {
+    // Mark that this table has been added.
+    if (empty($this->tables[$relationship][$table])) {
+      if (!isset($alias)) {
+        $alias = '';
+        if ($relationship != $this->base_table) {
+          // double underscore will help prevent accidental name
+          // space collisions.
+          $alias = $relationship . '__';
+        }
+        $alias .= $table;
+      }
+      $this->tables[$relationship][$table] = array(
+        'count' => 1,
+        'alias' => $alias,
+      );
+    }
+    else {
+      $this->tables[$relationship][$table]['count']++;
+    }
+
+    return $alias;
+  }
+
+  /**
+   * Ensure a table exists in the queue; if it already exists it won't
+   * do anything, but if it doesn't it will add the table queue. It will ensure
+   * a path leads back to the relationship table.
+   *
+   * @param $table
+   *   The unaliased name of the table to ensure.
+   * @param $relationship
+   *   The relationship to ensure the table links to. Each relationship will
+   *   get a unique instance of the table being added. If not specified,
+   *   will be the primary table.
+   * @param Drupal\views\Join $join
+   *   A Join object (or derived object) to join the alias in.
+   *
+   * @return
+   *   The alias used to refer to this specific table, or NULL if the table
+   *   cannot be ensured.
+   */
+  function ensure_table($table, $relationship = NULL, Join $join = NULL) {
+    // ensure a relationship
+    if (empty($relationship)) {
+      $relationship = $this->base_table;
+    }
+
+    // If the relationship is the primary table, this actually be a relationship
+    // link back from an alias. We store all aliases along with the primary table
+    // to detect this state, because eventually it'll hit a table we already
+    // have and that's when we want to stop.
+    if ($relationship == $this->base_table && !empty($this->tables[$relationship][$table])) {
+      return $this->tables[$relationship][$table]['alias'];
+    }
+
+    if (!array_key_exists($relationship, $this->relationships)) {
+      return FALSE;
+    }
+
+    if ($table == $this->relationships[$relationship]['base']) {
+      return $relationship;
+    }
+
+    // If we do not have join info, fetch it.
+    if (!isset($join)) {
+      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
+    }
+
+    // If it can't be fetched, this won't work.
+    if (empty($join)) {
+      return;
+    }
+
+    // Adjust this join for the relationship, which will ensure that the 'base'
+    // table it links to is correct. Tables adjoined to a relationship
+    // join to a link point, not the base table.
+    $join = $this->adjust_join($join, $relationship);
+
+    if ($this->ensure_path($table, $relationship, $join)) {
+      // Attempt to eliminate redundant joins.  If this table's
+      // relationship and join exactly matches an existing table's
+      // relationship and join, we do not have to join to it again;
+      // just return the existing table's alias.  See
+      // http://groups.drupal.org/node/11288 for details.
+      //
+      // This can be done safely here but not lower down in
+      // queue_table(), because queue_table() is also used by
+      // add_table() which requires the ability to intentionally add
+      // the same table with the same join multiple times.  For
+      // example, a view that filters on 3 taxonomy terms using AND
+      // needs to join taxonomy_term_data 3 times with the same join.
+
+      // scan through the table queue to see if a matching join and
+      // relationship exists.  If so, use it instead of this join.
+
+      // TODO: Scanning through $this->table_queue results in an
+      // O(N^2) algorithm, and this code runs every time the view is
+      // instantiated (Views 2 does not currently cache queries).
+      // There are a couple possible "improvements" but we should do
+      // some performance testing before picking one.
+      foreach ($this->table_queue as $queued_table) {
+        // In PHP 4 and 5, the == operation returns TRUE for two objects
+        // if they are instances of the same class and have the same
+        // attributes and values.
+        if ($queued_table['relationship'] == $relationship && $queued_table['join'] == $join) {
+          return $queued_table['alias'];
+        }
+      }
+
+      return $this->queue_table($table, $relationship, $join);
+    }
+  }
+
+  /**
+   * Make sure that the specified table can be properly linked to the primary
+   * table in the JOINs. This function uses recursion. If the tables
+   * needed to complete the path back to the primary table are not in the
+   * query they will be added, but additional copies will NOT be added
+   * if the table is already there.
+   */
+  function ensure_path($table, $relationship = NULL, $join = NULL, $traced = array(), $add = array()) {
+    if (!isset($relationship)) {
+      $relationship = $this->base_table;
+    }
+
+    if (!array_key_exists($relationship, $this->relationships)) {
+      return FALSE;
+    }
+
+    // If we do not have join info, fetch it.
+    if (!isset($join)) {
+      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
+    }
+
+    // If it can't be fetched, this won't work.
+    if (empty($join)) {
+      return FALSE;
+    }
+
+    // Does a table along this path exist?
+    if (isset($this->tables[$relationship][$table]) ||
+      ($join && $join->left_table == $relationship) ||
+      ($join && $join->left_table == $this->relationships[$relationship]['table'])) {
+
+      // Make sure that we're linking to the correct table for our relationship.
+      foreach (array_reverse($add) as $table => $path_join) {
+        $this->queue_table($table, $relationship, $this->adjust_join($path_join, $relationship));
+      }
+      return TRUE;
+    }
+
+    // Have we been this way?
+    if (isset($traced[$join->left_table])) {
+      // we looped. Broked.
+      return FALSE;
+    }
+
+    // Do we have to add this table?
+    $left_join = $this->get_join_data($join->left_table, $this->relationships[$relationship]['base']);
+    if (!isset($this->tables[$relationship][$join->left_table])) {
+      $add[$join->left_table] = $left_join;
+    }
+
+    // Keep looking.
+    $traced[$join->left_table] = TRUE;
+    return $this->ensure_path($join->left_table, $relationship, $left_join, $traced, $add);
+  }
+
+  /**
+   * Fix a join to adhere to the proper relationship; the left table can vary
+   * based upon what relationship items are joined in on.
+   */
+  function adjust_join($join, $relationship) {
+    if (!empty($join->adjusted)) {
+      return $join;
+    }
+
+    if (empty($relationship) || empty($this->relationships[$relationship])) {
+      return $join;
+    }
+
+    // Adjusts the left table for our relationship.
+    if ($relationship != $this->base_table) {
+      // If we're linking to the primary table, the relationship to use will
+      // be the prior relationship. Unless it's a direct link.
+
+      // Safety! Don't modify an original here.
+      $join = clone $join;
+
+      // 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'])) {
+        $this->ensure_table($join->left_table, $relationship);
+      }
+
+      // First, if this is our link point/anchor table, just use the relationship
+      if ($join->left_table == $this->relationships[$relationship]['table']) {
+        $join->left_table = $relationship;
+      }
+      // then, try the base alias.
+      elseif (isset($this->tables[$relationship][$join->left_table]['alias'])) {
+        $join->left_table = $this->tables[$relationship][$join->left_table]['alias'];
+      }
+      // But if we're already looking at an alias, use that instead.
+      elseif (isset($this->table_queue[$relationship]['alias'])) {
+        $join->left_table = $this->table_queue[$relationship]['alias'];
+      }
+    }
+
+    $join->adjusted = TRUE;
+    return $join;
+  }
+
+  /**
+   * Retrieve join data from the larger join data cache.
+   *
+   * @param $table
+   *   The table to get the join information for.
+   * @param $base_table
+   *   The path we're following to get this join.
+   *
+   * @return Drupal\views\Join
+   *   A Join object or child object, if one exists.
+   */
+  function get_join_data($table, $base_table) {
+    // Check to see if we're linking to a known alias. If so, get the real
+    // table's data instead.
+    if (!empty($this->table_queue[$table])) {
+      $table = $this->table_queue[$table]['table'];
+    }
+    return views_get_table_join($table, $base_table);
+  }
+
+  /**
+   * Get the information associated with a table.
+   *
+   * If you need the alias of a table with a particular relationship, use
+   * ensure_table().
+   */
+  function get_table_info($table) {
+    if (!empty($this->table_queue[$table])) {
+      return $this->table_queue[$table];
+    }
+
+    // In rare cases we might *only* have aliased versions of the table.
+    if (!empty($this->tables[$this->base_table][$table])) {
+      $alias = $this->tables[$this->base_table][$table]['alias'];
+      if (!empty($this->table_queue[$alias])) {
+        return $this->table_queue[$alias];
+      }
+    }
+  }
+
+  /**
+   * Add a field to the query table, possibly with an alias. This will
+   * automatically call ensure_table to make sure the required table
+   * exists, *unless* $table is unset.
+   *
+   * @param $table
+   *   The table this field is attached to. If NULL, it is assumed this will
+   *   be a formula; otherwise, ensure_table is used to make sure the
+   *   table exists.
+   * @param $field
+   *   The name of the field to add. This may be a real field or a formula.
+   * @param $alias
+   *   The alias to create. If not specified, the alias will be $table_$field
+   *   unless $table is NULL. When adding formulae, it is recommended that an
+   *   alias be used.
+   * @param $params
+   *   An array of parameters additional to the field that will control items
+   *   such as aggregation functions and DISTINCT.
+   *
+   * @return $name
+   *   The name that this field can be referred to as. Usually this is the alias.
+   */
+  function add_field($table, $field, $alias = '', $params = array()) {
+    // We check for this specifically because it gets a special alias.
+    if ($table == $this->base_table && $field == $this->base_field && empty($alias)) {
+      $alias = $this->base_field;
+    }
+
+    if ($table && empty($this->table_queue[$table])) {
+      $this->ensure_table($table);
+    }
+
+    if (!$alias && $table) {
+      $alias = $table . '_' . $field;
+    }
+
+    // Make sure an alias is assigned
+    $alias = $alias ? $alias : $field;
+
+    // PostgreSQL truncates aliases to 63 characters: http://drupal.org/node/571548
+
+    // We limit the length of the original alias up to 60 characters
+    // to get a unique alias later if its have duplicates
+    $alias = strtolower(substr($alias, 0, 60));
+
+    // Create a field info array.
+    $field_info = array(
+      'field' => $field,
+      'table' => $table,
+      'alias' => $alias,
+    ) + $params;
+
+    // Test to see if the field is actually the same or not. Due to
+    // differing parameters changing the aggregation function, we need
+    // to do some automatic alias collision detection:
+    $base = $alias;
+    $counter = 0;
+    while (!empty($this->fields[$alias]) && $this->fields[$alias] != $field_info) {
+      $field_info['alias'] = $alias = $base . '_' . ++$counter;
+    }
+
+    if (empty($this->fields[$alias])) {
+      $this->fields[$alias] = $field_info;
+    }
+
+    // Keep track of all aliases used.
+    $this->field_aliases[$table][$field] = $alias;
+
+    return $alias;
+  }
+
+  /**
+   * Remove all fields that may've been added; primarily used for summary
+   * mode where we're changing the query because we didn't get data we needed.
+   */
+  function clear_fields() {
+    $this->fields = array();
+  }
+
+  /**
+   * Add a simple WHERE clause to the query. The caller is responsible for
+   * ensuring that all fields are fully qualified (TABLE.FIELD) and that
+   * the table already exists in the query.
+   *
+   * @param $group
+   *   The WHERE group to add these to; groups are used to create AND/OR
+   *   sections. Groups cannot be nested. Use 0 as the default group.
+   *   If the group does not yet exist it will be created as an AND group.
+   * @param $field
+   *   The name of the field to check.
+   * @param $value
+   *   The value to test the field against. In most cases, this is a scalar. For more
+   *   complex options, it is an array. The meaning of each element in the array is
+   *   dependent on the $operator.
+   * @param $operator
+   *   The comparison operator, such as =, <, or >=. It also accepts more complex
+   *   options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array
+   *   = otherwise. If $field is a string you have to use 'formula' here.
+   *
+   * @see QueryConditionInterface::condition()
+   */
+  function add_where($group, $field, $value = NULL, $operator = NULL) {
+    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
+    // the default group.
+    if (empty($group)) {
+      $group = 0;
+    }
+
+    // Check for a group.
+    if (!isset($this->where[$group])) {
+      $this->set_where_group('AND', $group);
+    }
+
+    $this->where[$group]['conditions'][] = array(
+      'field' => $field,
+      'value' => $value,
+      'operator' => $operator,
+    );
+  }
+
+  /**
+   * Add a complex WHERE clause to the query.
+   *
+   * The caller is reponsible for ensuring that all fields are fully qualified
+   * (TABLE.FIELD) and that the table already exists in the query.
+   * Internally the dbtng method "where" is used.
+   *
+   * @param $group
+   *   The WHERE group to add these to; groups are used to create AND/OR
+   *   sections. Groups cannot be nested. Use 0 as the default group.
+   *   If the group does not yet exist it will be created as an AND group.
+   * @param $snippet
+   *   The snippet to check. This can be either a column or
+   *   a complex expression like "UPPER(table.field) = 'value'"
+   * @param $args
+   *   An associative array of arguments.
+   *
+   * @see QueryConditionInterface::where()
+   */
+  function add_where_expression($group, $snippet, $args = array()) {
+    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
+    // the default group.
+    if (empty($group)) {
+      $group = 0;
+    }
+
+    // Check for a group.
+    if (!isset($this->where[$group])) {
+      $this->set_where_group('AND', $group);
+    }
+
+    $this->where[$group]['conditions'][] = array(
+      'field' => $snippet,
+      'value' => $args,
+      'operator' => 'formula',
+    );
+  }
+
+  /**
+   * Add a simple HAVING clause to the query.
+   *
+   * The caller is responsible for ensuring that all fields are fully qualified
+   * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query.
+   * Internally the dbtng method "havingCondition" is used.
+   *
+   * @param $group
+   *   The HAVING group to add these to; groups are used to create AND/OR
+   *   sections. Groups cannot be nested. Use 0 as the default group.
+   *   If the group does not yet exist it will be created as an AND group.
+   * @param $field
+   *   The name of the field to check.
+   * @param $value
+   *   The value to test the field against. In most cases, this is a scalar. For more
+   *   complex options, it is an array. The meaning of each element in the array is
+   *   dependent on the $operator.
+   * @param $operator
+   *   The comparison operator, such as =, <, or >=. It also accepts more complex
+   *   options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array
+   *   = otherwise.  If $field is a string you have to use 'formula' here.
+   *
+   * @see SelectQueryInterface::havingCondition()
+   */
+  function add_having($group, $field, $value = NULL, $operator = NULL) {
+    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
+    // the default group.
+    if (empty($group)) {
+      $group = 0;
+    }
+
+    // Check for a group.
+    if (!isset($this->having[$group])) {
+      $this->set_where_group('AND', $group, 'having');
+    }
+
+    // Add the clause and the args.
+    $this->having[$group]['conditions'][] = array(
+      'field' => $field,
+      'value' => $value,
+      'operator' => $operator,
+    );
+  }
+
+  /**
+   * Add a complex HAVING clause to the query.
+   * The caller is responsible for ensuring that all fields are fully qualified
+   * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query.
+   * Internally the dbtng method "having" is used.
+   *
+   * @param $group
+   *   The HAVING group to add these to; groups are used to create AND/OR
+   *   sections. Groups cannot be nested. Use 0 as the default group.
+   *   If the group does not yet exist it will be created as an AND group.
+   * @param $snippet
+   *   The snippet to check. This can be either a column or
+   *   a complex expression like "COUNT(table.field) > 3"
+   * @param $args
+   *   An associative array of arguments.
+   *
+   * @see QueryConditionInterface::having()
+   */
+  function add_having_expression($group, $snippet, $args = array()) {
+    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
+    // the default group.
+    if (empty($group)) {
+      $group = 0;
+    }
+
+    // Check for a group.
+    if (!isset($this->having[$group])) {
+      $this->set_where_group('AND', $group, 'having');
+    }
+
+    // Add the clause and the args.
+    $this->having[$group]['conditions'][] = array(
+      'field' => $snippet,
+      'value' => $args,
+      'operator' => 'formula',
+    );
+  }
+
+  /**
+   * Add an ORDER BY clause to the query.
+   *
+   * @param $table
+   *   The table this field is part of. If a formula, enter NULL.
+   *   If you want to orderby random use "rand" as table and nothing else.
+   * @param $field
+   *   The field or formula to sort on. If already a field, enter NULL
+   *   and put in the alias.
+   * @param $order
+   *   Either ASC or DESC.
+   * @param $alias
+   *   The alias to add the field as. In SQL, all fields in the order by
+   *   must also be in the SELECT portion. If an $alias isn't specified
+   *   one will be generated for from the $field; however, if the
+   *   $field is a formula, this alias will likely fail.
+   * @param $params
+   *   Any params that should be passed through to the add_field.
+   */
+  function add_orderby($table, $field = NULL, $order = 'ASC', $alias = '', $params = array()) {
+    // Only ensure the table if it's not the special random key.
+    // @todo: Maybe it would make sense to just add a add_orderby_rand or something similar.
+    if ($table && $table != 'rand') {
+      $this->ensure_table($table);
+    }
+
+    // Only fill out this aliasing if there is a table;
+    // otherwise we assume it is a formula.
+    if (!$alias && $table) {
+      $as = $table . '_' . $field;
+    }
+    else {
+      $as = $alias;
+    }
+
+    if ($field) {
+      $as = $this->add_field($table, $field, $as, $params);
+    }
+
+    $this->orderby[] = array(
+      'field' => $as,
+      'direction' => strtoupper($order)
+    );
+
+    /**
+     * -- 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);
+    }
+     */
+  }
+
+  /**
+   * Add a simple GROUP BY clause to the query. The caller is responsible
+   * for ensuring that the fields are fully qualified and the table is properly
+   * added.
+   */
+  function add_groupby($clause) {
+    // Only add it if it's not already in there.
+    if (!in_array($clause, $this->groupby)) {
+      $this->groupby[] = $clause;
+    }
+  }
+
+  /**
+   * Returns the alias for the given field added to $table.
+   *
+   * @see views_plugin_query_default::add_field()
+   */
+  function get_field_alias($table_alias, $field) {
+    return isset($this->field_aliases[$table_alias][$field]) ? $this->field_aliases[$table_alias][$field] : FALSE;
+  }
+
+  /**
+   * Adds a query tag to the sql object.
+   *
+   * @see SelectQuery::addTag()
+   */
+  function add_tag($tag) {
+    $this->tags[] = $tag;
+  }
+
+  /**
+   * Generates a unique placeholder used in the db query.
+   */
+  function placeholder($base = 'views') {
+    static $placeholders = array();
+    if (!isset($placeholders[$base])) {
+      $placeholders[$base] = 0;
+      return ':' . $base;
+    }
+    else {
+      return ':' . $base . ++$placeholders[$base];
+    }
+  }
+
+  /**
+   * Construct the "WHERE" or "HAVING" part of the query.
+   *
+   * As views has to wrap the conditions from arguments with AND, a special
+   * group is wrapped around all conditions. This special group has the ID 0.
+   * There is other code in filters which makes sure that the group IDs are
+   * higher than zero.
+   *
+   * @param $where
+   *   'where' or 'having'.
+   */
+  function build_condition($where = 'where') {
+    $has_condition = FALSE;
+    $has_arguments = FALSE;
+    $has_filter = FALSE;
+
+    $main_group = db_and();
+    $filter_group = $this->group_operator == 'OR' ? db_or() : db_and();
+
+    foreach ($this->$where as $group => $info) {
+
+      if (!empty($info['conditions'])) {
+        $sub_group = $info['type'] == 'OR' ? db_or() : db_and();
+        foreach ($info['conditions'] as $key => $clause) {
+          // DBTNG doesn't support to add the same subquery twice to the main
+          // query and the count query, so clone the subquery to have two instances
+          // of the same object. - http://drupal.org/node/1112854
+          if (is_object($clause['value']) && $clause['value'] instanceof SelectQuery) {
+            $clause['value'] = clone $clause['value'];
+          }
+          if ($clause['operator'] == 'formula') {
+            $has_condition = TRUE;
+            $sub_group->where($clause['field'], $clause['value']);
+          }
+          else {
+            $has_condition = TRUE;
+            $sub_group->condition($clause['field'], $clause['value'], $clause['operator']);
+          }
+        }
+
+        // Add the item to the filter group.
+        if ($group != 0) {
+          $has_filter = TRUE;
+          $filter_group->condition($sub_group);
+        }
+        else {
+          $has_arguments = TRUE;
+          $main_group->condition($sub_group);
+        }
+      }
+    }
+
+    if ($has_filter) {
+      $main_group->condition($filter_group);
+    }
+
+    if (!$has_arguments && $has_condition) {
+      return $filter_group;
+    }
+    if ($has_arguments && $has_condition) {
+      return $main_group;
+    }
+  }
+
+  /**
+   * Build fields array.
+   */
+  function compile_fields($fields_array, $query) {
+    $non_aggregates = array();
+    foreach ($fields_array as $field) {
+      $string = '';
+      if (!empty($field['table'])) {
+        $string .= $field['table'] . '.';
+      }
+      $string .= $field['field'];
+      $fieldname = (!empty($field['alias']) ? $field['alias'] : $string);
+
+      if (!empty($field['distinct'])) {
+        throw new Exception("Column-level distinct is not supported anymore.");
+      }
+
+      if (!empty($field['count'])) {
+        // Retained for compatibility
+        $field['function'] = 'count';
+        // It seems there's no way to abstract the table+column reference
+        // without adding a field, aliasing, and then using the alias.
+      }
+
+      if (!empty($field['function'])) {
+        $info = $this->get_aggregation_info();
+        if (!empty($info[$field['function']]['method']) && function_exists($info[$field['function']]['method'])) {
+          $string = $info[$field['function']]['method']($field['function'], $string);
+          $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
+          $query->addExpression($string, $fieldname, $placeholders);
+        }
+
+        $this->has_aggregate = TRUE;
+      }
+      // This is a formula, using no tables.
+      elseif (empty($field['table'])) {
+        $non_aggregates[] = $fieldname;
+        $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
+        $query->addExpression($string, $fieldname, $placeholders);
+      }
+
+      elseif ($this->distinct && !in_array($fieldname, $this->groupby)) {
+        // d7cx: This code was there, apparently needed for PostgreSQL
+        // $string = db_driver() == 'pgsql' ? "FIRST($string)" : $string;
+        $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname);
+      }
+      elseif (empty($field['aggregate'])) {
+        $non_aggregates[] = $fieldname;
+        $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname);
+      }
+
+      // @TODO Remove this old code.
+      if (!empty($field['distinct']) && empty($field['function'])) {
+        $distinct[] = $string;
+      }
+      else {
+        $fields[] = $string;
+      }
+
+      if ($this->get_count_optimized) {
+        // We only want the first field in this case.
+        break;
+      }
+    }
+    return array(
+      $non_aggregates,
+    );
+  }
+
+  /**
+   * Generate a query and a countquery from all of the information supplied
+   * to the object.
+   *
+   * @param $get_count
+   *   Provide a countquery if this is true, otherwise provide a normal query.
+   */
+  function query($get_count = FALSE) {
+    // Check query distinct value.
+    if (empty($this->no_distinct) && $this->distinct && !empty($this->fields)) {
+      if ($this->pure_distinct === FALSE){
+        $base_field_alias = $this->add_field($this->base_table, $this->base_field);
+        $this->add_groupby($base_field_alias);
+      }
+      $distinct = TRUE;
+    }
+
+    /**
+     * An optimized count query includes just the base field instead of all the fields.
+     * Determine of this query qualifies by checking for a groupby or distinct.
+     */
+    $fields_array = $this->fields;
+    if ($get_count && !$this->groupby) {
+      foreach ($fields_array as $field) {
+        if (!empty($field['distinct']) || !empty($field['function'])) {
+          $this->get_count_optimized = FALSE;
+          break;
+        }
+      }
+    }
+    else {
+      $this->get_count_optimized = FALSE;
+    }
+    if (!isset($this->get_count_optimized)) {
+      $this->get_count_optimized = TRUE;
+    }
+
+    $options = array();
+    $target = 'default';
+    $key = 'default';
+    // Detect an external database and set the
+    if (isset($this->view->base_database)) {
+      $key = $this->view->base_database;
+    }
+
+    // Set the slave target if the slave option is set
+    if (!empty($this->options['slave'])) {
+      $target = 'slave';
+    }
+
+    // Go ahead and build the query.
+    // db_select doesn't support to specify the key, so use getConnection directly.
+    $query = Database::getConnection($target, $key)
+      ->select($this->base_table, $this->base_table, $options)
+      ->addTag('views')
+      ->addTag('views_' . $this->view->name);
+
+    // Add the tags added to the view itself.
+    foreach ($this->tags as $tag) {
+      $query->addTag($tag);
+    }
+
+    if (!empty($distinct)) {
+      $query->distinct();
+    }
+
+    $joins = $where = $having = $orderby = $groupby = '';
+    $fields = $distinct = array();
+
+    // Add all the tables to the query via joins. We assume all LEFT joins.
+    foreach ($this->table_queue as $table) {
+      if (is_object($table['join'])) {
+        $table['join']->build_join($query, $table, $this);
+      }
+    }
+
+    $this->has_aggregate = FALSE;
+    $non_aggregates = array();
+
+    list($non_aggregates) = $this->compile_fields($fields_array, $query);
+
+    if (count($this->having)) {
+      $this->has_aggregate = TRUE;
+    }
+    if ($this->has_aggregate && (!empty($this->groupby) || !empty($non_aggregates))) {
+      $groupby = array_unique(array_merge($this->groupby, $non_aggregates));
+      foreach ($groupby as $field) {
+        $query->groupBy($field);
+      }
+      if (!empty($this->having) && $condition = $this->build_condition('having')) {
+        $query->havingCondition($condition);
+      }
+    }
+
+    if (!$this->get_count_optimized) {
+      // we only add the orderby if we're not counting.
+      if ($this->orderby) {
+        foreach ($this->orderby as $order) {
+          if ($order['field'] == 'rand_') {
+            $query->orderRandom();
+          }
+          else {
+            $query->orderBy($order['field'], $order['direction']);
+          }
+        }
+      }
+    }
+
+    if (!empty($this->where) && $condition = $this->build_condition('where')) {
+      $query->condition($condition);
+    }
+
+    // Add a query comment.
+    if (!empty($this->options['query_comment'])) {
+      $query->comment($this->options['query_comment']);
+    }
+
+    // Add the query tags.
+    if (!empty($this->options['query_tags'])) {
+      foreach ($this->options['query_tags'] as $tag) {
+        $query->addTag($tag);
+      }
+    }
+
+    // Add all query substitutions as metadata.
+    $query->addMetaData('views_substitutions', module_invoke_all('views_query_substitutions', $this));
+
+    return $query;
+  }
+
+  /**
+   * Get the arguments attached to the WHERE and HAVING clauses of this query.
+   */
+  function get_where_args() {
+    $args = array();
+    foreach ($this->where as $group => $where) {
+      $args = array_merge($args, $where['args']);
+    }
+    foreach ($this->having as $group => $having) {
+      $args = array_merge($args, $having['args']);
+    }
+    return $args;
+  }
+
+  /**
+   * Let modules modify the query just prior to finalizing it.
+   */
+  function alter(&$view) {
+    foreach (module_implements('views_query_alter') as $module) {
+      $function = $module . '_views_query_alter';
+      $function($view, $this);
+    }
+  }
+
+  /**
+   * Builds the necessary info to execute the query.
+   */
+  function build(&$view) {
+    // Make the query distinct if the option was set.
+    if (!empty($this->options['distinct'])) {
+      $this->set_distinct(TRUE, !empty($this->options['pure_distinct']));
+    }
+
+    // Store the view in the object to be able to use it later.
+    $this->view = $view;
+
+    $view->init_pager();
+
+    // Let the pager modify the query to add limits.
+    $this->pager->query();
+
+    $view->build_info['query'] = $this->query();
+    $view->build_info['count_query'] = $this->query(TRUE);
+  }
+
+  /**
+   * Executes the query and fills the associated view object with according
+   * values.
+   *
+   * Values to set: $view->result, $view->total_rows, $view->execute_time,
+   * $view->current_page.
+   */
+  function execute(&$view) {
+    $external = FALSE; // Whether this query will run against an external database.
+    $query = $view->build_info['query'];
+    $count_query = $view->build_info['count_query'];
+
+    $query->addMetaData('view', $view);
+    $count_query->addMetaData('view', $view);
+
+    if (empty($this->options['disable_sql_rewrite'])) {
+      $base_table_data = views_fetch_data($this->base_table);
+      if (isset($base_table_data['table']['base']['access query tag'])) {
+        $access_tag = $base_table_data['table']['base']['access query tag'];
+        $query->addTag($access_tag);
+        $count_query->addTag($access_tag);
+      }
+    }
+
+    $items = array();
+    if ($query) {
+      $additional_arguments = module_invoke_all('views_query_substitutions', $view);
+
+      // Count queries must be run through the preExecute() method.
+      // If not, then hook_query_node_access_alter() may munge the count by
+      // adding a distinct against an empty query string
+      // (e.g. COUNT DISTINCT(1) ...) and no pager will return.
+      // See pager.inc > PagerDefault::execute()
+      // http://api.drupal.org/api/drupal/includes--pager.inc/function/PagerDefault::execute/7
+      // See http://drupal.org/node/1046170.
+      $count_query->preExecute();
+
+      // Build the count query.
+      $count_query = $count_query->countQuery();
+
+      // Add additional arguments as a fake condition.
+      // XXX: this doesn't work... because PDO mandates that all bound arguments
+      // are used on the query. TODO: Find a better way to do this.
+      if (!empty($additional_arguments)) {
+        // $query->where('1 = 1', $additional_arguments);
+        // $count_query->where('1 = 1', $additional_arguments);
+      }
+
+      $start = microtime(TRUE);
+
+
+      try {
+        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
+          $this->pager->execute_count_query($count_query);
+        }
+
+        // Let the pager modify the query to add limits.
+        $this->pager->pre_execute($query);
+
+        if (!empty($this->limit) || !empty($this->offset)) {
+          // We can't have an offset without a limit, so provide a very large limit instead.
+          $limit  = intval(!empty($this->limit) ? $this->limit : 999999);
+          $offset = intval(!empty($this->offset) ? $this->offset : 0);
+          $query->range($offset, $limit);
+        }
+
+        $result = $query->execute();
+
+        $view->result = array();
+        foreach ($result as $item) {
+          $view->result[] = $item;
+        }
+
+        $this->pager->post_execute($view->result);
+
+        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
+          $view->total_rows = $this->pager->get_total_items();
+        }
+      }
+      catch (Exception $e) {
+        $view->result = array();
+        if (!empty($view->live_preview)) {
+          drupal_set_message($e->getMessage(), 'error');
+        }
+        else {
+          vpr('Exception in @human_name[@view_name]: @message', array('@human_name' => $view->human_name, '@view_name' => $view->name, '@message' => $e->getMessage()));
+        }
+      }
+
+    }
+    else {
+      $start = microtime(TRUE);
+    }
+    $view->execute_time = microtime(TRUE) - $start;
+  }
+
+  function add_signature(&$view) {
+    $view->query->add_field(NULL, "'" . $view->name . ':' . $view->current_display . "'", 'view_name');
+  }
+
+  function get_aggregation_info() {
+    // @todo -- need a way to get database specific and customized aggregation
+    // functions into here.
+    return array(
+      'group' => array(
+        'title' => t('Group results together'),
+        'is aggregate' => FALSE,
+      ),
+      'count' => array(
+        'title' => t('Count'),
+        'method' => 'views_query_default_aggregation_method_simple',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'field' => 'views_handler_field_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+      'count_distinct' => array(
+        'title' => t('Count DISTINCT'),
+        'method' => 'views_query_default_aggregation_method_distinct',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'field' => 'views_handler_field_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+      'sum' => array(
+        'title' => t('Sum'),
+        'method' => 'views_query_default_aggregation_method_simple',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+      'avg' => array(
+        'title' => t('Average'),
+        'method' => 'views_query_default_aggregation_method_simple',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+      'min' => array(
+        'title' => t('Minimum'),
+        'method' => 'views_query_default_aggregation_method_simple',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+      'max' => array(
+        'title' => t('Maximum'),
+        'method' => 'views_query_default_aggregation_method_simple',
+        'handler' => array(
+          'argument' => 'views_handler_argument_group_by_numeric',
+          'filter' => 'views_handler_filter_group_by_numeric',
+          'sort' => 'views_handler_sort_group_by_numeric',
+        ),
+      ),
+    );
+  }
+
+  /**
+   * Returns the according entity objects for the given query results.
+   *
+   */
+  function get_result_entities($results, $relationship = NULL) {
+    $base_table = $this->base_table;
+    $base_table_alias = $base_table;
+
+    if (!empty($relationship)) {
+      foreach ($this->view->relationship as $current) {
+        if ($current->alias == $relationship) {
+          $base_table = $current->definition['base'];
+          $base_table_alias = $relationship;
+          break;
+        }
+      }
+    }
+    $table_data = views_fetch_data($base_table);
+
+    // Bail out if the table has not specified the according entity-type.
+    if (!isset($table_data['table']['entity type'])) {
+      return FALSE;
+    }
+    $entity_type = $table_data['table']['entity type'];
+    $info = entity_get_info($entity_type);
+    $id_alias = $this->get_field_alias($base_table_alias, $info['entity keys']['id']);
+
+    // Assemble the ids of the entities to load.
+    $ids = array();
+    foreach ($results as $key => $result) {
+      if (isset($result->$id_alias)) {
+        $ids[$key] = $result->$id_alias;
+      }
+    }
+
+    $entities = entity_load_multiple($entity_type, $ids);
+    // Re-key the array by row-index.
+    $result = array();
+    foreach ($ids as $key => $id) {
+      $result[$key] = isset($entities[$id]) ? $entities[$id] : FALSE;
+    }
+    return array($entity_type, $result);
+  }
+}
+
+function views_query_default_aggregation_method_simple($group_type, $field) {
+  return strtoupper($group_type) . '(' . $field . ')';
+}
+
+function views_query_default_aggregation_method_distinct($group_type, $field) {
+  $group_type = str_replace('_distinct', '', $group_type);
+  return strtoupper($group_type) . '(DISTINCT ' . $field . ')';
+}
+
+/**
+ * Validation callback for query tags.
+ */
+function views_element_validate_tags($element, &$form_state) {
+  $values = array_map('trim', explode(',', $element['#value']));
+  foreach ($values as $value) {
+    if (preg_match("/[^a-z_]/", $value)) {
+      form_error($element, t('The query tags may only contain lower-case alphabetical characters and underscores.'));
+      return;
+    }
+  }
+}
+
diff --git a/lib/Drupal/views/Plugins/views/relationship/GroupwiseMaxRelationship.php b/lib/Drupal/views/Plugins/views/relationship/GroupwiseMaxRelationship.php
new file mode 100644
index 0000000..c5d6419
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/relationship/GroupwiseMaxRelationship.php
@@ -0,0 +1,386 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\relationship\GroupwiseMaxRelationship.
+ */
+
+namespace Drupal\views\Plugins\views\relationship;
+
+use Drupal\Core\Database\Query\AlterableInterface;
+use Drupal\views\View;
+use Drupal\views\JoinSubquery;
+
+/**
+ * Relationship handler that allows a groupwise maximum of the linked in table.
+ * For a definition, see:
+ * http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
+ * In lay terms, instead of joining to get all matching records in the linked
+ * table, we get only one record, a 'representative record' picked according
+ * to a given criteria.
+ *
+ * Example:
+ * Suppose we have a term view that gives us the terms: Horse, Cat, Aardvark.
+ * We wish to show for each term the most recent node of that term.
+ * What we want is some kind of relationship from term to node.
+ * But a regular relationship will give us all the nodes for each term,
+ * giving the view multiple rows per term. What we want is just one
+ * representative node per term, the node that is the 'best' in some way:
+ * eg, the most recent, the most commented on, the first in alphabetical order.
+ *
+ * This handler gives us that kind of relationship from term to node.
+ * The method of choosing the 'best' implemented with a sort
+ * that the user selects in the relationship settings.
+ *
+ * So if we want our term view to show the most commented node for each term,
+ * add the relationship and in its options, pick the 'Comment count' sort.
+ *
+ * Relationship definition
+ *  - 'outer field': The outer field to substitute into the correlated subquery.
+ *       This must be the full field name, not the alias.
+ *       Eg: 'term_data.tid'.
+ *  - 'argument table',
+ *    'argument field': These options define a views argument that the subquery
+ *     must add to itself to filter by the main view.
+ *     Example: the main view shows terms, this handler is being used to get to
+ *     the nodes base table. Your argument must be 'term_node', 'tid', as this
+ *     is the argument that should be added to a node view to filter on terms.
+ *
+ * A note on performance:
+ * This relationship uses a correlated subquery, which is expensive.
+ * Subsequent versions of this handler could also implement the alternative way
+ * of doing this, with a join -- though this looks like it could be pretty messy
+ * to implement. This is also an expensive method, so providing both methods and
+ * allowing the user to choose which one works fastest for their data might be
+ * the best way.
+ * If your use of this relationship handler is likely to result in large
+ * data sets, you might want to consider storing statistics in a separate table,
+ * in the same way as node_comment_statistics.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class GroupwiseMaxRelationship extends relationshipPlugin {
+
+  /**
+   * Defines default values for options.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['subquery_sort'] = array('default' => NULL);
+    // Descending more useful.
+    $options['subquery_order'] = array('default' => 'DESC');
+    $options['subquery_regenerate'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['subquery_view'] = array('default' => FALSE);
+    $options['subquery_namespace'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  /**
+   * Extends the relationship's basic options, allowing the user to pick
+   * a sort and an order for it.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // Get the sorts that apply to our base.
+    $sorts = views_fetch_fields($this->definition['base'], 'sort');
+    foreach ($sorts as $sort_id => $sort) {
+      $sort_options[$sort_id] = "$sort[group]: $sort[title]";
+    }
+    $base_table_data = views_fetch_data($this->definition['base']);
+
+    $form['subquery_sort'] = array(
+      '#type' => 'select',
+      '#title' => t('Representative sort criteria'),
+      // Provide the base field as sane default sort option.
+      '#default_value' => !empty($this->options['subquery_sort']) ? $this->options['subquery_sort'] : $this->definition['base'] . '.' . $base_table_data['table']['base']['field'],
+      '#options' => $sort_options,
+      '#description' => theme('advanced_help_topic', array('module' => 'views', 'topic' => 'relationship-representative')) .
+        t("The sort criteria is applied to the data brought in by the relationship to determine how a representative item is obtained for each row. For example, to show the most recent node for each user, pick 'Content: Updated date'."),
+    );
+
+    $form['subquery_order'] = array(
+      '#type' => 'radios',
+      '#title' => t('Representative sort order'),
+      '#description' => t("The ordering to use for the sort criteria selected above."),
+      '#options' => array('ASC' => t('Ascending'), 'DESC' => t('Descending')),
+      '#default_value' => $this->options['subquery_order'],
+    );
+
+    $form['subquery_namespace'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Subquery namespace'),
+      '#description' => t('Advanced. Enter a namespace for the subquery used by this relationship.'),
+      '#default_value' => $this->options['subquery_namespace'],
+    );
+
+
+    // WIP: This stuff doens't work yet: namespacing issues.
+    // A list of suitable views to pick one as the subview.
+    $views = array('' => '<none>');
+    $all_views = views_get_all_views();
+    foreach ($all_views as $view) {
+      // Only get views that are suitable:
+      // - base must the base that our relationship joins towards
+      // - must have fields.
+      if ($view->base_table == $this->definition['base'] && !empty($view->display['default']->display_options['fields'])) {
+        // TODO: check the field is the correct sort?
+        // or let users hang themselves at this stage and check later?
+        if ($view->type == 'Default') {
+          $views[t('Default Views')][$view->name] = $view->name;
+        }
+        else {
+          $views[t('Existing Views')][$view->name] = $view->name;
+        }
+      }
+    }
+
+    $form['subquery_view'] = array(
+      '#type' => 'select',
+      '#title' => t('Representative view'),
+      '#default_value' => $this->options['subquery_view'],
+      '#options' => $views,
+      '#description' => t('Advanced. Use another view to generate the relationship subquery. This allows you to use filtering and more than one sort. If you pick a view here, the sort options above are ignored. Your view must have the ID of its base as its only field, and should have some kind of sorting.'),
+    );
+
+    $form['subquery_regenerate'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Generate subquery each time view is run.'),
+      '#default_value' => $this->options['subquery_regenerate'],
+      '#description' => t('Will re-generate the subquery for this relationship every time the view is run, instead of only when these options are saved. Use for testing if you are making changes elsewhere. WARNING: seriously impairs performance.'),
+    );
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   *
+   * Generate the subquery string when the user submits the options, and store
+   * it. This saves the expense of generating it when the view is run.
+   */
+  function options_submit(&$form, &$form_state) {
+    // Get the new user options from the form values.
+    $new_options = $form_state['values']['options'];
+    $subquery = $this->left_query($new_options);
+    // Add the subquery string to the options we're about to store.
+    $this->options['subquery_string'] = $subquery;
+  }
+
+  /**
+   * Helper function to create a pseudo view.
+   *
+   * We use this to obtain our subquery SQL.
+   */
+  function get_temporary_view() {
+    $view = new View();
+    $view->vid = 'new'; // @todo: what's this?
+    $view->base_table = $this->definition['base'];
+    $view->add_display('default');
+    return $view;
+  }
+
+  /**
+   * Generate a subquery given the user options, as set in the options.
+   * These are passed in rather than picked up from the object because we
+   * generate the subquery when the options are saved, rather than when the view
+   * is run. This saves considerable time.
+   *
+   * @param $options
+   *   An array of options:
+   *    - subquery_sort: the id of a views sort.
+   *    - subquery_order: either ASC or DESC.
+   * @return
+   *    The subquery SQL string, ready for use in the main query.
+   */
+  function left_query($options) {
+    // Either load another view, or create one on the fly.
+    if ($options['subquery_view']) {
+      $temp_view = views_get_view($options['subquery_view']);
+      // Remove all fields from default display
+      unset($temp_view->display['default']->display_options['fields']);
+    }
+    else {
+      // Create a new view object on the fly, which we use to generate a query
+      // object and then get the SQL we need for the subquery.
+      $temp_view = $this->get_temporary_view();
+
+      // Add the sort from the options to the default display.
+      // This is broken, in that the sort order field also gets added as a
+      // select field. See http://drupal.org/node/844910.
+      // We work around this further down.
+      $sort = $options['subquery_sort'];
+      list($sort_table, $sort_field) = explode('.', $sort);
+      $sort_options = array('order' => $options['subquery_order']);
+      $temp_view->add_item('default', 'sort', $sort_table, $sort_field, $sort_options);
+    }
+
+    // Get the namespace string.
+    $temp_view->namespace = (!empty($options['subquery_namespace'])) ? '_'. $options['subquery_namespace'] : '_INNER';
+    $this->subquery_namespace = (!empty($options['subquery_namespace'])) ? '_'. $options['subquery_namespace'] : 'INNER';
+
+    // The value we add here does nothing, but doing this adds the right tables
+    // and puts in a WHERE clause with a placeholder we can grab later.
+    $temp_view->args[] = '**CORRELATED**';
+
+    // Add the base table ID field.
+    $views_data = views_fetch_data($this->definition['base']);
+    $base_field = $views_data['table']['base']['field'];
+    $temp_view->add_item('default', 'field', $this->definition['base'], $this->definition['field']);
+
+    // Add the correct argument for our relationship's base
+    // ie the 'how to get back to base' argument.
+    // The relationship definition tells us which one to use.
+    $temp_view->add_item(
+      'default',
+      'argument',
+      $this->definition['argument table'], // eg 'term_node',
+      $this->definition['argument field'] //  eg 'tid'
+    );
+
+    // Build the view. The creates the query object and produces the query
+    // string but does not run any queries.
+    $temp_view->build();
+
+    // Now take the SelectQuery object the View has built and massage it
+    // somewhat so we can get the SQL query from it.
+    $subquery = $temp_view->build_info['query'];
+
+    // Workaround until http://drupal.org/node/844910 is fixed:
+    // Remove all fields from the SELECT except the base id.
+    $fields =& $subquery->getFields();
+    foreach (array_keys($fields) as $field_name) {
+      // The base id for this subquery is stored in our definition.
+      if ($field_name != $this->definition['field']) {
+        unset($fields[$field_name]);
+      }
+    }
+
+    // Make every alias in the subquery safe within the outer query by
+    // appending a namespace to it, '_inner' by default.
+    $tables =& $subquery->getTables();
+    foreach (array_keys($tables) as $table_name) {
+      $tables[$table_name]['alias'] .= $this->subquery_namespace;
+      // Namespace the join on every table.
+      if (isset($tables[$table_name]['condition'])) {
+        $tables[$table_name]['condition'] = $this->condition_namespace($tables[$table_name]['condition']);
+      }
+    }
+    // Namespace fields.
+    foreach (array_keys($fields) as $field_name) {
+      $fields[$field_name]['table'] .= $this->subquery_namespace;
+      $fields[$field_name]['alias'] .= $this->subquery_namespace;
+    }
+    // Namespace conditions.
+    $where =& $subquery->conditions();
+    $this->alter_subquery_condition($subquery, $where);
+    // Not sure why, but our sort order clause doesn't have a table.
+    // TODO: the call to add_item() above to add the sort handler is probably
+    // wrong -- needs attention from someone who understands it.
+    // In the meantime, this works, but with a leap of faith...
+    $orders =& $subquery->getOrderBy();
+    foreach ($orders as $order_key => $order) {
+      // But if we're using a whole view, we don't know what we have!
+      if ($options['subquery_view']) {
+        list($sort_table, $sort_field) = explode('.', $order_key);
+      }
+      $orders[$sort_table . $this->subquery_namespace . '.' . $sort_field] = $order;
+      unset($orders[$order_key]);
+    }
+
+    // The query we get doesn't include the LIMIT, so add it here.
+    $subquery->range(0, 1);
+
+    // Extract the SQL the temporary view built.
+    $subquery_sql = $subquery->__toString();
+
+    // Replace the placeholder with the outer, correlated field.
+    // Eg, change the placeholder ':users_uid' into the outer field 'users.uid'.
+    // We have to work directly with the SQL, because putting a name of a field
+    // into a SelectQuery that it does not recognize (because it's outer) just
+    // makes it treat it as a string.
+    $outer_placeholder = ':' . str_replace('.', '_', $this->definition['outer field']);
+    $subquery_sql = str_replace($outer_placeholder, $this->definition['outer field'], $subquery_sql);
+
+    return $subquery_sql;
+  }
+
+  /**
+   * Recursive helper to add a namespace to conditions.
+   *
+   * Similar to _views_query_tag_alter_condition().
+   *
+   * (Though why is the condition we get in a simple query 3 levels deep???)
+   */
+  function alter_subquery_condition(AlterableInterface $query, &$conditions) {
+    foreach ($conditions as $condition_id => &$condition) {
+      // Skip the #conjunction element.
+      if (is_numeric($condition_id)) {
+        if (is_string($condition['field'])) {
+          $condition['field'] = $this->condition_namespace($condition['field']);
+        }
+        elseif (is_object($condition['field'])) {
+          $sub_conditions =& $condition['field']->conditions();
+          $this->alter_subquery_condition($query, $sub_conditions);
+        }
+      }
+    }
+  }
+
+  /**
+   * Helper function to namespace query pieces.
+   *
+   * Turns 'foo.bar' into 'foo_NAMESPACE.bar'.
+   */
+  function condition_namespace($string) {
+    return str_replace('.', $this->subquery_namespace . '.', $string);
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   * This is mostly a copy of our parent's query() except for this bit with
+   * the join class.
+   */
+  function query() {
+    // Figure out what base table this relationship brings to the party.
+    $table_data = views_fetch_data($this->definition['base']);
+    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
+
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = $this->definition['base'];
+    $def['field'] = $base_field;
+    $def['left_table'] = $this->table_alias;
+    $def['left_field'] = $this->field;
+    if (!empty($this->options['required'])) {
+      $def['type'] = 'INNER';
+    }
+
+    if ($this->options['subquery_regenerate']) {
+      // For testing only, regenerate the subquery each time.
+      $def['left_query'] = $this->left_query($this->options);
+    }
+    else {
+      // Get the stored subquery SQL string.
+      $def['left_query'] = $this->options['subquery_string'];
+    }
+
+    if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
+      $join = new $def['join_handler'];
+    }
+    else {
+      $join = new JoinSubquery();
+    }
+
+    $join->definition = $def;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/relationship/RelationshipPlugin.php b/lib/Drupal/views/Plugins/views/relationship/RelationshipPlugin.php
new file mode 100644
index 0000000..0338bc0
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/relationship/RelationshipPlugin.php
@@ -0,0 +1,191 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\relationship\RelationshipPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\relationship;
+
+use Drupal\views\Plugins\views\Plugin;
+use Drupal\views\Join;
+
+/**
+ * @defgroup views_relationship_handlers Views relationship handlers
+ * @{
+ * Handlers to tell Views how to create alternate relationships.
+ */
+
+/**
+ * Simple relationship handler that allows a new version of the primary table
+ * to be linked in.
+ *
+ * The base relationship handler can only handle a single join. Some relationships
+ * are more complex and might require chains of joins; for those, you must
+ * utilize a custom relationship handler.
+ *
+ * Definition items:
+ * - base: The new base table this relationship will be adding. This does not
+ *   have to be a declared base table, but if there are no tables that
+ *   utilize this base table, it won't be very effective.
+ * - base field: The field to use in the relationship; if left out this will be
+ *   assumed to be the primary field.
+ * - relationship table: The actual table this relationship operates against.
+ *   This is analogous to using a 'table' override.
+ * - relationship field: The actual field this relationship operates against.
+ *   This is analogous to using a 'real field' override.
+ * - label: The default label to provide for this relationship, which is
+ *   shown in parentheses next to any field/sort/filter/argument that uses
+ *   the relationship.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class RelationshipPlugin extends Plugin {
+  /**
+   * Init handler to let relationships live on tables other than
+   * the table they operate on.
+   */
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+    if (isset($this->definition['relationship table'])) {
+      $this->table = $this->definition['relationship table'];
+    }
+    if (isset($this->definition['relationship field'])) {
+      // Set both real_field and field so custom handler
+      // can rely on the old field value.
+      $this->real_field = $this->field = $this->definition['relationship field'];
+    }
+  }
+
+  /**
+   * Get this field's label.
+   */
+  function label() {
+    if (!isset($this->options['label'])) {
+      return $this->ui_name();
+    }
+    return $this->options['label'];
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+
+    // Relationships definitions should define a default label, but if they aren't get another default value.
+    if (!empty($this->definition['label'])) {
+      $label = $this->definition['label'];
+    }
+    else {
+      $label = !empty($this->definition['field']) ? $this->definition['field'] : $this->definition['base field'];
+    }
+
+    $options['label'] = array('default' => $label, 'translatable' => TRUE);
+    $options['required'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Default options form that provides the label widget that all fields
+   * should have.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Identifier'),
+      '#default_value' => isset($this->options['label']) ? $this->options['label'] : '',
+      '#description' => t('Edit the administrative label displayed when referencing this relationship from filters, etc.'),
+      '#required' => TRUE,
+    );
+
+    $form['required'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Require this relationship'),
+      '#description' => t('Enable to hide items that do not contain this relationship'),
+      '#default_value' => !empty($this->options['required']),
+    );
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    // Figure out what base table this relationship brings to the party.
+    $table_data = views_fetch_data($this->definition['base']);
+    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
+
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = $this->definition['base'];
+    $def['field'] = $base_field;
+    $def['left_table'] = $this->table_alias;
+    $def['left_field'] = $this->real_field;
+    if (!empty($this->options['required'])) {
+      $def['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['extra'])) {
+      $def['extra'] = $this->definition['extra'];
+    }
+
+    if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
+      $join = new $def['join_handler'];
+    }
+    else {
+      $join = new Join();
+    }
+
+    $join->definition = $def;
+    $join->options = $this->options;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
+
+    // Add access tags if the base table provide it.
+    if (empty($this->query->options['disable_sql_rewrite']) && isset($table_data['table']['base']['access query tag'])) {
+      $access_tag = $table_data['table']['base']['access query tag'];
+      $this->query->add_tag($access_tag);
+    }
+  }
+
+  /**
+   * You can't groupby a relationship.
+   */
+  function use_group_by() {
+    return FALSE;
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_relationship_handlers
+ */
+class views_handler_relationship_broken extends views_handler_relationship {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query() { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/row/FieldsRow.php b/lib/Drupal/views/Plugins/views/row/FieldsRow.php
new file mode 100644
index 0000000..85faad7
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/row/FieldsRow.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\row\FieldsRow.
+ */
+
+namespace Drupal\views\Plugins\views\row;
+
+/**
+ * The basic 'fields' row plugin
+ *
+ * This displays fields one after another, giving options for inline
+ * or not.
+ *
+ * @ingroup views_row_plugins
+ */
+class FieldsRow extends RowPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['inline'] = array('default' => array());
+    $options['separator'] = array('default' => '');
+    $options['hide_empty'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['default_field_elements'] = array('default' => TRUE, 'bool' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide a form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $options = $this->display->handler->get_field_labels();
+
+    if (empty($this->options['inline'])) {
+      $this->options['inline'] = array();
+    }
+
+    $form['default_field_elements'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Provide default field wrapper elements'),
+      '#default_value' => $this->options['default_field_elements'],
+      '#description' => t('If not checked, fields that are not configured to customize their HTML elements will get no wrappers at all for their field, label and field + label wrappers. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'),
+    );
+
+    $form['inline'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Inline fields'),
+      '#options' => $options,
+      '#default_value' => $this->options['inline'],
+      '#description' => t('Inline fields will be displayed next to each other rather than one after another. Note that some fields will ignore this if they are block elements, particularly body fields and other formatted HTML.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $form['separator'] = array(
+      '#title' => t('Separator'),
+      '#type' => 'textfield',
+      '#size' => 10,
+      '#default_value' => isset($this->options['separator']) ? $this->options['separator'] : '',
+      '#description' => t('The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field.'),
+      '#states' => array(
+        'visible' => array(
+          ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $form['hide_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide empty fields'),
+      '#default_value' => $this->options['hide_empty'],
+      '#description' => t('Do not display fields, labels or markup for fields that are empty.'),
+    );
+
+  }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) {
+    $form_state['values']['row_options']['inline'] = array_filter($form_state['values']['row_options']['inline']);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/row/RowPlugin.php b/lib/Drupal/views/Plugins/views/row/RowPlugin.php
new file mode 100644
index 0000000..9ff2bc3
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/row/RowPlugin.php
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\row\RowPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\row;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_row_plugins Views row plugins
+ * @{
+ * Row plugins control how Views outputs an individual record.
+ *
+ * They are tightly coupled to style plugins, in that a style plugin is what
+ * calls the row plugin.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * Default plugin to view a single row of a table. This is really just a wrapper around
+ * a theme function.
+ */
+class RowPlugin extends Plugin {
+  /**
+   * Initialize the row plugin.
+   */
+  function init(&$view, &$display, $options = NULL) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    // Overlay incoming options on top of defaults
+    $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('row_options'));
+  }
+
+  function uses_fields() {
+    return !empty($this->definition['uses fields']);
+  }
+
+
+  function option_definition() {
+    $options = parent::option_definition();
+    if (isset($this->base_table)) {
+      $options['relationship'] = array('default' => 'none');
+    }
+
+    return $options;
+  }
+
+  /**
+   * Provide a form for setting options.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    if (isset($this->base_table)) {
+      $view = &$form_state['view'];
+
+      // A whole bunch of code to figure out what relationships are valid for
+      // this item.
+      $relationships = $view->display_handler->get_option('relationships');
+      $relationship_options = array();
+
+      foreach ($relationships as $relationship) {
+        $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
+
+        // If this relationship is valid for this type, add it to the list.
+        $data = views_fetch_data($relationship['table']);
+        $base = $data[$relationship['field']]['relationship']['base'];
+        if ($base == $this->base_table) {
+          $relationship_handler->init($view, $relationship);
+          $relationship_options[$relationship['id']] = $relationship_handler->label();
+        }
+      }
+
+      if (!empty($relationship_options)) {
+        $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
+        $rel = empty($this->options['relationship']) ? 'none' : $this->options['relationship'];
+        if (empty($relationship_options[$rel])) {
+          // Pick the first relationship.
+          $rel = key($relationship_options);
+        }
+
+        $form['relationship'] = array(
+          '#type' => 'select',
+          '#title' => t('Relationship'),
+          '#options' => $relationship_options,
+          '#default_value' => $rel,
+        );
+      }
+      else {
+        $form['relationship'] = array(
+          '#type' => 'value',
+          '#value' => 'none',
+        );
+      }
+    }
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  function query() {
+    if (isset($this->base_table)) {
+      if (isset($this->options['relationship']) && isset($this->view->relationship[$this->options['relationship']])) {
+        $relationship = $this->view->relationship[$this->options['relationship']];
+        $this->field_alias = $this->view->query->add_field($relationship->alias, $this->base_field);
+      }
+      else {
+        $this->field_alias = $this->view->query->add_field($this->base_table, $this->base_field);
+      }
+    }
+  }
+
+  /**
+   * Allow the style to do stuff before each row is rendered.
+   *
+   * @param $result
+   *   The full array of results from the query.
+   */
+  function pre_render($result) { }
+
+  /**
+   * Render a row object. This usually passes through to a theme template
+   * of some form, but not always.
+   *
+   * @param stdClass $row
+   *   A single row of the query result, so an element of $view->result.
+   *
+   * @return string
+   *   The rendered output of a single row, used by the style plugin.
+   */
+  function render($row) {
+    return theme($this->theme_functions(),
+      array(
+        'view' => $this->view,
+        'options' => $this->options,
+        'row' => $row,
+        'field_alias' => isset($this->field_alias) ? $this->field_alias : '',
+      ));
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/row/RssFieldsRow.php b/lib/Drupal/views/Plugins/views/row/RssFieldsRow.php
new file mode 100644
index 0000000..fedc458
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/row/RssFieldsRow.php
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\row\RssFieldsRow.
+ */
+
+namespace Drupal\views\Plugins\views\row;
+
+/**
+ * Renders an RSS item based on fields.
+ */
+class RssFieldsRow extends RowPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['title_field'] = array('default' => '');
+    $options['link_field'] = array('default' => '');
+    $options['description_field'] = array('default' => '');
+    $options['creator_field'] = array('default' => '');
+    $options['date_field'] = array('default' => '');
+    $options['guid_field_options']['guid_field'] = array('default' => '');
+    $options['guid_field_options']['guid_field_is_permalink'] = array('default' => TRUE, 'bool' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $initial_labels = array('' => t('- None -'));
+    $view_fields_labels = $this->display->handler->get_field_labels();
+    $view_fields_labels = array_merge($initial_labels, $view_fields_labels);
+
+    $form['title_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Title field'),
+      '#description' => t('The field that is going to be used as the RSS item title for each row.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['title_field'],
+      '#required' => TRUE,
+    );
+    $form['link_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Link field'),
+      '#description' => t('The field that is going to be used as the RSS item link for each row. This must be a drupal relative path.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['link_field'],
+      '#required' => TRUE,
+    );
+    $form['description_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Description field'),
+      '#description' => t('The field that is going to be used as the RSS item description for each row.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['description_field'],
+      '#required' => TRUE,
+    );
+    $form['creator_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Creator field'),
+      '#description' => t('The field that is going to be used as the RSS item creator for each row.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['creator_field'],
+      '#required' => TRUE,
+    );
+    $form['date_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Publication date field'),
+      '#description' => t('The field that is going to be used as the RSS item pubDate for each row. It needs to be in RFC 2822 format.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['date_field'],
+      '#required' => TRUE,
+    );
+    $form['guid_field_options'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('GUID settings'),
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+    );
+    $form['guid_field_options']['guid_field'] = array(
+      '#type' => 'select',
+      '#title' => t('GUID field'),
+      '#description' => t('The globally unique identifier of the RSS item.'),
+      '#options' => $view_fields_labels,
+      '#default_value' => $this->options['guid_field_options']['guid_field'],
+      '#required' => TRUE,
+    );
+    $form['guid_field_options']['guid_field_is_permalink'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('GUID is permalink'),
+      '#description' => t('The RSS item GUID is a permalink.'),
+      '#default_value' => $this->options['guid_field_options']['guid_field_is_permalink'],
+    );
+  }
+
+  function validate() {
+    $errors = parent::validate();
+    $required_options = array('title_field', 'link_field', 'description_field', 'creator_field', 'date_field');
+    foreach ($required_options as $required_option) {
+      if (empty($this->options[$required_option])) {
+        $errors[] = t('Row style plugin requires specifying which views fields to use for RSS item.');
+        break;
+      }
+    }
+    // Once more for guid.
+    if (empty($this->options['guid_field_options']['guid_field'])) {
+      $errors[] = t('Row style plugin requires specifying which views fields to use for RSS item.');
+    }
+    return $errors;
+  }
+
+  function render($row) {
+    static $row_index;
+    if (!isset($row_index)) {
+      $row_index = 0;
+    }
+    if (function_exists('rdf_get_namespaces')) {
+      // Merge RDF namespaces in the XML namespaces in case they are used
+      // further in the RSS content.
+      $xml_rdf_namespaces = array();
+      foreach (rdf_get_namespaces() as $prefix => $uri) {
+        $xml_rdf_namespaces['xmlns:' . $prefix] = $uri;
+      }
+      $this->view->style_plugin->namespaces += $xml_rdf_namespaces;
+    }
+
+    // Create the RSS item object.
+    $item = new stdClass();
+    $item->title = $this->get_field($row_index, $this->options['title_field']);
+    $item->link = url($this->get_field($row_index, $this->options['link_field']), array('absolute' => TRUE));
+    $item->description = $this->get_field($row_index, $this->options['description_field']);
+    $item->elements = array(
+      array('key' => 'pubDate', 'value' => $this->get_field($row_index, $this->options['date_field'])),
+      array(
+        'key' => 'dc:creator',
+        'value' => $this->get_field($row_index, $this->options['creator_field']),
+        'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'),
+      ),
+    );
+    $guid_is_permalink_string = 'false';
+    $item_guid = $this->get_field($row_index, $this->options['guid_field_options']['guid_field']);
+    if ($this->options['guid_field_options']['guid_field_is_permalink']) {
+      $guid_is_permalink_string = 'true';
+      $item_guid = url($item_guid, array('absolute' => TRUE));
+    }
+    $item->elements[] = array(
+      'key' => 'guid',
+      'value' => $item_guid,
+      'attributes' => array('isPermaLink' => $guid_is_permalink_string),
+    );
+
+    $row_index++;
+
+    foreach ($item->elements as $element) {
+      if (isset($element['namespace'])) {
+        $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']);
+      }
+    }
+
+    return theme($this->theme_functions(),
+      array(
+        'view' => $this->view,
+        'options' => $this->options,
+        'row' => $item,
+        'field_alias' => isset($this->field_alias) ? $this->field_alias : '',
+      ));
+  }
+
+  /**
+   * Retrieves a views field value from the style plugin.
+   *
+   * @param $index
+   *   The index count of the row as expected by views_plugin_style::get_field().
+   * @param $field_id
+   *   The ID assigned to the required field in the display.
+   */
+  function get_field($index, $field_id) {
+    if (empty($this->view->style_plugin) || !is_object($this->view->style_plugin) || empty($field_id)) {
+      return '';
+    }
+    return $this->view->style_plugin->get_field($index, $field_id);
+  }
+
+}
diff --git a/lib/Drupal/views/Plugins/views/sort/DateSort.php b/lib/Drupal/views/Plugins/views/sort/DateSort.php
new file mode 100644
index 0000000..6bfb6cc
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/sort/DateSort.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\sort\DateSort.
+ */
+
+namespace Drupal\views\Plugins\views\sort;
+
+/**
+ * Basic sort handler for dates.
+ *
+ * This handler enables granularity, which is the ability to make dates
+ * equivalent based upon nearness.
+ *
+ * @ingroup views_sort_handlers
+ */
+class DateSort extends SortPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['granularity'] = array('default' => 'second');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['granularity'] = array(
+      '#type' => 'radios',
+      '#title' => t('Granularity'),
+      '#options' => array(
+        'second' => t('Second'),
+        'minute' => t('Minute'),
+        'hour'   => t('Hour'),
+        'day'    => t('Day'),
+        'month'  => t('Month'),
+        'year'   => t('Year'),
+      ),
+      '#description' => t('The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is "Year" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date.'),
+      '#default_value' => $this->options['granularity'],
+    );
+  }
+
+  /**
+   * Called to add the sort to a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+    switch ($this->options['granularity']) {
+      case 'second':
+      default:
+        $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
+        return;
+      case 'minute':
+        $formula = views_date_sql_format('YmdHi', "$this->table_alias.$this->real_field");
+        break;
+      case 'hour':
+        $formula = views_date_sql_format('YmdH', "$this->table_alias.$this->real_field");
+        break;
+      case 'day':
+        $formula = views_date_sql_format('Ymd', "$this->table_alias.$this->real_field");
+        break;
+      case 'month':
+        $formula = views_date_sql_format('Ym', "$this->table_alias.$this->real_field");
+        break;
+      case 'year':
+        $formula = views_date_sql_format('Y', "$this->table_alias.$this->real_field");
+        break;
+    }
+
+    // Add the field.
+    $this->query->add_orderby(NULL, $formula, $this->options['order'], $this->table_alias . '_' . $this->field . '_' . $this->options['granularity']);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/sort/GroupByNumericSort.php b/lib/Drupal/views/Plugins/views/sort/GroupByNumericSort.php
new file mode 100644
index 0000000..9199894
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/sort/GroupByNumericSort.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\sort\GroupByNumericSort.
+ */
+
+namespace Drupal\views\Plugins\views\sort;
+
+/**
+ * Handler for GROUP BY on simple numeric fields.
+ *
+ * @ingroup views_sort_handlers
+ */
+class GroupByNumericSort extends SortPlugin {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Initialize the original handler.
+    $this->handler = views_get_handler($options['table'], $options['field'], 'sort');
+    $this->handler->init($view, $options);
+  }
+
+  /**
+   * Called to add the field to a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+
+    $params = array(
+      'function' => $this->options['group_type'],
+    );
+
+    $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order'], NULL, $params);
+  }
+
+  function ui_name($short = FALSE) {
+    return $this->get_field(parent::ui_name($short));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/sort/MenuHierarchySort.php b/lib/Drupal/views/Plugins/views/sort/MenuHierarchySort.php
new file mode 100644
index 0000000..fd22a98
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/sort/MenuHierarchySort.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\sort\MenuHierarchySort.
+ */
+
+namespace Drupal\views\Plugins\views\sort;
+
+use Drupal\views\Join;
+
+/**
+ * Sort in menu hierarchy order.
+ *
+ * Given a field name of 'p' this produces an ORDER BY on p1, p2, ..., p9;
+ * and optionally injects multiple joins to {menu_links} to sort by weight
+ * and title as well.
+ *
+ * This is only really useful for the {menu_links} table.
+ *
+ * @ingroup views_sort_handlers
+ */
+class MenuHierarchySort extends SortPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['sort_within_level'] = array('default' => FALSE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['sort_within_level'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Sort within each hierarchy level'),
+      '#description' => t('Enable this to sort the items within each level of the hierarchy by weight and title.  Warning: this may produce a slow query.'),
+      '#default_value' => $this->options['sort_within_level'],
+    );
+  }
+
+  function query() {
+    $this->ensure_my_table();
+    $max_depth = isset($this->definition['max depth']) ? $this->definition['max depth'] : MENU_MAX_DEPTH;
+    for ($i = 1; $i <= $max_depth; ++$i) {
+      if ($this->options['sort_within_level']) {
+        $join = new Join();
+        $join->construct('menu_links', $this->table_alias, $this->field . $i, 'mlid');
+        $menu_links = $this->query->add_table('menu_links', NULL, $join);
+        $this->query->add_orderby($menu_links, 'weight', $this->options['order']);
+        $this->query->add_orderby($menu_links, 'link_title', $this->options['order']);
+      }
+
+      // We need this even when also sorting by weight and title, to make sure
+      // that children of two parents with the same weight and title are
+      // correctly separated.
+      $this->query->add_orderby($this->table_alias, $this->field . $i, $this->options['order']);
+    }
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/sort/RandomSort.php b/lib/Drupal/views/Plugins/views/sort/RandomSort.php
new file mode 100644
index 0000000..4b91296
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/sort/RandomSort.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\sort\RandomSort.
+ */
+
+namespace Drupal\views\Plugins\views\sort;
+
+/**
+ * Handle a random sort.
+ *
+ * @ingroup views_sort_handlers
+ */
+class RandomSort extends SortPlugin {
+  function query() {
+    $this->query->add_orderby('rand');
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['order']['#access'] = FALSE;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/sort/SortPlugin.php b/lib/Drupal/views/Plugins/views/sort/SortPlugin.php
new file mode 100644
index 0000000..a2fa5f9
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/sort/SortPlugin.php
@@ -0,0 +1,244 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\sort\SortPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\sort;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_sort_handlers Views sort handlers
+ * @{
+ * Handlers to tell Views how to sort queries.
+ */
+
+/**
+ * Base sort handler that has no options and performs a simple sort.
+ *
+ * @ingroup views_sort_handlers
+ */
+class SortPlugin extends Plugin {
+
+  /**
+   * Determine if a sort can be exposed.
+   */
+  function can_expose() { return TRUE; }
+
+  /**
+   * Called to add the sort to a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+    // Add the field.
+    $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['order'] = array('default' => 'ASC');
+    $options['exposed'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['expose'] = array(
+      'contains' => array(
+        'label' => array('default' => '', 'translatable' => TRUE),
+      ),
+    );
+    return $options;
+  }
+
+  /**
+   * Display whether or not the sort order is ascending or descending
+   */
+  function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('Exposed');
+    }
+    switch ($this->options['order']) {
+      case 'ASC':
+      case 'asc':
+      default:
+        return t('asc');
+        break;
+      case 'DESC';
+      case 'desc';
+        return t('desc');
+        break;
+    }
+  }
+
+  /**
+   * Basic options for all sort criteria
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    if ($this->can_expose()) {
+      $this->show_expose_button($form, $form_state);
+    }
+    $form['op_val_start'] = array('#value' => '<div class="clearfix">');
+    $this->show_sort_form($form, $form_state);
+    $form['op_val_end'] = array('#value' => '</div>');
+    if ($this->can_expose()) {
+      $this->show_expose_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Shortcut to display the expose/hide button.
+   */
+  function show_expose_button(&$form, &$form_state) {
+    $form['expose_button'] = array(
+      '#prefix' => '<div class="views-expose clearfix">',
+      '#suffix' => '</div>',
+      // Should always come first
+      '#weight' => -1000,
+    );
+
+    // Add a checkbox for JS users, which will have behavior attached to it
+    // so it can replace the button.
+    $form['expose_button']['checkbox'] = array(
+      '#theme_wrappers' => array('container'),
+      '#attributes' => array('class' => array('js-only')),
+    );
+    $form['expose_button']['checkbox']['checkbox'] = array(
+      '#title' => t('Expose this sort to visitors, to allow them to change it'),
+      '#type' => 'checkbox',
+    );
+
+    // Then add the button itself.
+    if (empty($this->options['exposed'])) {
+      $form['expose_button']['markup'] = array(
+        '#markup' => '<div class="description exposed-description" style="float: left; margin-right:10px">' . t('This sort is not exposed. Expose it to allow the users to change it.') . '</div>',
+      );
+      $form['expose_button']['button'] = array(
+        '#limit_validation_errors' => array(),
+        '#type' => 'submit',
+        '#value' => t('Expose sort'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0;
+    }
+    else {
+      $form['expose_button']['markup'] = array(
+        '#markup' => '<div class="description exposed-description">' . t('This sort is exposed. If you hide it, users will not be able to change it.') . '</div>',
+      );
+      $form['expose_button']['button'] = array(
+        '#limit_validation_errors' => array(),
+        '#type' => 'submit',
+        '#value' => t('Hide sort'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1;
+    }
+  }
+
+  /**
+   * Simple validate handler
+   */
+  function options_validate(&$form, &$form_state) {
+    $this->sort_validate($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_validate($form, $form_state);
+    }
+
+  }
+
+  /**
+   * Simple submit handler
+   */
+  function options_submit(&$form, &$form_state) {
+    unset($form_state['values']['expose_button']); // don't store this.
+    $this->sort_submit($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_submit($form, $form_state);
+    }
+  }
+
+  /**
+   * Shortcut to display the value form.
+   */
+  function show_sort_form(&$form, &$form_state) {
+    $options = $this->sort_options();
+    if (!empty($options)) {
+      $form['order'] = array(
+        '#type' => 'radios',
+        '#options' => $options,
+        '#default_value' => $this->options['order'],
+      );
+    }
+  }
+
+  function sort_validate(&$form, &$form_state) { }
+
+  function sort_submit(&$form, &$form_state) { }
+
+  /**
+   * Provide a list of options for the default sort form.
+   * Should be overridden by classes that don't override sort_form
+   */
+  function sort_options() {
+    return array(
+      'ASC' => t('Sort ascending'),
+      'DESC' => t('Sort descending'),
+    );
+  }
+
+  function expose_form(&$form, &$form_state) {
+    // #flatten will move everything from $form['expose'][$key] to $form[$key]
+    // prior to rendering. That's why the pre_render for it needs to run first,
+    // so that when the next pre_render (the one for fieldsets) runs, it gets
+    // the flattened data.
+    array_unshift($form['#pre_render'], 'views_ui_pre_render_flatten_data');
+    $form['expose']['#flatten'] = TRUE;
+
+    $form['expose']['label'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['label'],
+      '#title' => t('Label'),
+      '#required' => TRUE,
+      '#size' => 40,
+      '#weight' => -1,
+   );
+  }
+
+  /**
+   * Provide default options for exposed sorts.
+   */
+  function expose_options() {
+    $this->options['expose'] = array(
+      'order' => $this->options['order'],
+      'label' => $this->definition['title'],
+    );
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ *
+ * @ingroup views_sort_handlers
+ */
+class views_handler_sort_broken extends views_handler_sort {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query($group_by = FALSE) { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/style/DefaultStyle.php b/lib/Drupal/views/Plugins/views/style/DefaultStyle.php
new file mode 100644
index 0000000..7e79cc0
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/DefaultStyle.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\DefaultStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Default style plugin to render rows one after another with no
+ * decorations.
+ *
+ * @ingroup views_style_plugins
+ */
+class DefaultStyle extends StylePlugin {
+  /**
+   * Set default options
+   */
+  function options(&$options) {
+    parent::options($options);
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/GridStyle.php b/lib/Drupal/views/Plugins/views/style/GridStyle.php
new file mode 100644
index 0000000..d6f72ab
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/GridStyle.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\GridStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Style plugin to render each item in a grid cell.
+ *
+ * @ingroup views_style_plugins
+ */
+class GridStyle extends StylePlugin {
+  /**
+   * Set default options
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['columns'] = array('default' => '4');
+    $options['alignment'] = array('default' => 'horizontal');
+    $options['fill_single_line'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['summary'] = array('default' => '');
+
+    return $options;
+  }
+
+  /**
+   * Render the given style.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['columns'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Number of columns'),
+      '#default_value' => $this->options['columns'],
+      '#required' => TRUE,
+      '#element_validate' => array('views_element_validate_integer'),
+    );
+    $form['alignment'] = array(
+      '#type' => 'radios',
+      '#title' => t('Alignment'),
+      '#options' => array('horizontal' => t('Horizontal'), 'vertical' => t('Vertical')),
+      '#default_value' => $this->options['alignment'],
+      '#description' => t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'),
+    );
+
+    $form['fill_single_line'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Fill up single line'),
+      '#description' => t('If you disable this option, a grid with only one row will have the same number of table cells (<TD>) as items. Disabling it can cause problems with your CSS.'),
+      '#default_value' => !empty($this->options['fill_single_line']),
+    );
+
+    $form['summary'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Table summary'),
+      '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'),
+      '#default_value' => $this->options['summary'],
+    );
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/JumpMenuStyle.php b/lib/Drupal/views/Plugins/views/style/JumpMenuStyle.php
new file mode 100644
index 0000000..9b7eadd
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/JumpMenuStyle.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\JumpMenuStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Style plugin to render each item as a row in a table.
+ *
+ * @ingroup views_style_plugins
+ */
+class JumpMenuStyle extends StylePlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['hide'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['path'] = array('default' => '');
+    $options['text'] = array('default' => 'Go', 'translatable' => TRUE);
+    $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE);
+    $options['default_value'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Render the given style.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $handlers = $this->display->handler->get_handlers('field');
+    if (empty($handlers)) {
+      $form['error_markup'] = array(
+        '#markup' => t('You need at least one field before you can configure your jump menu settings'),
+        '#prefix' => '<div class="error messages">',
+        '#suffix' => '</div>',
+      );
+      return;
+    }
+
+    $form['markup'] = array(
+      '#markup' => t('To properly configure a jump menu, you must select one field that will represent the path to utilize. You should then set that field to exclude. All other displayed fields will be part of the menu. Please note that all HTML will be stripped from this output as select boxes cannot show HTML.'),
+      '#prefix' => '<div class="form-item description">',
+      '#suffix' => '</div>',
+    );
+
+    foreach ($handlers as $id => $handler) {
+      $options[$id] = $handler->ui_name();
+    }
+
+    $form['path'] = array(
+      '#type' => 'select',
+      '#title' => t('Path field'),
+      '#options' => $options,
+      '#default_value' => $this->options['path'],
+    );
+
+    $form['hide'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide the "Go" button'),
+      '#default_value' => !empty($this->options['hide']),
+      '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'),
+    );
+
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Button text'),
+      '#default_value' => $this->options['text'],
+    );
+
+    $form['choose'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Choose text'),
+      '#default_value' => $this->options['choose'],
+      '#description' => t('The text that will appear as the selected option in the jump menu.'),
+    );
+
+    $form['default_value'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Select the current contextual filter value'),
+      '#default_value' => !empty($this->options['default_value']),
+      '#description' => t('If checked, the current path will be displayed as the default option in the jump menu, if applicable.'),
+    );
+  }
+
+  /**
+   * Render the display in this style.
+   *
+   * This is overridden so that we can render our grouping specially.
+   */
+  function render() {
+    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
+
+    // Turn this all into an $options array for the jump menu.
+    $this->view->row_index = 0;
+    $options = array();
+    $paths = array();
+
+    foreach ($sets as $title => $records) {
+      foreach ($records as $row_index => $row) {
+        $this->view->row_index = $row_index;
+        $path = strip_tags(decode_entities($this->get_field($this->view->row_index, $this->options['path'])));
+        // Putting a '/' in front messes up url() so let's take that out
+        // so users don't shoot themselves in the foot.
+        $base_path = base_path();
+        if (strpos($path, $base_path) === 0) {
+          $path = drupal_substr($path, drupal_strlen($base_path));
+        }
+
+        // use drupal_parse_url() to preserve query and fragment in case the user
+        // wants to do fun tricks.
+        $url_options = drupal_parse_url($path);
+
+        $path = url($url_options['path'], $url_options);
+        $field = strip_tags(decode_entities($this->row_plugin->render($row)));
+        $key = md5($path . $field) . "::" . $path;
+        if ($title) {
+          $options[$title][$key] = $field;
+        }
+        else {
+          $options[$key] = $field;
+        }
+        $paths[$path] = $key;
+        $this->view->row_index++;
+      }
+    }
+    unset($this->view->row_index);
+
+    $default_value = '';
+    if ($this->options['default_value'] && !empty($paths[url(current_path())])) {
+      $default_value = $paths[url(current_path())];
+    }
+
+    ctools_include('jump-menu');
+    $settings = array(
+      'hide' => $this->options['hide'],
+      'button' => $this->options['text'],
+      'choose' => $this->options['choose'],
+      'default_value' => $default_value,
+    );
+
+    $form = drupal_get_form('ctools_jump_menu', $options, $settings);
+    return $form;
+  }
+
+  function render_set($title, $records) {
+    $options = array();
+    $fields = $this->rendered_fields;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/JumpMenuStyleSummary.php b/lib/Drupal/views/Plugins/views/style/JumpMenuStyleSummary.php
new file mode 100644
index 0000000..93cd9e6
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/JumpMenuStyleSummary.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\JumpMenuStyleSummary.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * The default style plugin for summaries.
+ *
+ * @ingroup views_style_plugins
+ */
+class JumpMenuStyleSummary extends StyleSummaryPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['base_path'] = array('default' => '');
+    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['hide'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['text'] = array('default' => 'Go', 'translatable' => TRUE);
+    $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE);
+    $options['default_value'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function query() {
+    // Copy the offset option.
+    $pager = array(
+      'type' => 'none',
+      'options' => $this->display->handler->options['pager']['options'],
+    );
+    $this->display->handler->set_option('pager', $pager);
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['base_path'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Base path'),
+      '#default_value' => $this->options['base_path'],
+      '#description' => t('Define the base path for links in this summary
+        view, i.e. http://example.com/<strong>your_view_path/archive</strong>.
+        Do not include beginning and ending forward slash. If this value
+        is empty, views will use the first path found as the base path,
+        in page displays, or / if no path could be found.'),
+    );
+    $form['count'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['count']),
+      '#title' => t('Display record count with link'),
+    );
+
+    $form['hide'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide the "Go" button'),
+      '#default_value' => !empty($this->options['hide']),
+      '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'),
+    );
+
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Button text'),
+      '#default_value' => $this->options['text'],
+    );
+
+    $form['choose'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Choose text'),
+      '#default_value' => $this->options['choose'],
+      '#description' => t('The text that will appear as the selected option in the jump menu.'),
+    );
+
+    $form['default_value'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Select the current contextual filter value'),
+      '#default_value' => !empty($this->options['default_value']),
+      '#description' => t('If checked, the current contextual filter value will be displayed as the default option in the jump menu, if applicable.'),
+    );
+  }
+
+  function render() {
+    $argument = $this->view->argument[$this->view->build_info['summary_level']];
+
+    $url_options = array();
+
+    if (!empty($this->view->exposed_raw_input)) {
+      $url_options['query'] = $this->view->exposed_raw_input;
+    }
+
+    $options = array();
+    $default_value = '';
+    $row_args = array();
+    foreach ($this->view->result as $id => $row) {
+      $row_args[$id] = $argument->summary_argument($row);
+    }
+    $argument->process_summary_arguments($row_args);
+
+    foreach ($this->view->result as $id => $row) {
+      $args = $this->view->args;
+      $args[$argument->position] = $row_args[$id];
+      $base_path = NULL;
+      if (!empty($argument->options['summary_options']['base_path'])) {
+        $base_path = $argument->options['summary_options']['base_path'];
+      }
+      $path = url($this->view->get_url($args, $base_path), $url_options);
+      $summary_value = strip_tags($argument->summary_name($row));
+      $key = md5($path . $summary_value) . "::" . $path;
+
+      $options[$key] = $summary_value;
+      if (!empty($this->options['count'])) {
+        $options[$key] .= ' (' . intval($row->{$argument->count_alias}) . ')';
+      }
+      if ($this->options['default_value'] && current_path() == $this->view->get_url($args)) {
+        $default_value = $key;
+      }
+    }
+
+    ctools_include('jump-menu');
+    $settings = array(
+      'hide' => $this->options['hide'],
+      'button' => $this->options['text'],
+      'choose' => $this->options['choose'],
+      'default_value' => $default_value,
+    );
+
+    $form = drupal_get_form('ctools_jump_menu', $options, $settings);
+    return drupal_render($form);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/ListStyle.php b/lib/Drupal/views/Plugins/views/style/ListStyle.php
new file mode 100644
index 0000000..7df1469
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/ListStyle.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\ListStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Style plugin to render each item in an ordered or unordered list.
+ *
+ * @ingroup views_style_plugins
+ */
+class ListStyle extends StylePlugin {
+  /**
+   * Set default options
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['type'] = array('default' => 'ul');
+    $options['class'] = array('default' => '');
+    $options['wrapper_class'] = array('default' => 'item-list');
+
+    return $options;
+  }
+
+  /**
+   * Render the given style.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['type'] = array(
+      '#type' => 'radios',
+      '#title' => t('List type'),
+      '#options' => array('ul' => t('Unordered list'), 'ol' => t('Ordered list')),
+      '#default_value' => $this->options['type'],
+    );
+    $form['wrapper_class'] = array(
+      '#title' => t('Wrapper class'),
+      '#description' => t('The class to provide on the wrapper, outside the list.'),
+      '#type' => 'textfield',
+      '#size' => '30',
+      '#default_value' => $this->options['wrapper_class'],
+    );
+    $form['class'] = array(
+      '#title' => t('List class'),
+      '#description' => t('The class to provide on the list element itself.'),
+      '#type' => 'textfield',
+      '#size' => '30',
+      '#default_value' => $this->options['class'],
+    );
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/RssStyle.php b/lib/Drupal/views/Plugins/views/style/RssStyle.php
new file mode 100644
index 0000000..028bb0d
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/RssStyle.php
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\RssStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Default style plugin to render an RSS feed.
+ *
+ * @ingroup views_style_plugins
+ */
+class RssStyle extends StylePlugin {
+  function attach_to($display_id, $path, $title) {
+    $display = $this->view->display[$display_id]->handler;
+    $url_options = array();
+    $input = $this->view->get_exposed_input();
+    if ($input) {
+      $url_options['query'] = $input;
+    }
+    $url_options['absolute'] = TRUE;
+
+    $url = url($this->view->get_url(NULL, $path), $url_options);
+    if ($display->has_path()) {
+      if (empty($this->preview)) {
+        drupal_add_feed($url, $title);
+      }
+    }
+    else {
+      if (empty($this->view->feed_icon)) {
+        $this->view->feed_icon = '';
+      }
+
+      $this->view->feed_icon .= theme('feed_icon', array('url' => $url, 'title' => $title));
+      drupal_add_html_head_link(array(
+        'rel' => 'alternate',
+        'type' => 'application/rss+xml',
+        'title' => $title,
+        'href' => $url
+      ));
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['description'] = array('default' => '', 'translatable' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['description'] = array(
+      '#type' => 'textfield',
+      '#title' => t('RSS description'),
+      '#default_value' => $this->options['description'],
+      '#description' => t('This will appear in the RSS feed itself.'),
+      '#maxlength' => 1024,
+    );
+  }
+
+  /**
+   * Return an array of additional XHTML elements to add to the channel.
+   *
+   * @return
+   *   An array that can be passed to format_xml_elements().
+   */
+  function get_channel_elements() {
+    return array();
+  }
+
+  /**
+   * Get RSS feed description.
+   *
+   * @return string
+   *   The string containing the description with the tokens replaced.
+   */
+  function get_description() {
+    $description = $this->options['description'];
+
+    // Allow substitutions from the first row.
+    $description = $this->tokenize_value($description, 0);
+
+    return $description;
+  }
+
+  function render() {
+    if (empty($this->row_plugin)) {
+      vpr('views_plugin_style_default: Missing row plugin');
+      return;
+    }
+    $rows = '';
+
+    // This will be filled in by the row plugin and is used later on in the
+    // theming output.
+    $this->namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
+
+    // Fetch any additional elements for the channel and merge in their
+    // namespaces.
+    $this->channel_elements = $this->get_channel_elements();
+    foreach ($this->channel_elements as $element) {
+      if (isset($element['namespace'])) {
+        $this->namespaces = array_merge($this->namespaces, $element['namespace']);
+      }
+    }
+
+    foreach ($this->view->result as $row_index => $row) {
+      $this->view->row_index = $row_index;
+      $rows .= $this->row_plugin->render($row);
+    }
+
+    $output = theme($this->theme_functions(),
+      array(
+        'view' => $this->view,
+        'options' => $this->options,
+        'rows' => $rows
+      ));
+    unset($this->view->row_index);
+    return $output;
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/StylePlugin.php b/lib/Drupal/views/Plugins/views/style/StylePlugin.php
new file mode 100644
index 0000000..c27c4b6
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/StylePlugin.php
@@ -0,0 +1,607 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\StylePlugin.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+use Drupal\views\Plugins\views\Plugin;
+
+/**
+ * @defgroup views_style_plugins Views style plugins
+ * @{
+ * Style plugins control how a view is rendered. For example, they
+ * can choose to display a collection of fields, node_view() output,
+ * table output, or any kind of crazy output they want.
+ *
+ * Many style plugins can have an optional 'row' plugin, that displays
+ * a single record. Not all style plugins can utilize this, so it is
+ * up to the plugin to set this up and call through to the row plugin.
+ *
+ * @see hook_views_plugins()
+ */
+
+/**
+ * Base class to define a style plugin handler.
+ */
+class StylePlugin extends Plugin {
+  /**
+   * Store all available tokens row rows.
+   */
+  var $row_tokens = array();
+
+  /**
+   * Contains the row plugin, if it's initialized
+   * and the style itself supports it.
+   *
+   * @var views_plugin_row
+   */
+  var $row_plugin;
+
+  /**
+   * Initialize a style plugin.
+   *
+   * @param $view
+   * @param $display
+   * @param $options
+   *   The style options might come externally as the style can be sourced
+   *   from at least two locations. If it's not included, look on the display.
+   */
+  function init(&$view, &$display, $options = NULL) {
+    $this->view = &$view;
+    $this->display = &$display;
+
+    // Overlay incoming options on top of defaults
+    $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
+
+    if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
+      $this->row_plugin = $display->handler->get_plugin('row');
+    }
+
+    $this->options += array(
+      'grouping' => array(),
+    );
+
+    $this->definition += array(
+      'uses grouping' => TRUE,
+    );
+  }
+
+  function destroy() {
+    parent::destroy();
+
+    if (isset($this->row_plugin)) {
+      $this->row_plugin->destroy();
+    }
+  }
+
+  /**
+   * Return TRUE if this style also uses a row plugin.
+   */
+  function uses_row_plugin() {
+    return !empty($this->definition['uses row plugin']);
+  }
+
+  /**
+   * Return TRUE if this style also uses a row plugin.
+   */
+  function uses_row_class() {
+    return !empty($this->definition['uses row class']);
+  }
+
+  /**
+   * Return TRUE if this style also uses fields.
+   *
+   * @return bool
+   */
+  function uses_fields() {
+    // If we use a row plugin, ask the row plugin. Chances are, we don't
+    // care, it does.
+    $row_uses_fields = FALSE;
+    if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
+      $row_uses_fields = $this->row_plugin->uses_fields();
+    }
+    // Otherwise, check the definition or the option.
+    return $row_uses_fields || !empty($this->definition['uses fields']) || !empty($this->options['uses_fields']);
+  }
+
+  /**
+   * Return TRUE if this style uses tokens.
+   *
+   * Used to ensure we don't fetch tokens when not needed for performance.
+   */
+  function uses_tokens() {
+    if ($this->uses_row_class()) {
+      $class = $this->options['row_class'];
+      if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
+        return TRUE;
+      }
+    }
+  }
+
+  /**
+   * Return the token replaced row class for the specified row.
+   */
+  function get_row_class($row_index) {
+    if ($this->uses_row_class()) {
+      $class = $this->options['row_class'];
+      if ($this->uses_fields() && $this->view->field) {
+        $class = strip_tags($this->tokenize_value($class, $row_index));
+      }
+
+      $classes = explode(' ', $class);
+      foreach ($classes as &$class) {
+        $class = drupal_clean_css_identifier($class);
+      }
+      return implode(' ', $classes);
+    }
+  }
+
+  /**
+   * Take a value and apply token replacement logic to it.
+   */
+  function tokenize_value($value, $row_index) {
+    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
+      $fake_item = array(
+        'alter_text' => TRUE,
+        'text' => $value,
+      );
+
+      // Row tokens might be empty, for example for node row style.
+      $tokens = isset($this->row_tokens[$row_index]) ? $this->row_tokens[$row_index] : array();
+      if (!empty($this->view->build_info['substitutions'])) {
+        $tokens += $this->view->build_info['substitutions'];
+      }
+
+      if ($tokens) {
+        $value = strtr($value, $tokens);
+      }
+    }
+
+    return $value;
+  }
+
+  /**
+   * Should the output of the style plugin be rendered even if it's a empty view.
+   */
+  function even_empty() {
+    return !empty($this->definition['even empty']);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['grouping'] = array('default' => array());
+    if ($this->uses_row_class()) {
+      $options['row_class'] = array('default' => '');
+      $options['default_row_class'] = array('default' => TRUE, 'bool' => TRUE);
+      $options['row_class_special'] = array('default' => TRUE, 'bool' => TRUE);
+    }
+    $options['uses_fields'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    // Only fields-based views can handle grouping.  Style plugins can also exclude
+    // themselves from being groupable by setting their "use grouping" definiton
+    // key to FALSE.
+    // @TODO: Document "uses grouping" in docs.php when docs.php is written.
+    if ($this->uses_fields() && $this->definition['uses grouping']) {
+      $options = array('' => t('- None -'));
+      $field_labels = $this->display->handler->get_field_labels();
+      $options += $field_labels;
+
+      // If there are no fields, we can't group on them.
+      if (count($options) > 1) {
+        // This is for backward compability, when there was just a single select form.
+        if (is_string($this->options['grouping'])) {
+          $grouping = $this->options['grouping'];
+          $this->options['grouping'] = array();
+          $this->options['grouping'][0]['field'] = $grouping;
+        }
+        if (isset($this->options['group_rendered']) && is_string($this->options['group_rendered'])) {
+          $this->options['grouping'][0]['rendered'] = $this->options['group_rendered'];
+          unset($this->options['group_rendered']);
+        }
+
+        $c = count($this->options['grouping']);
+        // Add a form for every grouping, plus one.
+        for ($i = 0; $i <= $c; $i++) {
+          $grouping = !empty($this->options['grouping'][$i]) ? $this->options['grouping'][$i] : array();
+          $grouping += array('field' => '', 'rendered' => TRUE, 'rendered_strip' => FALSE);
+          $form['grouping'][$i]['field'] = array(
+            '#type' => 'select',
+            '#title' => t('Grouping field Nr.@number', array('@number' => $i + 1)),
+            '#options' => $options,
+            '#default_value' => $grouping['field'],
+            '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
+          );
+          $form['grouping'][$i]['rendered'] = array(
+            '#type' => 'checkbox',
+            '#title' => t('Use rendered output to group rows'),
+            '#default_value' => $grouping['rendered'],
+            '#description' => t('If enabled the rendered output of the grouping field is used to group the rows.'),
+            '#states' => array(
+              'invisible' => array(
+                ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
+              ),
+            ),
+          );
+          $form['grouping'][$i]['rendered_strip'] = array(
+            '#type' => 'checkbox',
+            '#title' => t('Remove tags from rendered output'),
+            '#default_value' => $grouping['rendered_strip'],
+            '#states' => array(
+              'invisible' => array(
+                ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
+              ),
+            ),
+          );
+        }
+      }
+    }
+
+    if ($this->uses_row_class()) {
+      $form['row_class'] = array(
+        '#title' => t('Row class'),
+        '#description' => t('The class to provide on each row.'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['row_class'],
+      );
+
+      if ($this->uses_fields()) {
+        $form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.');
+      }
+
+      $form['default_row_class'] = array(
+        '#title' => t('Add views row classes'),
+        '#description' => t('Add the default row classes like views-row-1 to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'),
+        '#type' => 'checkbox',
+        '#default_value' => $this->options['default_row_class'],
+      );
+      $form['row_class_special'] = array(
+        '#title' => t('Add striping (odd/even), first/last row classes'),
+        '#description' => t('Add css classes to the first and last line, as well as odd/even classes for striping.'),
+        '#type' => 'checkbox',
+        '#default_value' => $this->options['row_class_special'],
+      );
+    }
+
+    if (!$this->uses_fields() || !empty($this->options['uses_fields'])) {
+      $form['uses_fields'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Force using fields'),
+        '#description' => t('If neither the row nor the style plugin supports fields, this field allows to enable them, so you can for example use groupby.'),
+        '#default_value' => $this->options['uses_fields'],
+      );
+    }
+  }
+
+  function options_validate(&$form, &$form_state) {
+    // Don't run validation on style plugins without the grouping setting.
+    if (isset($form_state['values']['style_options']['grouping'])) {
+      // Don't save grouping if no field is specified.
+      foreach ($form_state['values']['style_options']['grouping'] as $index => $grouping) {
+        if (empty($grouping['field'])) {
+          unset($form_state['values']['style_options']['grouping'][$index]);
+        }
+      }
+    }
+  }
+
+  /**
+   * Called by the view builder to see if this style handler wants to
+   * interfere with the sorts. If so it should build; if it returns
+   * any non-TRUE value, normal sorting will NOT be added to the query.
+   */
+  function build_sort() { return TRUE; }
+
+  /**
+   * Called by the view builder to let the style build a second set of
+   * sorts that will come after any other sorts in the view.
+   */
+  function build_sort_post() { }
+
+  /**
+   * Allow the style to do stuff before each row is rendered.
+   *
+   * @param $result
+   *   The full array of results from the query.
+   */
+  function pre_render($result) {
+    if (!empty($this->row_plugin)) {
+      $this->row_plugin->pre_render($result);
+    }
+  }
+
+  /**
+   * Render the display in this style.
+   */
+  function render() {
+    if ($this->uses_row_plugin() && empty($this->row_plugin)) {
+      debug('views_plugin_style_default: Missing row plugin');
+      return;
+    }
+
+    // Group the rows according to the grouping instructions, if specified.
+    $sets = $this->render_grouping(
+      $this->view->result,
+      $this->options['grouping'],
+      TRUE
+    );
+
+    return $this->render_grouping_sets($sets);
+  }
+
+  /**
+   * Render the grouping sets.
+   *
+   * Plugins may override this method if they wish some other way of handling
+   * grouping.
+   *
+   * @param $sets
+   *   Array containing the grouping sets to render.
+   * @param $level
+   *   Integer indicating the hierarchical level of the grouping.
+   *
+   * @return string
+   *   Rendered output of given grouping sets.
+   */
+  function render_grouping_sets($sets, $level = 0) {
+    $output = '';
+    foreach ($sets as $set) {
+      $row = reset($set['rows']);
+      // Render as a grouping set.
+      if (is_array($row) && isset($row['group'])) {
+        $output .= theme(views_theme_functions('views_view_grouping', $this->view, $this->display),
+          array(
+            'view' => $this->view,
+            'grouping' => $this->options['grouping'][$level],
+            'grouping_level' => $level,
+            'rows' => $set['rows'],
+            'title' => $set['group'])
+        );
+      }
+      // Render as a record set.
+      else {
+        if ($this->uses_row_plugin()) {
+          foreach ($set['rows'] as $index => $row) {
+            $this->view->row_index = $index;
+            $set['rows'][$index] = $this->row_plugin->render($row);
+          }
+        }
+
+        $output .= theme($this->theme_functions(),
+          array(
+            'view' => $this->view,
+            'options' => $this->options,
+            'grouping_level' => $level,
+            'rows' => $set['rows'],
+            'title' => $set['group'])
+        );
+      }
+    }
+    unset($this->view->row_index);
+    return $output;
+  }
+
+  /**
+   * Group records as needed for rendering.
+   *
+   * @param $records
+   *   An array of records from the view to group.
+   * @param $groupings
+   *   An array of grouping instructions on which fields to group. If empty, the
+   *   result set will be given a single group with an empty string as a label.
+   * @param $group_rendered
+   *   Boolean value whether to use the rendered or the raw field value for
+   *   grouping. If set to NULL the return is structured as before
+   *   Views 7.x-3.0-rc2. After Views 7.x-3.0 this boolean is only used if
+   *   $groupings is an old-style string or if the rendered option is missing
+   *   for a grouping instruction.
+   * @return
+   *   The grouped record set.
+   *   A nested set structure is generated if multiple grouping fields are used.
+   *
+   *   @code
+   *   array(
+   *     'grouping_field_1:grouping_1' => array(
+   *       'group' => 'grouping_field_1:content_1',
+   *       'rows' => array(
+   *         'grouping_field_2:grouping_a' => array(
+   *           'group' => 'grouping_field_2:content_a',
+   *           'rows' => array(
+   *             $row_index_1 => $row_1,
+   *             $row_index_2 => $row_2,
+   *             // ...
+   *           )
+   *         ),
+   *       ),
+   *     ),
+   *     'grouping_field_1:grouping_2' => array(
+   *       // ...
+   *     ),
+   *   )
+   *   @endcode
+   */
+  function render_grouping($records, $groupings = array(), $group_rendered = NULL) {
+    // This is for backward compability, when $groupings was a string containing
+    // the ID of a single field.
+    if (is_string($groupings)) {
+      $rendered = $group_rendered === NULL ? TRUE : $group_rendered;
+      $groupings = array(array('field' => $groupings, 'rendered' => $rendered));
+    }
+
+    // Make sure fields are rendered
+    $this->render_fields($this->view->result);
+    $sets = array();
+    if ($groupings) {
+      foreach ($records as $index => $row) {
+        // Iterate through configured grouping fields to determine the
+        // hierarchically positioned set where the current row belongs to.
+        // While iterating, parent groups, that do not exist yet, are added.
+        $set = &$sets;
+        foreach ($groupings as $info) {
+          $field = $info['field'];
+          $rendered = isset($info['rendered']) ? $info['rendered'] : $group_rendered;
+          $rendered_strip = isset($info['rendered_strip']) ? $info['rendered_strip'] : FALSE;
+          $grouping = '';
+          $group_content = '';
+          // Group on the rendered version of the field, not the raw.  That way,
+          // we can control any special formatting of the grouping field through
+          // the admin or theme layer or anywhere else we'd like.
+          if (isset($this->view->field[$field])) {
+            $group_content = $this->get_field($index, $field);
+            if ($this->view->field[$field]->options['label']) {
+              $group_content = $this->view->field[$field]->options['label'] . ': ' . $group_content;
+            }
+            if ($rendered) {
+              $grouping = $group_content;
+              if ($rendered_strip) {
+                $group_content = $grouping = strip_tags(htmlspecialchars_decode($group_content));
+              }
+            }
+            else {
+              $grouping = $this->get_field_value($index, $field);
+              // Not all field handlers return a scalar value,
+              // e.g. views_handler_field_field.
+              if (!is_scalar($grouping)) {
+                $grouping = md5(serialize($grouping));
+              }
+            }
+          }
+
+          // Create the group if it does not exist yet.
+          if (empty($set[$grouping])) {
+            $set[$grouping]['group'] = $group_content;
+            $set[$grouping]['rows'] = array();
+          }
+
+          // Move the set reference into the row set of the group we just determined.
+          $set = &$set[$grouping]['rows'];
+        }
+        // Add the row to the hierarchically positioned row set we just determined.
+        $set[$index] = $row;
+      }
+    }
+    else {
+      // Create a single group with an empty grouping field.
+      $sets[''] = array(
+        'group' => '',
+        'rows' => $records,
+      );
+    }
+
+    // If this parameter isn't explicitely set modify the output to be fully
+    // backward compatible to code before Views 7.x-3.0-rc2.
+    // @TODO Remove this as soon as possible e.g. October 2020
+    if ($group_rendered === NULL) {
+      $old_style_sets = array();
+      foreach ($sets as $group) {
+        $old_style_sets[$group['group']] = $group['rows'];
+      }
+      $sets = $old_style_sets;
+    }
+
+    return $sets;
+  }
+
+  /**
+   * Render all of the fields for a given style and store them on the object.
+   *
+   * @param $result
+   *   The result array from $view->result
+   */
+  function render_fields($result) {
+    if (!$this->uses_fields()) {
+      return;
+    }
+
+    if (!isset($this->rendered_fields)) {
+      $this->rendered_fields = array();
+      $this->view->row_index = 0;
+      $keys = array_keys($this->view->field);
+
+      // If all fields have a field::access FALSE there might be no fields, so
+      // there is no reason to execute this code.
+      if (!empty($keys)) {
+        foreach ($result as $count => $row) {
+          $this->view->row_index = $count;
+          foreach ($keys as $id) {
+            $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
+          }
+
+          $this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array());
+        }
+      }
+      unset($this->view->row_index);
+    }
+
+    return $this->rendered_fields;
+  }
+
+  /**
+   * Get a rendered field.
+   *
+   * @param $index
+   *   The index count of the row.
+   * @param $field
+   *    The id of the field.
+   */
+  function get_field($index, $field) {
+    if (!isset($this->rendered_fields)) {
+      $this->render_fields($this->view->result);
+    }
+
+    if (isset($this->rendered_fields[$index][$field])) {
+      return $this->rendered_fields[$index][$field];
+    }
+  }
+
+  /**
+  * Get the raw field value.
+  *
+  * @param $index
+  *   The index count of the row.
+  * @param $field
+  *    The id of the field.
+  */
+  function get_field_value($index, $field) {
+    $this->view->row_index = $index;
+    $value = $this->view->field[$field]->get_value($this->view->result[$index]);
+    unset($this->view->row_index);
+    return $value;
+  }
+
+  function validate() {
+    $errors = parent::validate();
+
+    if ($this->uses_row_plugin()) {
+      $plugin = $this->display->handler->get_plugin('row');
+      if (empty($plugin)) {
+        $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
+      }
+      else {
+        $result = $plugin->validate();
+        if (!empty($result) && is_array($result)) {
+          $errors = array_merge($errors, $result);
+        }
+      }
+    }
+    return $errors;
+  }
+
+  function query() {
+    parent::query();
+    if (isset($this->row_plugin)) {
+      $this->row_plugin->query();
+    }
+  }
+}
+
+/**
+ * @}
+ */
diff --git a/lib/Drupal/views/Plugins/views/style/StyleSummaryPlugin.php b/lib/Drupal/views/Plugins/views/style/StyleSummaryPlugin.php
new file mode 100644
index 0000000..f98962a
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/StyleSummaryPlugin.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\StyleSummaryPlugin.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+use Drupal\views\Plugins\Plugin;
+
+/**
+ * The default style plugin for summaries.
+ *
+ * @ingroup views_style_plugins
+ */
+class StyleSummaryPlugin extends Plugin {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['base_path'] = array('default' => '');
+    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['override'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['items_per_page'] = array('default' => 25);
+
+    return $options;
+  }
+
+  function query() {
+    if (!empty($this->options['override'])) {
+      $this->view->set_items_per_page(intval($this->options['items_per_page']));
+    }
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['base_path'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Base path'),
+      '#default_value' => $this->options['base_path'],
+      '#description' => t('Define the base path for links in this summary
+        view, i.e. http://example.com/<strong>your_view_path/archive</strong>.
+        Do not include beginning and ending forward slash. If this value
+        is empty, views will use the first path found as the base path,
+        in page displays, or / if no path could be found.'),
+    );
+    $form['count'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['count']),
+      '#title' => t('Display record count with link'),
+    );
+    $form['override'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['override']),
+      '#title' => t('Override number of items to display'),
+    );
+
+    $form['items_per_page'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Items to display'),
+      '#default_value' => $this->options['items_per_page'],
+      '#states' => array(
+        'visible' => array(
+          ':input[name="options[summary][options][' . $this->definition['name'] . '][override]"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+  }
+
+  function render() {
+    $rows = array();
+    foreach ($this->view->result as $row) {
+      // @todo: Include separator as an option.
+      $rows[] = $row;
+    }
+
+    return theme($this->theme_functions(), array(
+      'view' => $this->view,
+      'options' => $this->options,
+      'rows' => $rows
+    ));
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/TableStyle.php b/lib/Drupal/views/Plugins/views/style/TableStyle.php
new file mode 100644
index 0000000..d16d730
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/TableStyle.php
@@ -0,0 +1,322 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\TableStyle.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * Style plugin to render each item as a row in a table.
+ *
+ * @ingroup views_style_plugins
+ */
+class TableStyle extends StylePlugin {
+
+  /**
+   * Contains the current active sort column.
+   * @var string
+   */
+  public $active;
+
+  /**
+   * Contains the current active sort order, either desc or asc.
+   * @var string
+   */
+  public $order;
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['columns'] = array('default' => array());
+    $options['default'] = array('default' => '');
+    $options['info'] = array('default' => array());
+    $options['override'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['sticky'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['order'] = array('default' => 'asc');
+    $options['summary'] = array('default' => '', 'translatable' => TRUE);
+    $options['empty_table'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Determine if we should provide sorting based upon $_GET inputs
+   *
+   * @return bool
+   */
+  function build_sort() {
+    if (!isset($_GET['order']) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) {
+      return TRUE;
+    }
+
+    // If a sort we don't know anything about gets through, exit gracefully.
+    if (isset($_GET['order']) && empty($this->view->field[$_GET['order']])) {
+      return TRUE;
+    }
+
+    // Let the builder know whether or not we're overriding the default sorts.
+    return empty($this->options['override']);
+  }
+
+  /**
+   * Add our actual sort criteria
+   */
+  function build_sort_post() {
+    if (!isset($_GET['order'])) {
+      // check for a 'default' clicksort. If there isn't one, exit gracefully.
+      if (empty($this->options['default'])) {
+        return;
+      }
+      $sort = $this->options['default'];
+      if (!empty($this->options['info'][$sort]['default_sort_order'])) {
+        $this->order = $this->options['info'][$sort]['default_sort_order'];
+      }
+      else {
+        $this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc';
+      }
+    }
+    else {
+      $sort = $_GET['order'];
+      // Store the $order for later use.
+      $this->order = !empty($_GET['sort']) ? strtolower($_GET['sort']) : 'asc';
+    }
+
+    // If a sort we don't know anything about gets through, exit gracefully.
+    if (empty($this->view->field[$sort])) {
+      return;
+    }
+
+    // Ensure $this->order is valid.
+    if ($this->order != 'asc' && $this->order != 'desc') {
+      $this->order = 'asc';
+    }
+
+    // Store the $sort for later use.
+    $this->active = $sort;
+
+    // Tell the field to click sort.
+    $this->view->field[$sort]->click_sort($this->order);
+  }
+
+  /**
+   * Normalize a list of columns based upon the fields that are
+   * available. This compares the fields stored in the style handler
+   * to the list of fields actually in the view, removing fields that
+   * have been removed and adding new fields in their own column.
+   *
+   * - Each field must be in a column.
+   * - Each column must be based upon a field, and that field
+   *   is somewhere in the column.
+   * - Any fields not currently represented must be added.
+   * - Columns must be re-ordered to match the fields.
+   *
+   * @param $columns
+   *   An array of all fields; the key is the id of the field and the
+   *   value is the id of the column the field should be in.
+   * @param $fields
+   *   The fields to use for the columns. If not provided, they will
+   *   be requested from the current display. The running render should
+   *   send the fields through, as they may be different than what the
+   *   display has listed due to access control or other changes.
+   *
+   * @return array
+   *    An array of all the sanitized columns.
+   */
+  function sanitize_columns($columns, $fields = NULL) {
+    $sanitized = array();
+    if ($fields === NULL) {
+      $fields = $this->display->handler->get_option('fields');
+    }
+    // Preconfigure the sanitized array so that the order is retained.
+    foreach ($fields as $field => $info) {
+      // Set to itself so that if it isn't touched, it gets column
+      // status automatically.
+      $sanitized[$field] = $field;
+    }
+
+    foreach ($columns as $field => $column) {
+      // first, make sure the field still exists.
+      if (!isset($sanitized[$field])) {
+        continue;
+      }
+
+      // If the field is the column, mark it so, or the column
+      // it's set to is a column, that's ok
+      if ($field == $column || $columns[$column] == $column && !empty($sanitized[$column])) {
+        $sanitized[$field] = $column;
+      }
+      // Since we set the field to itself initially, ignoring
+      // the condition is ok; the field will get its column
+      // status back.
+    }
+
+    return $sanitized;
+  }
+
+  /**
+   * Render the given style.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $handlers = $this->display->handler->get_handlers('field');
+    if (empty($handlers)) {
+      $form['error_markup'] = array(
+        '#markup' => '<div class="error messages">' . t('You need at least one field before you can configure your table settings') . '</div>',
+      );
+      return;
+    }
+
+    $form['override'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Override normal sorting if click sorting is used'),
+      '#default_value' => !empty($this->options['override']),
+    );
+
+    $form['sticky'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable Drupal style "sticky" table headers (Javascript)'),
+      '#default_value' => !empty($this->options['sticky']),
+      '#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'),
+    );
+
+    $form['summary'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Table summary'),
+      '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'),
+      '#default_value' => $this->options['summary'],
+      '#maxlength' => 255,
+    );
+
+    // Note: views UI registers this theme handler on our behalf. Your module
+    // will have to register your theme handlers if you do stuff like this.
+    $form['#theme'] = 'views_ui_style_plugin_table';
+
+    $columns = $this->sanitize_columns($this->options['columns']);
+
+    // Create an array of allowed columns from the data we know:
+    $field_names = $this->display->handler->get_field_labels();
+
+    if (isset($this->options['default'])) {
+      $default = $this->options['default'];
+      if (!isset($columns[$default])) {
+        $default = -1;
+      }
+    }
+    else {
+      $default = -1;
+    }
+
+    foreach ($columns as $field => $column) {
+      $column_selector = ':input[name="style_options[columns][' . $field . ']"]';
+
+      $form['columns'][$field] = array(
+        '#type' => 'select',
+        '#options' => $field_names,
+        '#default_value' => $column,
+      );
+      if ($handlers[$field]->click_sortable()) {
+        $form['info'][$field]['sortable'] = array(
+          '#type' => 'checkbox',
+          '#default_value' => !empty($this->options['info'][$field]['sortable']),
+          '#states' => array(
+            'visible' => array(
+              $column_selector => array('value' => $field),
+            ),
+          ),
+        );
+        $form['info'][$field]['default_sort_order'] = array(
+          '#type' => 'select',
+          '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')),
+          '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc',
+          '#states' => array(
+            'visible' => array(
+              $column_selector => array('value' => $field),
+              ':input[name="style_options[info][' . $field . '][sortable]"]' => array('checked' => TRUE),
+            ),
+          ),
+        );
+        // Provide an ID so we can have such things.
+        $radio_id = drupal_html_id('edit-default-' . $field);
+        $form['default'][$field] = array(
+          '#type' => 'radio',
+          '#return_value' => $field,
+          '#parents' => array('style_options', 'default'),
+          '#id' => $radio_id,
+          // because 'radio' doesn't fully support '#id' =(
+          '#attributes' => array('id' => $radio_id),
+          '#default_value' => $default,
+          '#states' => array(
+            'visible' => array(
+              $column_selector => array('value' => $field),
+            ),
+          ),
+        );
+      }
+      $form['info'][$field]['align'] = array(
+        '#type' => 'select',
+        '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '',
+        '#options' => array(
+          '' => t('None'),
+          'views-align-left' => t('Left'),
+          'views-align-center' => t('Center'),
+          'views-align-right' => t('Right'),
+          ),
+        '#states' => array(
+          'visible' => array(
+            $column_selector => array('value' => $field),
+          ),
+        ),
+      );
+      $form['info'][$field]['separator'] = array(
+        '#type' => 'textfield',
+        '#size' => 10,
+        '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '',
+        '#states' => array(
+          'visible' => array(
+            $column_selector => array('value' => $field),
+          ),
+        ),
+      );
+      $form['info'][$field]['empty_column'] = array(
+        '#type' => 'checkbox',
+        '#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE,
+        '#states' => array(
+          'visible' => array(
+            $column_selector => array('value' => $field),
+          ),
+        ),
+      );
+
+      // markup for the field name
+      $form['info'][$field]['name'] = array(
+        '#markup' => $field_names[$field],
+      );
+    }
+
+    // Provide a radio for no default sort
+    $form['default'][-1] = array(
+      '#type' => 'radio',
+      '#return_value' => -1,
+      '#parents' => array('style_options', 'default'),
+      '#id' => 'edit-default-0',
+      '#default_value' => $default,
+    );
+
+    $form['empty_table'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show the empty text in the table'),
+      '#default_value' => $this->options['empty_table'],
+      '#description' => t('Per default the table is hidden for an empty view. With this option it is posible to show an empty table with the text in it.'),
+    );
+
+    $form['description_markup'] = array(
+      '#markup' => '<div class="description form-item">' . t('Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section.') . '</div>',
+    );
+  }
+
+  function even_empty() {
+    return parent::even_empty() || !empty($this->options['empty_table']);
+  }
+}
diff --git a/lib/Drupal/views/Plugins/views/style/UnformattedStyleSummary.php b/lib/Drupal/views/Plugins/views/style/UnformattedStyleSummary.php
new file mode 100644
index 0000000..0a29eb6
--- /dev/null
+++ b/lib/Drupal/views/Plugins/views/style/UnformattedStyleSummary.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Plugins\views\style\UnformattedStyleSummary.
+ */
+
+namespace Drupal\views\Plugins\views\style;
+
+/**
+ * The default style plugin for summaries.
+ *
+ * @ingroup views_style_plugins
+ */
+class UnformattedStyleSummary extends StyleSummaryPlugin {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['inline'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['separator'] = array('default' => '');
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['inline'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['inline']),
+      '#title' => t('Display items inline'),
+    );
+    $form['separator'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Separator'),
+      '#default_value' => $this->options['separator'],
+    );
+  }
+}
diff --git a/lib/Drupal/views/View.php b/lib/Drupal/views/View.php
index 715d730..4211019 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\Plugins\Type\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/export_ui/views_ui.class.php b/plugins/export_ui/views_ui.class.php
deleted file mode 100644
index c5c4001..0000000
--- a/plugins/export_ui/views_ui.class.php
+++ /dev/null
@@ -1,442 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the CTools Export UI integration code.
- *
- * Note that this is only a partial integration.
- */
-
-/**
- * CTools Export UI class handler for Views UI.
- */
-class views_ui extends ctools_export_ui {
-
-  function init($plugin) {
-    // We modify the plugin info here so that we take the defaults and
-    // twiddle, rather than completely override them.
-
-    // Reset the edit path to match what we're really using.
-    $plugin['menu']['items']['edit']['path'] = 'view/%ctools_export_ui/edit';
-    $plugin['menu']['items']['clone']['path'] = 'view/%ctools_export_ui/clone';
-    $plugin['menu']['items']['clone']['type'] = MENU_VISIBLE_IN_BREADCRUMB;
-    $plugin['menu']['items']['export']['path'] = 'view/%ctools_export_ui/export';
-    $plugin['menu']['items']['export']['type'] = MENU_VISIBLE_IN_BREADCRUMB;
-    $plugin['menu']['items']['enable']['path'] = 'view/%ctools_export_ui/enable';
-    $plugin['menu']['items']['disable']['path'] = 'view/%ctools_export_ui/disable';
-    $plugin['menu']['items']['delete']['path'] = 'view/%ctools_export_ui/delete';
-    $plugin['menu']['items']['delete']['type'] = MENU_VISIBLE_IN_BREADCRUMB;
-    $plugin['menu']['items']['revert']['path'] = 'view/%ctools_export_ui/revert';
-    $plugin['menu']['items']['revert']['type'] = MENU_VISIBLE_IN_BREADCRUMB;
-
-    $prefix_count = count(explode('/', $plugin['menu']['menu prefix']));
-    $plugin['menu']['items']['add-template'] = array(
-      'path' => 'template/%/add',
-      'title' => 'Add from template',
-      'page callback' => 'ctools_export_ui_switcher_page',
-      'page arguments' => array($plugin['name'], 'add_template', $prefix_count + 2),
-      'load arguments' => array($plugin['name']),
-      'access callback' => 'ctools_export_ui_task_access',
-      'access arguments' => array($plugin['name'], 'add_template', $prefix_count + 2),
-      'type' => MENU_CALLBACK,
-    );
-
-    return parent::init($plugin);
-  }
-
-  function hook_menu(&$items) {
-    // We are using our own 'edit' still, rather than having edit on this
-    // object (maybe in the future) so unset the edit callbacks:
-
-    // Store this so we can put them back as sometimes they're needed
-    // again laster:
-    $stored_items = $this->plugin['menu']['items'];
-    // We leave these to make sure the operations still exist in the plugin so
-    // that the path finder.
-    unset($this->plugin['menu']['items']['edit']);
-    unset($this->plugin['menu']['items']['add']);
-    unset($this->plugin['menu']['items']['import']);
-    unset($this->plugin['menu']['items']['edit callback']);
-
-    parent::hook_menu($items);
-
-    $this->plugin['menu']['items'] = $stored_items;
-  }
-
-  function load_item($item_name) {
-    return views_ui_cache_load($item_name);
-  }
-
-  function list_form(&$form, &$form_state) {
-    $row_class = 'container-inline';
-    if (!config('views.settings')->get('views_ui_show_listing_filters')) {
-      $row_class .= " element-invisible";
-    }
-
-    views_include('admin');
-
-    parent::list_form($form, $form_state);
-
-    // ctools only has two rows. We want four.
-    // That's why we create our own structure.
-    $form['bottom row']['submit']['#attributes']['class'][] = 'js-hide';
-    $form['first row'] = array(
-      '#prefix' => '<div class="' . $row_class . ' ctools-export-ui-row ctools-export-ui-first-row clearfix">',
-      '#suffix' => '</div>',
-      'search' => $form['top row']['search'],
-      'submit' => $form['bottom row']['submit'],
-      'reset' => $form['bottom row']['reset'],
-    );
-    $form['second row'] = array(
-      '#prefix' => '<div class="' . $row_class . ' ctools-export-ui-row ctools-export-ui-second-row clearfix">',
-      '#suffix' => '</div>',
-      'storage' => $form['top row']['storage'],
-      'disabled' => $form['top row']['disabled'],
-    );
-    $form['third row'] = array(
-      '#prefix' => '<div class="' . $row_class . ' ctools-export-ui-row ctools-export-ui-third-row clearfix element-hidden">',
-      '#suffix' => '</div>',
-      'order' => $form['bottom row']['order'],
-      'sort' => $form['bottom row']['sort'],
-    );
-    unset($form['top row']);
-    unset($form['bottom row']);
-
-    // Modify the look and contents of existing form elements.
-    $form['second row']['storage']['#title'] = '';
-    $form['second row']['storage']['#options'] = array(
-      'all' => t('All storage'),
-      t('Normal') => t('In database'),
-      t('Default') => t('In code'),
-      t('Overridden') => t('Database overriding code'),
-    );
-    $form['second row']['disabled']['#title'] = '';
-    $form['second row']['disabled']['#options']['all'] = t('All status');
-    $form['third row']['sort']['#title'] = '';
-
-    // And finally, add our own.
-    $this->bases = array();
-    foreach (views_fetch_base_tables() as $table => $info) {
-      $this->bases[$table] = $info['title'];
-    }
-
-    $form['second row']['base'] = array(
-      '#type' => 'select',
-      '#options' => array_merge(array('all' => t('All types')), $this->bases),
-      '#default_value' => 'all',
-      '#weight' => -1,
-    );
-
-    $tags = array();
-    if (isset($form_state['object']->items)) {
-      foreach ($form_state['object']->items as $name => $view) {
-        if (!empty($view->tag)) {
-          $view_tags = drupal_explode_tags($view->tag);
-          foreach ($view_tags as $tag) {
-            $tags[$tag] = $tag;
-          }
-        }
-      }
-    }
-    asort($tags);
-
-    $form['second row']['tag'] = array(
-      '#type' => 'select',
-      '#title' => t('Filter'),
-      '#options' => array_merge(array('all' => t('All tags')), array('none' => t('No tags')), $tags),
-      '#default_value' => 'all',
-      '#weight' => -9,
-    );
-
-    $displays = array();
-    foreach (views_fetch_plugin_data('display') as $id => $info) {
-      if (!empty($info['admin'])) {
-        $displays[$id] = $info['admin'];
-      }
-    }
-    asort($displays);
-
-    $form['second row']['display'] = array(
-      '#type' => 'select',
-      '#options' => array_merge(array('all' => t('All displays')), $displays),
-      '#default_value' => 'all',
-      '#weight' => -1,
-    );
-  }
-
-  function list_filter($form_state, $view) {
-    // Don't filter by tags if all is set up.
-    if ($form_state['values']['tag'] != 'all') {
-      // If none is selected check whether the view has a tag.
-      if ($form_state['values']['tag'] == 'none') {
-        return !empty($view->tag);
-      }
-      else {
-        // Check whether the tag can be found in the views tag.
-        return strpos($view->tag, $form_state['values']['tag']) === FALSE;
-      }
-    }
-    if ($form_state['values']['base'] != 'all' && $form_state['values']['base'] != $view->base_table) {
-      return TRUE;
-    }
-
-    return parent::list_filter($form_state, $view);
-  }
-
-  function list_sort_options() {
-    return array(
-      'disabled' => t('Enabled, name'),
-      'name' => t('Name'),
-      'path' => t('Path'),
-      'tag' => t('Tag'),
-      'storage' => t('Storage'),
-    );
-  }
-
-
-  function list_build_row($view, &$form_state, $operations) {
-    if (!empty($view->human_name)) {
-      $title = $view->human_name;
-    }
-    else {
-      $title = $view->get_title();
-      if (empty($title)) {
-        $title = $view->name;
-      }
-    }
-
-    $paths = _views_ui_get_paths($view);
-    $paths = implode(", ", $paths);
-
-    $base = !empty($this->bases[$view->base_table]) ? $this->bases[$view->base_table] : t('Broken');
-
-    $info = theme('views_ui_view_info', array('view' => $view, 'base' => $base));
-
-    // Reorder the operations so that enable is the default action for a templatic views
-    if (!empty($operations['enable'])) {
-      $operations = array('enable' => $operations['enable']) + $operations;
-    }
-
-    // Set up sorting
-    switch ($form_state['values']['order']) {
-      case 'disabled':
-        $this->sorts[$view->name] = strtolower(empty($view->disabled) . $title);
-        break;
-      case 'name':
-        $this->sorts[$view->name] = strtolower($title);
-        break;
-      case 'path':
-        $this->sorts[$view->name] = strtolower($paths);
-        break;
-      case 'tag':
-        $this->sorts[$view->name] = strtolower($view->tag);
-        break;
-      case 'storage':
-        $this->sorts[$view->name] = strtolower($view->type . $title);
-        break;
-    }
-
-    $ops = theme('links__ctools_dropbutton', array('links' => $operations, 'attributes' => array('class' => array('links', 'inline'))));
-
-    $this->rows[$view->name] = array(
-      'data' => array(
-        array('data' => $info, 'class' => array('views-ui-name')),
-        array('data' => check_plain($view->description), 'class' => array('views-ui-description')),
-        array('data' => check_plain($view->tag), 'class' => array('views-ui-tag')),
-        array('data' => $paths, 'class' => array('views-ui-path')),
-        array('data' => $ops, 'class' => array('views-ui-operations')),
-      ),
-      'title' => t('Machine name: ') . check_plain($view->name),
-      'class' => array(!empty($view->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled'),
-    );
-  }
-
-  function list_render(&$form_state) {
-    views_include('admin');
-    views_ui_add_admin_css();
-    if (empty($_REQUEST['js'])) {
-      views_ui_check_advanced_help();
-    }
-    drupal_add_library('system', 'jquery.bbq');
-    views_add_js('views-list');
-
-    $this->active = $form_state['values']['order'];
-    $this->order = $form_state['values']['sort'];
-
-    $query    = tablesort_get_query_parameters();
-
-    $header = array(
-      $this->tablesort_link(t('View name'), 'name', 'views-ui-name'),
-      array('data' => t('Description'), 'class' => array('views-ui-description')),
-      $this->tablesort_link(t('Tag'), 'tag', 'views-ui-tag'),
-      $this->tablesort_link(t('Path'), 'path', 'views-ui-path'),
-      array('data' => t('Operations'), 'class' => array('views-ui-operations')),
-    );
-
-    $table = array(
-      'header' => $header,
-      'rows' => $this->rows,
-      'empty' => t('No views match the search criteria.'),
-      'attributes' => array('id' => 'ctools-export-ui-list-items'),
-    );
-    return theme('table', $table);
-  }
-
-  function tablesort_link($label, $field, $class) {
-    $title = t('sort by @s', array('@s' => $label));
-    $initial = 'asc';
-
-    if ($this->active == $field) {
-      $initial = ($this->order == 'asc') ? 'desc' : 'asc';
-      $label .= theme('tablesort_indicator', array('style' => $initial));
-    }
-
-    $query['order'] = $field;
-    $query['sort'] = $initial;
-    $link_options = array(
-      'html' => TRUE,
-      'attributes' => array('title' => $title),
-      'query' => $query,
-    );
-    $link = l($label, current_path(), $link_options);
-    if ($this->active == $field) {
-      $class .= ' active';
-    }
-
-    return array('data' => $link, 'class' => $class);
-  }
-
-  function clone_page($js, $input, $item, $step = NULL) {
-    drupal_set_title($this->get_page_title('clone', $item));
-
-    $name = $item->{$this->plugin['export']['key']};
-
-    $form_state = array(
-      'plugin' => $this->plugin,
-      'object' => &$this,
-      'ajax' => $js,
-      'item' => $item,
-      'op' => 'add',
-      'form type' => 'clone',
-      'original name' => $name,
-      'rerender' => TRUE,
-      'no_redirect' => TRUE,
-      'step' => $step,
-      // Store these in case additional args are needed.
-      'function args' => func_get_args(),
-    );
-
-    $output = drupal_build_form('views_ui_clone_form', $form_state);
-    if (!empty($form_state['executed'])) {
-      $item->name = $form_state['values']['name'];
-      $item->human_name = $form_state['values']['human_name'];
-      $item->vid = NULL;
-      views_ui_cache_set($item);
-
-      drupal_goto(ctools_export_ui_plugin_menu_path($this->plugin, 'edit', $item->name));
-    }
-
-    return $output;
-  }
-
-  function add_template_page($js, $input, $name, $step = NULL) {
-    $templates = views_get_all_templates();
-
-    if (empty($templates[$name])) {
-      return MENU_NOT_FOUND;
-    }
-
-    $template = $templates[$name];
-
-    // The template description probably describes the template, not the
-    // view that will be created from it, but users aren't that likely to
-    // touch it.
-    if (!empty($template->description)) {
-      unset($template->description);
-    }
-
-    $template->is_template = TRUE;
-    $template->type = t('Default');
-
-    $output = $this->clone_page($js, $input, $template, $step);
-    drupal_set_title(t('Create view from template @template', array('@template' => $template->get_human_name())));
-    return $output;
-  }
-
-  function set_item_state($state, $js, $input, $item) {
-    ctools_export_set_object_status($item, $state);
-    menu_router_rebuild();
-
-    if (!$js) {
-      drupal_goto(ctools_export_ui_plugin_base_path($this->plugin));
-    }
-    else {
-      return $this->list_page($js, $input);
-    }
-  }
-
-  function list_page($js, $input) {
-    // wrap output in a div for CSS
-    $output = parent::list_page($js, $input);
-    if (is_string($output)) {
-      $output = '<div id="views-ui-list-page">' . $output . '</div>';
-      return $output;
-    }
-  }
-}
-
-/**
- * Form callback to edit an exportable item using the wizard
- *
- * This simply loads the object defined in the plugin and hands it off.
- */
-function views_ui_clone_form($form, &$form_state) {
-  $counter = 1;
-
-  if (!isset($form_state['item'])) {
-    $view = views_get_view($form_state['original name']);
-  }
-  else {
-    $view = $form_state['item'];
-  }
-  do {
-    if (empty($form_state['item']->is_template)) {
-      $name = format_plural($counter, 'Clone of', 'Clone @count of') . ' ' . $view->get_human_name();
-    }
-    else {
-      $name = $view->get_human_name();
-      if ($counter > 1) {
-        $name .= ' ' . $counter;
-      }
-    }
-    $counter++;
-    $machine_name = preg_replace('/[^a-z0-9_]+/', '_', drupal_strtolower($name));
-  } while (ctools_export_crud_load($form_state['plugin']['schema'], $machine_name));
-
-  $form['human_name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View name'),
-    '#default_value' => $name,
-    '#size' => 32,
-    '#maxlength' => 255,
-  );
-
-  $form['name'] = array(
-    '#title' => t('View name'),
-    '#type' => 'machine_name',
-    '#required' => TRUE,
-    '#maxlength' => 128,
-    '#size' => 128,
-    '#machine_name' => array(
-      'exists' => 'ctools_export_ui_edit_name_exists',
-      'source' => array('human_name'),
-    ),
-  );
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Continue'),
-  );
-
-  return $form;
-}
diff --git a/plugins/export_ui/views_ui.inc b/plugins/export_ui/views_ui.inc
deleted file mode 100644
index 042fc79..0000000
--- a/plugins/export_ui/views_ui.inc
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Plugin definition for CTools Export UI integration.
- */
-
-$plugin = array(
-  'schema' => 'views_view',
-  'access' => 'administer views',
-
-  'menu' => array(
-    'menu item' => 'views',
-    'menu title' => 'Views',
-    'menu description' => 'Manage customized lists of content.',
-  ),
-
-  'title singular' => t('view'),
-  'title singular proper' => t('View'),
-  'title plural' => t('views'),
-  'title plural proper' => t('Views'),
-
-  'handler' => 'views_ui',
-
-  'strings' => array(
-    'confirmation' => array(
-      'revert' => array(
-        'information' => t('This action will permanently remove any customizations made to this view.'),
-        'success' => t('The view has been reverted.'),
-      ),
-      'delete' => array(
-        'information' => t('This action will permanently remove the view from your database.'),
-        'success' => t('The view has been deleted.'),
-      ),
-    ),
-  ),
-);
diff --git a/plugins/views_plugin_access.inc b/plugins/views_plugin_access.inc
deleted file mode 100644
index 7f80d9b..0000000
--- a/plugins/views_plugin_access.inc
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_access.
- */
-
-/**
- * @defgroup views_access_plugins Views access plugins
- * @{
- * @todo.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The base plugin to handle access control.
- */
-class views_plugin_access extends views_plugin {
-  /**
-   * Initialize the plugin.
-   *
-   * @param $view
-   *   The view object.
-   * @param $display
-   *   The display handler.
-   */
-  function init(&$view, &$display) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    if (is_object($display->handler)) {
-      $options = $display->handler->get_option('access');
-      // Overlay incoming options on top of defaults
-      $this->unpack_options($this->options, $options);
-    }
-  }
-
-  /**
-   * Retrieve the options when this is a new access
-   * control plugin
-   */
-  function option_definition() { return array(); }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for validating options
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for submitting options
-   */
-  function options_submit(&$form, &$form_state) { }
-
-  /**
-   * Return a string to display as the clickable title for the
-   * access control.
-   */
-  function summary_title() {
-    return t('Unknown');
-  }
-
-  /**
-   * Determine if the current user has access or not.
-   */
-  function access($account) {
-    // default to no access control.
-    return TRUE;
-  }
-
-  /**
-   * Determine the access callback and arguments.
-   *
-   * This information will be embedded in the menu in order to reduce
-   * performance hits during menu item access testing, which happens
-   * a lot.
-   *
-   * @return an array; the first item should be the function to call,
-   *   and the second item should be an array of arguments. The first
-   *   item may also be TRUE (bool only) which will indicate no
-   *   access control.)
-   */
-  function get_access_callback() {
-    // default to no access control.
-    return TRUE;
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_access_none.inc b/plugins/views_plugin_access_none.inc
deleted file mode 100644
index d69fe8e..0000000
--- a/plugins/views_plugin_access_none.inc
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_access_none.
- */
-
-/**
- * Access plugin that provides no access control at all.
- *
- * @ingroup views_access_plugins
- */
-class views_plugin_access_none extends views_plugin_access {
-  function summary_title() {
-    return t('Unrestricted');
-  }
-}
diff --git a/plugins/views_plugin_access_perm.inc b/plugins/views_plugin_access_perm.inc
deleted file mode 100644
index ec174bf..0000000
--- a/plugins/views_plugin_access_perm.inc
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_access_perm.
- */
-
-/**
- * Access plugin that provides permission-based access control.
- *
- * @ingroup views_access_plugins
- */
-class views_plugin_access_perm extends views_plugin_access {
-  function access($account) {
-    return views_check_perm($this->options['perm'], $account);
-  }
-
-  function get_access_callback() {
-    return array('views_check_perm', array($this->options['perm']));
-  }
-
-  function summary_title() {
-    $permissions = module_invoke_all('permission');
-    if (isset($permissions[$this->options['perm']])) {
-      return $permissions[$this->options['perm']]['title'];
-    }
-
-    return t($this->options['perm']);
-  }
-
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['perm'] = array('default' => 'access content');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $perms = array();
-    $module_info = system_get_info('module');
-
-    // Get list of permissions
-    foreach (module_implements('permission') as $module) {
-      $permissions = module_invoke($module, 'permission');
-      foreach ($permissions as $name => $perm) {
-        $perms[$module_info[$module]['name']][$name] = strip_tags($perm['title']);
-      }
-    }
-
-    asort($perms);
-
-    $form['perm'] = array(
-      '#type' => 'select',
-      '#options' => $perms,
-      '#title' => t('Permission'),
-      '#default_value' => $this->options['perm'],
-      '#description' => t('Only users with the selected permission flag will be able to access this display. Note that users with "access all views" can see any view, regardless of other permissions.'),
-    );
-  }
-}
diff --git a/plugins/views_plugin_access_role.inc b/plugins/views_plugin_access_role.inc
deleted file mode 100644
index b06812e..0000000
--- a/plugins/views_plugin_access_role.inc
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_access_role.
- */
-
-/**
- * Access plugin that provides role-based access control.
- *
- * @ingroup views_access_plugins
- */
-class views_plugin_access_role extends views_plugin_access {
-  function access($account) {
-    return views_check_roles(array_filter($this->options['role']), $account);
-  }
-
-  function get_access_callback() {
-    return array('views_check_roles', array(array_filter($this->options['role'])));
-  }
-
-  function summary_title() {
-    $count = count($this->options['role']);
-    if ($count < 1) {
-      return t('No role(s) selected');
-    }
-    elseif ($count > 1) {
-      return t('Multiple roles');
-    }
-    else {
-      $rids = views_ui_get_roles();
-      $rid = reset($this->options['role']);
-      return check_plain($rids[$rid]);
-    }
-  }
-
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['role'] = array('default' => array());
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['role'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Role'),
-      '#default_value' => $this->options['role'],
-      '#options' => array_map('check_plain', views_ui_get_roles()),
-      '#description' => t('Only the checked roles will be able to access this display. Note that users with "access all views" can see any view, regardless of role.'),
-    );
-  }
-
-  function options_validate(&$form, &$form_state) {
-    if (!array_filter($form_state['values']['access_options']['role'])) {
-      form_error($form['role'], t('You must select at least one role if type is "by role"'));
-    }
-  }
-
-  function options_submit(&$form, &$form_state) {
-    // I hate checkboxes.
-    $form_state['values']['access_options']['role'] = array_filter($form_state['values']['access_options']['role']);
-  }
-}
diff --git a/plugins/views_plugin_argument_default.inc b/plugins/views_plugin_argument_default.inc
deleted file mode 100644
index 2b87730..0000000
--- a/plugins/views_plugin_argument_default.inc
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_argument_default.
- */
-
-/**
- * @defgroup views_argument_default_plugins Views argument default plugins
- * @{
- * Allow specialized methods of filling in arguments when they aren't provided.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The fixed argument default handler; also used as the base.
- */
-class views_plugin_argument_default extends views_plugin {
-  /**
-   * Return the default argument.
-   *
-   * This needs to be overridden by every default argument handler to properly do what is needed.
-   */
-  function get_argument() { }
-
-  /**
-   * Initialize this plugin with the view and the argument
-   * it is linked to.
-   */
-  function init(&$view, &$argument, $options) {
-    $this->view = &$view;
-    $this->argument = &$argument;
-
-    $this->convert_options($options);
-    $this->unpack_options($this->options, $options);
-  }
-
-  /**
-   * Retrieve the options when this is a new access
-   * control plugin
-   */
-  function option_definition() { return array(); }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for validating options
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for submitting options
-   */
-  function options_submit(&$form, &$form_state, &$options = array()) { }
-
-  /**
-   * Determine if the administrator has the privileges to use this
-   * plugin
-   */
-  function access() { return TRUE; }
-
-  /**
-   * If we don't have access to the form but are showing it anyway, ensure that
-   * the form is safe and cannot be changed from user input.
-   *
-   * This is only called by child objects if specified in the options_form(),
-   * so it will not always be used.
-   */
-  function check_access(&$form, $option_name) {
-    if (!$this->access()) {
-      $form[$option_name]['#disabled'] = TRUE;
-      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
-      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default filter type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
-    }
-  }
-
-  /**
-   * Convert options from the older style.
-   *
-   * In Views 3, the method of storing default argument options has changed
-   * and each plugin now gets its own silo. This method can be used to
-   * move arguments from the old style to the new style. See
-   * views_plugin_argument_default_fixed for a good example of this method.
-   */
-  function convert_options(&$options) { }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_argument_default_fixed.inc b/plugins/views_plugin_argument_default_fixed.inc
deleted file mode 100644
index 38ede34..0000000
--- a/plugins/views_plugin_argument_default_fixed.inc
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the fixed argument default plugin.
- */
-
-/**
- * The fixed argument default handler.
- *
- * @ingroup views_argument_default_plugins
- */
-class views_plugin_argument_default_fixed extends views_plugin_argument_default {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['argument'] = array('default' => '');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['argument'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Fixed value'),
-      '#default_value' => $this->options['argument'],
-    );
-  }
-
-  /**
-   * Return the default argument.
-   */
-  function get_argument() {
-    return $this->options['argument'];
-  }
-
-  function convert_options(&$options) {
-    if (!isset($options['argument']) && isset($this->argument->options['default_argument_fixed'])) {
-      $options['argument'] = $this->argument->options['default_argument_fixed'];
-    }
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_argument_default_php.inc b/plugins/views_plugin_argument_default_php.inc
deleted file mode 100644
index c2fb14f..0000000
--- a/plugins/views_plugin_argument_default_php.inc
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the php code argument default plugin.
- */
-
-/**
- * Default argument plugin to provide a PHP code block.
- *
- * @ingroup views_argument_default_plugins
- */
-class views_plugin_argument_default_php extends views_plugin_argument_default {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['code'] = array('default' => '');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['code'] = array(
-      '#type' => 'textarea',
-      '#title' => t('PHP contextual filter code'),
-      '#default_value' => $this->options['code'],
-      '#description' => t('Enter PHP code that returns a value to use for this filter. Do not use &lt;?php ?&gt;. You must return only a single value for just this filter. Some variables are available: the view object will be "$view". The argument handler will be "$argument", for example you may change the title used for substitutions for this argument by setting "argument->validated_title"".'),
-    );
-
-    // Only do this if using one simple standard form gadget
-    $this->check_access($form, 'code');
-  }
-
-  function convert_options(&$options) {
-    if (!isset($options['code']) && isset($this->argument->options['default_argument_php'])) {
-      $options['code'] = $this->argument->options['default_argument_php'];
-    }
-  }
-
-  /**
-   * Only let users with PHP block visibility permissions set/modify this
-   * default plugin.
-   */
-  function access() {
-    return user_access('use PHP for settings');
-  }
-
-  function get_argument() {
-    // set up variables to make it easier to reference during the argument.
-    $view = &$this->view;
-    $argument = &$this->argument;
-    ob_start();
-    $result = eval($this->options['code']);
-    ob_end_clean();
-    return $result;
-  }
-}
diff --git a/plugins/views_plugin_argument_default_raw.inc b/plugins/views_plugin_argument_default_raw.inc
deleted file mode 100644
index 385ca91..0000000
--- a/plugins/views_plugin_argument_default_raw.inc
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the raw value argument default plugin.
- */
-
-/**
- * Default argument plugin to use the raw value from the URL.
- *
- * @ingroup views_argument_default_plugins
- */
-class views_plugin_argument_default_raw extends views_plugin_argument_default {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['index'] = array('default' => '');
-    $options['use_alias'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    // Using range(1, 10) will create an array keyed 0-9, which allows arg() to
-    // properly function since it is also zero-based.
-    $form['index'] = array(
-      '#type' => 'select',
-      '#title' => t('Path component'),
-      '#default_value' => $this->options['index'],
-      '#options' => range(1, 10),
-      '#description' => t('The numbering starts from 1, e.g. on the page admin/structure/types, the 3rd path component is "types".'),
-    );
-    $form['use_alias'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use path alias'),
-      '#default_value' => $this->options['use_alias'],
-      '#description' => t('Use path alias instead of internal path.'),
-    );
-  }
-
-  function get_argument() {
-    $path = NULL;
-    if ($this->options['use_alias']) {
-      $path = drupal_get_path_alias();
-    }
-    if ($arg = arg($this->options['index'], $path)) {
-      return $arg;
-    }
-  }
-}
diff --git a/plugins/views_plugin_argument_validate.inc b/plugins/views_plugin_argument_validate.inc
deleted file mode 100644
index 07b49ee..0000000
--- a/plugins/views_plugin_argument_validate.inc
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the base argument validator plugin.
- */
-
-/**
- * @defgroup views_argument_validate_plugins Views argument validate plugins
- * @{
- * Allow specialized methods of validating arguments.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * Base argument validator plugin to provide basic functionality.
- */
-class views_plugin_argument_validate extends views_plugin {
-
-  /**
-   * Initialize this plugin with the view and the argument
-   * it is linked to.
-   */
-  function init(&$view, &$argument, $options) {
-    $this->view = &$view;
-    $this->argument = &$argument;
-
-    $this->convert_options($options);
-    $this->unpack_options($this->options, $options);
-  }
-
-  /**
-   * Retrieve the options when this is a new access
-   * control plugin
-   */
-  function option_definition() { return array(); }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for validating options
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for submitting options
-   */
-  function options_submit(&$form, &$form_state, &$options = array()) { }
-
-  /**
-   * Convert options from the older style.
-   *
-   * In Views 3, the method of storing default argument options has changed
-   * and each plugin now gets its own silo. This method can be used to
-   * move arguments from the old style to the new style. See
-   * views_plugin_argument_default_fixed for a good example of this method.
-   */
-  function convert_options(&$options) { }
-
-  /**
-   * Determine if the administrator has the privileges to use this plugin
-   */
-  function access() { return TRUE; }
-
-  /**
-   * If we don't have access to the form but are showing it anyway, ensure that
-   * the form is safe and cannot be changed from user input.
-   *
-   * This is only called by child objects if specified in the options_form(),
-   * so it will not always be used.
-   */
-  function check_access(&$form, $option_name) {
-    if (!$this->access()) {
-      $form[$option_name]['#disabled'] = TRUE;
-      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
-      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default filter type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
-    }
-  }
-
-  function validate_argument($arg) { return TRUE; }
-
-  /**
-   * Process the summary arguments for displaying.
-   *
-   * Some plugins alter the argument so it uses something else interal.
-   * For example the user validation set's the argument to the uid,
-   * for a faster query. But there are use cases where you want to use
-   * the old value again, for example the summary.
-   */
-  function process_summary_arguments(&$args) { }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_argument_validate_numeric.inc b/plugins/views_plugin_argument_validate_numeric.inc
deleted file mode 100644
index 049531b..0000000
--- a/plugins/views_plugin_argument_validate_numeric.inc
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the numeric argument validator plugin.
- */
-
-/**
- * Validate whether an argument is numeric or not.
- *
- * @ingroup views_argument_validate_plugins
- */
-class views_plugin_argument_validate_numeric extends views_plugin_argument_validate {
-  function validate_argument($argument) {
-    return is_numeric($argument);
-  }
-}
diff --git a/plugins/views_plugin_argument_validate_php.inc b/plugins/views_plugin_argument_validate_php.inc
deleted file mode 100644
index 83b22b4..0000000
--- a/plugins/views_plugin_argument_validate_php.inc
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the php code argument validator plugin.
- */
-
-/**
- * Provide PHP code to validate whether or not an argument is ok.
- *
- * @ingroup views_argument_validate_plugins
- */
-class views_plugin_argument_validate_php extends views_plugin_argument_validate {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['code'] = array('default' => '');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['code'] = array(
-      '#type' => 'textarea',
-      '#title' => t('PHP validate code'),
-      '#default_value' => $this->options['code'],
-      '#description' => t('Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use &lt;?php ?&gt;. The argument to validate will be "$argument" and the view will be "$view". You may change the argument by setting "$handler->argument". You may change the title used for substitutions for this argument by setting "$handler->validated_title".'),
-    );
-
-    $this->check_access($form, 'code');
-  }
-
-  /**
-   * Only let users with PHP block visibility permissions set/modify this
-   * validate plugin.
-   */
-  function access() {
-    return user_access('use PHP for settings');
-  }
-
-  function convert_options(&$options) {
-    if (!isset($options['code']) && isset($this->argument->options['validate_argument_php'])) {
-      $options['code'] = $this->argument->options['validate_argument_php'];
-    }
-  }
-
-  function validate_argument($argument) {
-    // set up variables to make it easier to reference during the argument.
-    $view = &$this->view;
-    $handler = &$this->argument;
-
-    ob_start();
-    $result = eval($this->options['code']);
-    ob_end_clean();
-    return $result;
-  }
-}
diff --git a/plugins/views_plugin_cache.inc b/plugins/views_plugin_cache.inc
deleted file mode 100644
index 5a804b8..0000000
--- a/plugins/views_plugin_cache.inc
+++ /dev/null
@@ -1,322 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_cache.
- */
-
-/**
- * @defgroup views_cache_plugins Views cache plugins
- * @{
- * @todo.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The base plugin to handle caching.
- */
-class views_plugin_cache extends views_plugin {
-  /**
-   * Contains all data that should be written/read from cache.
-   */
-  var $storage = array();
-
-  /**
-   * What table to store data in.
-   */
-  var $table = 'cache_views_data';
-
-  /**
-   * Stores the cache id used for the results cache, once get_results_key() got
-   * executed.
-   *
-   * @see views_plugin_cache::get_results_key
-   * @var string
-   */
-  public $_results_key;
-
-  /**
-   * Stores the cache id used for the output cache, once get_output_key() got
-   * executed.
-   *
-   * @see views_plugin_cache::get_output_key
-   * @var string
-   */
-  public $_output_key;
-
-  /**
-   * Initialize the plugin.
-   *
-   * @param $view
-   *   The view object.
-   * @param $display
-   *   The display handler.
-   */
-  function init(&$view, &$display) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    if (is_object($display->handler)) {
-      $options = $display->handler->get_option('cache');
-      // Overlay incoming options on top of defaults
-      $this->unpack_options($this->options, $options);
-    }
-  }
-
-  /**
-   * Return a string to display as the clickable title for the
-   * access control.
-   */
-  function summary_title() {
-    return t('Unknown');
-  }
-
-  /**
-   * Determine the expiration time of the cache type, or NULL if no expire.
-   *
-   * Plugins must override this to implement expiration.
-   *
-   * @param $type
-   *   The cache type, either 'query', 'result' or 'output'.
-   */
-   function cache_expire($type) { }
-
-   /**
-    * Determine expiration time in the cache table of the cache type
-    * or CACHE_PERMANENT if item shouldn't be removed automatically from cache.
-    *
-    * Plugins must override this to implement expiration in the cache table.
-    *
-    * @param $type
-    *   The cache type, either 'query', 'result' or 'output'.
-    */
-  function cache_set_expire($type) {
-    return CACHE_PERMANENT;
-  }
-
-
-  /**
-   * Save data to the cache.
-   *
-   * A plugin should override this to provide specialized caching behavior.
-   */
-  function cache_set($type) {
-    switch ($type) {
-      case 'query':
-        // Not supported currently, but this is certainly where we'd put it.
-        break;
-      case 'results':
-        $data = array(
-          'result' => $this->view->result,
-          'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0,
-          'current_page' => $this->view->get_current_page(),
-        );
-        cache($this->table)->set($this->get_results_key(), $data, $this->cache_set_expire($type));
-        break;
-      case 'output':
-        $this->gather_headers();
-        $this->storage['output'] = $this->view->display_handler->output;
-        cache($this->table)->set($this->get_output_key(), $this->storage, $this->cache_set_expire($type));
-        break;
-    }
-  }
-
-
-  /**
-   * Retrieve data from the cache.
-   *
-   * A plugin should override this to provide specialized caching behavior.
-   */
-  function cache_get($type) {
-    $cutoff = $this->cache_expire($type);
-    switch ($type) {
-      case 'query':
-        // Not supported currently, but this is certainly where we'd put it.
-        return FALSE;
-      case 'results':
-        // Values to set: $view->result, $view->total_rows, $view->execute_time,
-        // $view->current_page.
-        if ($cache = cache($this->table)->get($this->get_results_key())) {
-          if (!$cutoff || $cache->created > $cutoff) {
-            $this->view->result = $cache->data['result'];
-            $this->view->total_rows = $cache->data['total_rows'];
-            $this->view->set_current_page($cache->data['current_page']);
-            $this->view->execute_time = 0;
-            return TRUE;
-          }
-        }
-        return FALSE;
-      case 'output':
-        if ($cache = cache($this->table)->get($this->get_output_key())) {
-          if (!$cutoff || $cache->created > $cutoff) {
-            $this->storage = $cache->data;
-            $this->view->display_handler->output = $cache->data['output'];
-            $this->restore_headers();
-            return TRUE;
-          }
-        }
-        return FALSE;
-    }
-  }
-
-  /**
-   * Clear out cached data for a view.
-   *
-   * We're just going to nuke anything related to the view, regardless of display,
-   * to be sure that we catch everything. Maybe that's a bad idea.
-   */
-  function cache_flush() {
-    cache($this->table)->deletePrefix($this->view->name . ':');
-  }
-
-  /**
-   * Post process any rendered data.
-   *
-   * This can be valuable to be able to cache a view and still have some level of
-   * dynamic output. In an ideal world, the actual output will include HTML
-   * comment based tokens, and then the post process can replace those tokens.
-   *
-   * Example usage. If it is known that the view is a node view and that the
-   * primary field will be a nid, you can do something like this:
-   *
-   * <!--post-FIELD-NID-->
-   *
-   * And then in the post render, create an array with the text that should
-   * go there:
-   *
-   * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1');
-   *
-   * All of the cached result data will be available in $view->result, as well,
-   * so all ids used in the query should be discoverable.
-   */
-  function post_render(&$output) { }
-
-  /**
-   * Start caching javascript, css and other out of band info.
-   *
-   * This takes a snapshot of the current system state so that we don't
-   * duplicate it. Later on, when gather_headers() is run, this information
-   * will be removed so that we don't hold onto it.
-   */
-  function cache_start() {
-    $this->storage['head'] = drupal_add_html_head();
-    $this->storage['css'] = drupal_add_css();
-    $this->storage['js'] = drupal_add_js();
-  }
-
-  /**
-   * Gather out of band data, compare it to what we started with and store the difference.
-   */
-  function gather_headers() {
-    // Simple replacement for head
-    if (isset($this->storage['head'])) {
-      $this->storage['head'] = str_replace($this->storage['head'], '', drupal_add_html_head());
-    }
-    else {
-      $this->storage['head'] = '';
-    }
-
-    // Slightly less simple for CSS:
-    $css = drupal_add_css();
-    $css_start = isset($this->storage['css']) ? $this->storage['css'] : array();
-    $this->storage['css'] = array_diff_assoc($css, $css_start);
-
-    // Get javascript after/before views renders.
-    $js = drupal_add_js();
-    $js_start = isset($this->storage['js']) ? $this->storage['js'] : array();
-    // If there are any differences between the old and the new javascript then
-    // store them to be added later.
-    $this->storage['js'] = array_diff_assoc($js, $js_start);
-
-    // Special case the settings key and get the difference of the data.
-    $settings = isset($js['settings']['data']) ? $js['settings']['data'] : array();
-    $settings_start = isset($js_start['settings']['data']) ? $js_start['settings']['data'] : array();
-    $this->storage['js']['settings'] = array_diff_assoc($settings, $settings_start);
-  }
-
-  /**
-   * Restore out of band data saved to cache. Copied from Panels.
-   */
-  function restore_headers() {
-    if (!empty($this->storage['head'])) {
-      drupal_add_html_head($this->storage['head']);
-    }
-    if (!empty($this->storage['css'])) {
-      foreach ($this->storage['css'] as $args) {
-        drupal_add_css($args['data'], $args);
-      }
-    }
-    if (!empty($this->storage['js'])) {
-      foreach ($this->storage['js'] as $key => $args) {
-        if ($key != 'settings') {
-          drupal_add_js($args['data'], $args);
-        }
-        else {
-          foreach ($args as $setting) {
-            drupal_add_js($setting, 'setting');
-          }
-        }
-      }
-    }
-  }
-
-  function get_results_key() {
-    global $user;
-
-    if (!isset($this->_results_key)) {
-
-      $build_info = $this->view->build_info;
-
-      $query_plugin = $this->view->display_handler->get_plugin('query');
-
-      foreach (array('query','count_query') as $index) {
-        // If the default query back-end is used generate SQL query strings from
-        // the query objects.
-        if ($build_info[$index] instanceof Drupal\Core\Database\Query\Select) {
-          $query = clone $build_info[$index];
-          $query->preExecute();
-          $build_info[$index] = (string)$query;
-        }
-      }
-      $key_data = array(
-        'build_info' => $build_info,
-        'roles' => array_keys($user->roles),
-        'super-user' => $user->uid == 1, // special caching for super user.
-        'language' => drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode,
-        'base_url' => $GLOBALS['base_url'],
-      );
-      foreach (array('exposed_info', 'page', 'sort', 'order', 'items_per_page', 'offset') as $key) {
-        if (isset($_GET[$key])) {
-          $key_data[$key] = $_GET[$key];
-        }
-      }
-
-      $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . md5(serialize($key_data));
-    }
-
-    return $this->_results_key;
-  }
-
-  function get_output_key() {
-    global $user;
-    if (!isset($this->_output_key)) {
-      $key_data = array(
-        'result' => $this->view->result,
-        'roles' => array_keys($user->roles),
-        'super-user' => $user->uid == 1, // special caching for super user.
-        'theme' => $GLOBALS['theme'],
-        'language' => drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode,
-        'base_url' => $GLOBALS['base_url'],
-      );
-
-      $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . md5(serialize($key_data));
-    }
-
-    return $this->_output_key;
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_cache_none.inc b/plugins/views_plugin_cache_none.inc
deleted file mode 100644
index 9927a9d..0000000
--- a/plugins/views_plugin_cache_none.inc
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_cache_none.
- */
-
-/**
- * Caching plugin that provides no caching at all.
- *
- * @ingroup views_cache_plugins
- */
-class views_plugin_cache_none extends views_plugin_cache {
-  function cache_start() { /* do nothing */ }
-
-  function summary_title() {
-    return t('None');
-  }
-
-  function cache_get($type) {
-    return FALSE;
-  }
-
-  function cache_set($type) { }
-}
diff --git a/plugins/views_plugin_cache_time.inc b/plugins/views_plugin_cache_time.inc
deleted file mode 100644
index 3bce56e..0000000
--- a/plugins/views_plugin_cache_time.inc
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_cache_time.
- */
-
-/**
- * Simple caching of query results for Views displays.
- *
- * @ingroup views_cache_plugins
- */
-class views_plugin_cache_time extends views_plugin_cache {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['results_lifespan'] = array('default' => 3600);
-    $options['results_lifespan_custom'] = array('default' => 0);
-    $options['output_lifespan'] = array('default' => 3600);
-    $options['output_lifespan_custom'] = array('default' => 0);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $options = array(60, 300, 1800, 3600, 21600, 518400);
-    $options = drupal_map_assoc($options, 'format_interval');
-    $options = array(-1 => t('Never cache')) + $options + array('custom' => t('Custom'));
-
-    $form['results_lifespan'] = array(
-      '#type' => 'select',
-      '#title' => t('Query results'),
-      '#description' => t('The length of time raw query results should be cached.'),
-      '#options' => $options,
-      '#default_value' => $this->options['results_lifespan'],
-    );
-    $form['results_lifespan_custom'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Seconds'),
-      '#size' => '25',
-      '#maxlength' => '30',
-      '#description' => t('Length of time in seconds raw query results should be cached.'),
-      '#default_value' => $this->options['results_lifespan_custom'],
-      '#states' => array(
-        'visible' => array(
-          ':input[name="cache_options[results_lifespan]"]' => array('value' => 'custom'),
-        ),
-      ),
-    );
-    $form['output_lifespan'] = array(
-      '#type' => 'select',
-      '#title' => t('Rendered output'),
-      '#description' => t('The length of time rendered HTML output should be cached.'),
-      '#options' => $options,
-      '#default_value' => $this->options['output_lifespan'],
-    );
-    $form['output_lifespan_custom'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Seconds'),
-      '#size' => '25',
-      '#maxlength' => '30',
-      '#description' => t('Length of time in seconds rendered HTML output should be cached.'),
-      '#default_value' => $this->options['output_lifespan_custom'],
-      '#states' => array(
-        'visible' => array(
-          ':input[name="cache_options[output_lifespan]"]' => array('value' => 'custom'),
-        ),
-      ),
-    );
-  }
-
-  function options_validate(&$form, &$form_state) {
-    $custom_fields = array('output_lifespan', 'results_lifespan');
-    foreach ($custom_fields as $field) {
-      if ($form_state['values']['cache_options'][$field] == 'custom' && !is_numeric($form_state['values']['cache_options'][$field . '_custom'])) {
-        form_error($form[$field .'_custom'], t('Custom time values must be numeric.'));
-      }
-    }
-  }
-
-  function summary_title() {
-    $results_lifespan = $this->get_lifespan('results');
-    $output_lifespan = $this->get_lifespan('output');
-    return format_interval($results_lifespan, 1) . '/' . format_interval($output_lifespan, 1);
-  }
-
-  function get_lifespan($type) {
-    $lifespan = $this->options[$type . '_lifespan'] == 'custom' ? $this->options[$type . '_lifespan_custom'] : $this->options[$type . '_lifespan'];
-    return $lifespan;
-  }
-
-  function cache_expire($type) {
-    $lifespan = $this->get_lifespan($type);
-    if ($lifespan) {
-      $cutoff = REQUEST_TIME - $lifespan;
-      return $cutoff;
-    }
-    else {
-      return FALSE;
-    }
-  }
-
-  function cache_set_expire($type) {
-    $lifespan = $this->get_lifespan($type);
-    if ($lifespan) {
-      return time() + $lifespan;
-    }
-    else {
-      return CACHE_PERMANENT;
-    }
-  }
-}
diff --git a/plugins/views_plugin_display.inc b/plugins/views_plugin_display.inc
deleted file mode 100644
index 97e3660..0000000
--- a/plugins/views_plugin_display.inc
+++ /dev/null
@@ -1,3038 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the base display plugin.
- */
-
-use Drupal\views\View;
-
-/**
- * @defgroup views_display_plugins Views display plugins
- * @{
- * Display plugins control how Views interact with the rest of Drupal.
- *
- * They can handle creating Views from a Drupal page hook; they can
- * handle creating Views from a Drupal block hook. They can also
- * handle creating Views from an external module source, such as
- * a Panels pane, or an insert view, or a CCK field type.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The default display plugin handler. Display plugins handle options and
- * basic mechanisms for different output methods.
- */
-class views_plugin_display extends views_plugin {
-  /**
-   * The top object of a view.
-   *
-   * @var view
-   */
-  var $view = NULL;
-
-  var $handlers = array();
-
-  /**
-   * Stores all available display extenders.
-   */
-  var $extender = array();
-
-  /**
-   * Stores the rendered output of the display.
-   *
-   * @see View::render
-   * @var string
-   */
-  public $output = NULL;
-
-  function init(&$view, &$display, $options = NULL) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    // Load extenders as soon as possible.
-    $this->extender = array();
-    $extenders = views_get_enabled_display_extenders();
-    // If you update to the dev version the registry might not be loaded yet.
-    if (!empty($extenders) && class_exists('views_plugin_display_extender')) {
-      foreach ($extenders as $extender) {
-        $plugin = views_get_plugin('display_extender', $extender);
-        if ($plugin) {
-          $plugin->init($this->view, $this);
-          $this->extender[$extender] = $plugin;
-        }
-        else {
-          vpr('Invalid display extender @extender', array('@handler' => $extender));
-        }
-      }
-    }
-
-    // Track changes that the user should know about.
-    $changed = FALSE;
-
-    // Make some modifications:
-    if (!isset($options) && isset($display->display_options)) {
-      $options = $display->display_options;
-    }
-
-    if ($this->is_default_display() && isset($options['defaults'])) {
-      unset($options['defaults']);
-    }
-
-    // Cache for unpack_options, but not if we are in the ui.
-    static $unpack_options = array();
-    if (empty($view->editing)) {
-      $cid = 'unpack_options:' . md5(serialize(array($this->options, $options)));
-      if (empty($unpack_options[$cid])) {
-        $cache = views_cache_get($cid, TRUE);
-        if (!empty($cache->data)) {
-          $this->options = $cache->data;
-        }
-        else {
-          $this->unpack_options($this->options, $options);
-          views_cache_set($cid, $this->options, TRUE);
-        }
-        $unpack_options[$cid] = $this->options;
-      }
-      else {
-        $this->options = $unpack_options[$cid];
-      }
-    }
-    else {
-      $this->unpack_options($this->options, $options);
-    }
-
-    // Translate changed settings:
-    $items_per_page = $this->get_option('items_per_page');
-    $offset = $this->get_option('offset');
-    $use_pager = $this->get_option('use_pager');
-    $pager = $this->get_option('pager');
-    // Check if the pager options were already converted.
-    // The pager settings of a Views 2.x view specifying 10 items with an
-    // offset of 0 and no pager is the same as of a Views 3.x view with
-    // default settings. In this case, the only way to determine which case we
-    // are dealing with is checking the API version but that's only available
-    // for exported Views as it's not stored in the database.
-    // If you would like to change this code, really take care that you thought
-    // of every possibility.
-    // @TODO: Provide a way to convert the database views as well.
-    if (((!empty($items_per_page) && $items_per_page != 10) || !empty($offset) || !empty($use_pager))
-      || (!empty($view->api_version) && $view->api_version == 2)) {
-      // Find out the right pager type.
-      // If the view "use pager" it's a normal/full pager.
-      if ($use_pager) {
-        $type = 'full';
-      }
-      // If it does not use pager, but 0 items per page it should not page
-      // else it should display just a certain amount of items.
-      else {
-        $type = $items_per_page ? 'some' : 'none';
-      }
-
-      // Setup the pager options.
-      $pager = array(
-        'type' => $type,
-        'options' => array(
-          'offset' => intval($offset)
-        ),
-      );
-
-      if ($items_per_page) {
-        $pager['options']['items_per_page'] = $items_per_page;
-      }
-      // Setup the pager element.
-      if ($id = $this->get_option('pager_element')) {
-        $pager['options']['id'] = $id;
-      }
-
-      // Unset the previous options
-      // After edit and save the view they will be erased
-      $this->set_option('items_per_page', NULL);
-      $this->set_option('offset', NULL);
-      $this->set_option('use_pager', NULL);
-      $this->set_option('pager', $pager);
-      $changed = TRUE;
-    }
-
-
-    // Plugable headers, footer and empty texts are
-    // not compatible with previous version of views
-    // This code converts old values into a configured handler for each area
-    foreach (array('header', 'footer', 'empty') as $area) {
-      $converted = FALSE;
-      if (isset($this->options[$area]) && !is_array($this->options[$area])) {
-        if (!empty($this->options[$area])) {
-          $content = $this->get_option($area);
-          if (!empty($content) && !is_array($content)) {
-            $format = $this->get_option($area . '_format');
-            $options = array(
-              'id' => 'area',
-              'table' => 'views',
-              'field' => 'area',
-              'label' => '',
-              'relationship' => 'none',
-              'group_type' => 'group',
-              'content' => $content,
-              'format' => !empty($format) ? $format : filter_default_format(),
-            );
-
-            if ($area != 'empty' && $empty = $this->get_option($area . '_empty')) {
-              $options['empty'] = $empty;
-            }
-            $this->set_option($area, array('text' => $options));
-            $converted = TRUE;
-            $changed = TRUE;
-          }
-        }
-        // Ensure that options are at least an empty array
-        if (!$converted) {
-          $this->set_option($area, array());
-        }
-      }
-    }
-
-    // Convert distinct setting from display to query settings.
-    $distinct = $this->get_option('distinct');
-    if (!empty($distinct)) {
-      $query_settings = $this->get_option('query');
-      $query_settings['options']['distinct'] = $distinct;
-      $this->set_option('query', $query_settings);
-      // Clear the values
-      $this->set_option('distinct', NULL);
-      $changed = TRUE;
-    }
-
-    // Convert field language settings.
-    $query_options = $this->get_option('query');
-    if (isset($query_options['options']['field_language'])) {
-      $this->set_option('field_language', $query_options['options']['field_language']);
-      unset($query_options['options']['field_language']);
-      $changed = TRUE;
-    }
-    if (isset($query_options['options']['field_language_add_to_query'])) {
-      $this->set_option('field_language_add_to_query', $query_options['options']['field_language_add_to_query']);
-      unset($query_options['options']['field_language_add_to_query']);
-      $changed = TRUE;
-    }
-    $this->set_option('query', $query_options);
-
-    // Convert filter groups.
-    $filter_groups = $this->get_option('filter_groups');
-    // Only convert if it wasn't converted yet, which is the case if there is a 0 group.
-    if (isset($filter_groups['groups'][0])) {
-      // Update filter groups.
-      $filter_groups ['groups'] = views_array_key_plus($filter_groups['groups']);
-      $this->set_option('filter_groups', $filter_groups);
-      // Update the filter group on each filter.
-      $filters = $this->get_option('filters');
-      foreach ($filters as &$filter) {
-        if (isset($filter['group'])) {
-          $filter['group']++;
-        }
-        else {
-          $filter['group'] = 1;
-        }
-      }
-      $this->set_option('filters', $filters);
-      $changed = TRUE;
-    }
-
-    // Filter groups were allowed to be rewritten without its filters, so
-    // before this update the view was using the default values. To be sure that
-    // the existing view isn't broken, don't use this overridden values but copy
-    // them from the default display. Only do this if the filters are overridden
-    // but the filter_groups are not marked as so.
-    if (!$this->is_default_display() && !$this->options['defaults']['filters'] && $this->options['defaults']['filter_groups']) {
-      // Set filter_groups to be overridden and save the value in the
-      // display_options as well.
-      $this->options['defaults']['filter_groups'] = FALSE;
-      $this->display->display_options['defaults']['filter_groups'] = $this->options['defaults']['filter_groups'];
-      // Copy the filter_groups from the default, and add them to the
-      // display_options as well. $this->default_display is not initialized at
-      // this point.
-      $this->options['filter_groups'] = $this->view->display['default']->handler->options['filter_groups'];
-      $this->display->display_options['filter_groups'] = $this->options['filter_groups'];
-
-      $changed = TRUE;
-    }
-
-    // Mark the view as changed so the user has a chance to save it.
-    if ($changed) {
-      $this->view->changed = TRUE;
-    }
-  }
-
-  function destroy() {
-    parent::destroy();
-
-    foreach ($this->handlers as $type => $handlers) {
-      foreach ($handlers as $id => $handler) {
-        if (is_object($handler)) {
-          $this->handlers[$type][$id]->destroy();
-        }
-      }
-    }
-
-    if (isset($this->default_display)) {
-      unset($this->default_display);
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->destroy();
-    }
-  }
-
-  /**
-   * Determine if this display is the 'default' display which contains
-   * fallback settings
-   */
-  function is_default_display() { return FALSE; }
-
-  /**
-   * Determine if this display uses exposed filters, so the view
-   * will know whether or not to build them.
-   */
-  function uses_exposed() {
-    if (!isset($this->has_exposed)) {
-      foreach ($this->handlers as $type => $value) {
-        foreach ($this->view->$type as $id => $handler) {
-          if ($handler->can_expose() && $handler->is_exposed()) {
-            // one is all we need; if we find it, return true.
-            $this->has_exposed = TRUE;
-            return TRUE;
-          }
-        }
-      }
-      $pager = $this->get_plugin('pager');
-      if (isset($pager) && $pager->uses_exposed()) {
-        $this->has_exposed = TRUE;
-        return TRUE;
-      }
-      $this->has_exposed = FALSE;
-    }
-
-    return $this->has_exposed;
-  }
-
-  /**
-   * Determine if this display should display the exposed
-   * filters widgets, so the view will know whether or not
-   * to render them.
-   *
-   * Regardless of what this function
-   * returns, exposed filters will not be used nor
-   * displayed unless uses_exposed() returns TRUE.
-   */
-  function displays_exposed() {
-    return TRUE;
-  }
-
-  /**
-   * Does the display use AJAX?
-   */
-  function use_ajax() {
-    if (!empty($this->definition['use ajax'])) {
-      return $this->get_option('use_ajax');
-    }
-    return FALSE;
-  }
-
-  /**
-   * Does the display have a pager enabled?
-   */
-  function use_pager() {
-    $pager = $this->get_plugin('pager');
-    if ($pager) {
-      return $pager->use_pager();
-    }
-  }
-
-  /**
-   * Does the display have a more link enabled?
-   */
-  function use_more() {
-    if (!empty($this->definition['use more'])) {
-      return $this->get_option('use_more');
-    }
-    return FALSE;
-  }
-
-  /**
-   * Does the display have groupby enabled?
-   */
-  function use_group_by() {
-    return $this->get_option('group_by');
-  }
-
-  /**
-   * Should the enabled display more link be shown when no more items?
-   */
-  function use_more_always() {
-    if (!empty($this->definition['use more'])) {
-      return $this->get_option('use_more_always');
-    }
-    return FALSE;
-  }
-
-  /**
-   * Does the display have custom link text?
-   */
-  function use_more_text() {
-    if (!empty($this->definition['use more'])) {
-      return $this->get_option('use_more_text');
-    }
-    return FALSE;
-  }
-
-  /**
-   * Can this display accept attachments?
-   */
-  function accept_attachments() {
-    if (empty($this->definition['accept attachments'])) {
-      return FALSE;
-    }
-    if (!empty($this->view->argument) && $this->get_option('hide_attachment_summary')) {
-      foreach ($this->view->argument as $argument_id => $argument) {
-        if ($argument->needs_style_plugin() && empty($argument->argument_validated)) {
-          return FALSE;
-        }
-      }
-    }
-    return TRUE;
-  }
-
-  /**
-   * Allow displays to attach to other views.
-   */
-  function attach_to($display_id) { }
-
-  /**
-   * Static member function to list which sections are defaultable
-   * and what items each section contains.
-   */
-  function defaultable_sections($section = NULL) {
-    $sections = array(
-      'access' => array('access', 'access_options'),
-      'access_options' => array('access', 'access_options'),
-      'cache' => array('cache', 'cache_options'),
-      'cache_options' => array('cache', 'cache_options'),
-      'title' => array('title'),
-      'css_class' => array('css_class'),
-      'use_ajax' => array('use_ajax'),
-      'hide_attachment_summary' => array('hide_attachment_summary'),
-      'group_by' => array('group_by'),
-      'query' => array('query'),
-      'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
-      'link_display' => array('link_display', 'link_url'),
-
-      // Force these to cascade properly.
-      'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
-      'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
-      'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
-      'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
-
-      'pager' => array('pager', 'pager_options'),
-      'pager_options' => array('pager', 'pager_options'),
-
-      'exposed_form' => array('exposed_form', 'exposed_form_options'),
-      'exposed_form_options' => array('exposed_form', 'exposed_form_options'),
-
-      // These guys are special
-      'header' => array('header'),
-      'footer' => array('footer'),
-      'empty' => array('empty'),
-      'relationships' => array('relationships'),
-      'fields' => array('fields'),
-      'sorts' => array('sorts'),
-      'arguments' => array('arguments'),
-      'filters' => array('filters', 'filter_groups'),
-      'filter_groups' => array('filters', 'filter_groups'),
-    );
-
-    // If the display cannot use a pager, then we cannot default it.
-    if (empty($this->definition['use pager'])) {
-      unset($sections['pager']);
-      unset($sections['items_per_page']);
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->defaultable_sections($sections, $section);
-    }
-
-    if ($section) {
-      if (!empty($sections[$section])) {
-        return $sections[$section];
-      }
-    }
-    else {
-      return $sections;
-    }
-  }
-
-  function option_definition() {
-    $options = array(
-      'defaults' => array(
-        'default' => array(
-          'access' => TRUE,
-          'cache' => TRUE,
-          'query' => TRUE,
-          'title' => TRUE,
-          'css_class' => TRUE,
-
-          'display_description' => FALSE,
-          'use_ajax' => TRUE,
-          'hide_attachment_summary' => TRUE,
-          'pager' => TRUE,
-          'pager_options' => TRUE,
-          'use_more' => TRUE,
-          'use_more_always' => TRUE,
-          'use_more_text' => TRUE,
-          'exposed_form' => TRUE,
-          'exposed_form_options' => TRUE,
-
-          'link_display' => TRUE,
-          'link_url' => '',
-          'group_by' => TRUE,
-
-          'style_plugin' => TRUE,
-          'style_options' => TRUE,
-          'row_plugin' => TRUE,
-          'row_options' => TRUE,
-
-          'header' => TRUE,
-          'footer' => TRUE,
-          'empty' => TRUE,
-
-          'relationships' => TRUE,
-          'fields' => TRUE,
-          'sorts' => TRUE,
-          'arguments' => TRUE,
-          'filters' => TRUE,
-          'filter_groups' => TRUE,
-        ),
-        'export' => FALSE,
-      ),
-
-      'title' => array(
-        'default' => '',
-        'translatable' => TRUE,
-      ),
-      'enabled' => array(
-        'default' => TRUE,
-        'translatable' => FALSE,
-        'bool' => TRUE,
-      ),
-      'display_comment' => array(
-        'default' => '',
-      ),
-      'css_class' => array(
-        'default' => '',
-        'translatable' => FALSE,
-      ),
-      'display_description' => array(
-        'default' => '',
-        'translatable' => TRUE,
-      ),
-      'use_ajax' => array(
-        'default' => FALSE,
-        'bool' => TRUE,
-      ),
-      'hide_attachment_summary' => array(
-        'default' => FALSE,
-        'bool' => TRUE,
-      ),
-      // This is legacy code:
-      // Items_per/offset/use_pager is moved to the pager plugin
-      // but the automatic update path needs this items defined, so don't remove it.
-      // @see views_plugin_display::init()
-      'items_per_page' => array(
-        'default' => 10,
-      ),
-      'offset' => array(
-        'default' => 0,
-      ),
-      'use_pager' => array(
-        'default' => FALSE,
-        'bool' => TRUE,
-      ),
-      'use_more' => array(
-        'default' => FALSE,
-        'bool' => TRUE,
-      ),
-      'use_more_always' => array(
-        'default' => FALSE,
-        'bool' => FALSE,
-      ),
-      'use_more_text' => array(
-        'default' => 'more',
-        'translatable' => TRUE,
-      ),
-      'link_display' => array(
-        'default' => '',
-      ),
-      'link_url' => array(
-        'default' => '',
-      ),
-      'group_by' => array(
-        'default' => FALSE,
-        'bool' => TRUE,
-      ),
-      'field_language' => array(
-        'default' => '***CURRENT_LANGUAGE***',
-      ),
-      'field_language_add_to_query' => array(
-        'default' => 1,
-      ),
-
-      // These types are all plugins that can have individual settings
-      // and therefore need special handling.
-      'access' => array(
-        'contains' => array(
-          'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
-         ),
-      ),
-      'cache' => array(
-        'contains' => array(
-          'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
-         ),
-      ),
-      'query' => array(
-        'contains' => array(
-          'type' => array('default' => 'views_query', 'export' => 'export_plugin'),
-          'options' => array('default' => array(), 'export' => FALSE),
-         ),
-      ),
-      // Note that exposed_form plugin has options in a separate array,
-      // while access and cache do not. access and cache are legacy and
-      // that pattern should not be repeated, but it is left as is to
-      // reduce the need to modify older views. Let's consider the
-      // pattern used here to be the template from which future plugins
-      // should be copied.
-      'exposed_form' => array(
-        'contains' => array(
-          'type' => array('default' => 'basic', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
-          'options' => array('default' => array(), 'export' => FALSE),
-         ),
-      ),
-      'pager' => array(
-        'contains' => array(
-          'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
-          'options' => array('default' => array(), 'export' => FALSE),
-         ),
-      ),
-
-      // Note that the styles have their options completely independent.
-      // Like access and cache above, this is a legacy pattern and
-      // should not be repeated.
-      'style_plugin' => array(
-        'default' => 'default',
-        'export' => 'export_style',
-        'unpack_translatable' => 'unpack_style',
-      ),
-      'style_options' => array(
-        'default' => array(),
-        'export' => FALSE,
-      ),
-      'row_plugin' => array(
-        'default' => 'fields',
-        'export' => 'export_style',
-        'unpack_translatable' => 'unpack_style',
-      ),
-      'row_options' => array(
-        'default' => array(),
-        'export' => FALSE,
-      ),
-
-      'exposed_block' => array(
-        'default' => FALSE,
-      ),
-
-      'header' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-      'footer' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-      'empty' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-
-      // We want these to export last.
-      // These are the 5 handler types.
-      'relationships' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-
-      ),
-      'fields' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-      'sorts' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-      'arguments' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-      'filter_groups' => array(
-        'contains' => array(
-          'operator' => array('default' => 'AND'),
-          'groups' => array('default' => array(1 => 'AND')),
-        ),
-      ),
-      'filters' => array(
-        'default' => array(),
-        'export' => 'export_handler',
-        'unpack_translatable' => 'unpack_handler',
-      ),
-    );
-
-    if (empty($this->definition['use pager'])) {
-      $options['defaults']['default']['use_pager'] = FALSE;
-      $options['defaults']['default']['items_per_page'] = FALSE;
-      $options['defaults']['default']['offset'] = FALSE;
-      $options['defaults']['default']['pager'] = FALSE;
-      $options['pager']['contains']['type']['default'] = 'some';
-    }
-
-    if ($this->is_default_display()) {
-      unset($options['defaults']);
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->options_definition_alter($options);
-    }
-
-    return $options;
-  }
-
-  /**
-   * Check to see if the display has a 'path' field.
-   *
-   * This is a pure function and not just a setting on the definition
-   * because some displays (such as a panel pane) may have a path based
-   * upon configuration.
-   *
-   * By default, displays do not have a path.
-   */
-  function has_path() { return FALSE; }
-
-  /**
-   * Check to see if the display has some need to link to another display.
-   *
-   * For the most part, displays without a path will use a link display. However,
-   * sometimes displays that have a path might also need to link to another display.
-   * This is true for feeds.
-   */
-  function uses_link_display() { return !$this->has_path(); }
-
-  /**
-   * Check to see if the display can put the exposed formin a block.
-   *
-   * By default, displays that do not have a path cannot disconnect
-   * the exposed form and put it in a block, because the form has no
-   * place to go and Views really wants the forms to go to a specific
-   * page.
-   */
-  function uses_exposed_form_in_block() { return $this->has_path(); }
-
-  /**
-   * Check to see which display to use when creating links within
-   * a view using this display.
-   */
-  function get_link_display() {
-    $display_id = $this->get_option('link_display');
-    // If unknown, pick the first one.
-    if (empty($display_id) || empty($this->view->display[$display_id])) {
-      foreach ($this->view->display as $display_id => $display) {
-        if (!empty($display->handler) && $display->handler->has_path()) {
-          return $display_id;
-        }
-      }
-    }
-    else {
-      return $display_id;
-    }
-    // fall-through returns NULL
-  }
-
-  /**
-   * Return the base path to use for this display.
-   *
-   * This can be overridden for displays that do strange things
-   * with the path.
-   */
-  function get_path() {
-    if ($this->has_path()) {
-      return $this->get_option('path');
-    }
-
-    $display_id = $this->get_link_display();
-    if ($display_id && !empty($this->view->display[$display_id]) && is_object($this->view->display[$display_id]->handler)) {
-      return $this->view->display[$display_id]->handler->get_path();
-    }
-  }
-
-  function get_url() {
-    return $this->view->get_url();
-  }
-
-  /**
-   * Check to see if the display needs a breadcrumb
-   *
-   * By default, displays do not need breadcrumbs
-   */
-  function uses_breadcrumb() { return FALSE; }
-
-  /**
-   * Determine if a given option is set to use the default display or the
-   * current display
-   *
-   * @return
-   *   TRUE for the default display
-   */
-  function is_defaulted($option) {
-    return !$this->is_default_display() && !empty($this->default_display) && !empty($this->options['defaults'][$option]);
-  }
-
-  /**
-   * Intelligently get an option either from this display or from the
-   * default display, if directed to do so.
-   */
-  function get_option($option) {
-    if ($this->is_defaulted($option)) {
-      return $this->default_display->get_option($option);
-    }
-
-    if (array_key_exists($option, $this->options)) {
-      return $this->options[$option];
-    }
-  }
-
-  /**
-   * Determine if the display's style uses fields.
-   */
-  function uses_fields() {
-    $plugin = $this->get_plugin();
-    if ($plugin) {
-      return $plugin->uses_fields();
-    }
-  }
-
-  /**
-   * Get the instance of a plugin, for example style or row.
-   *
-   * @param string $type
-   *   The type of the plugin.
-   * @param string $name
-   *   The name of the plugin defined in hook_views_plugins.
-   *
-   * @return views_plugin|FALSE
-   */
-  function get_plugin($type = 'style', $name = NULL) {
-    static $cache = array();
-    if (!isset($cache[$type][$name])) {
-      switch ($type) {
-        case 'style':
-        case 'row':
-          $option_name = $type . '_plugin';
-          $options = $this->get_option($type . '_options');
-          if (!$name) {
-            $name = $this->get_option($option_name);
-          }
-
-          break;
-        case 'query':
-          $views_data = views_fetch_data($this->view->base_table);
-          $name = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
-        default:
-          $option_name = $type;
-          $options = $this->get_option($type);
-          if (!$name) {
-            $name = $options['type'];
-          }
-
-          // access & cache store their options as siblings with the
-          // type; all others use an 'options' array.
-          if ($type != 'access' && $type != 'cache') {
-            $options = $options['options'];
-          }
-      }
-      $plugin = views_get_plugin($type, $name);
-
-      if (!$plugin) {
-        return;
-      }
-      if ($type != 'query') {
-        $plugin->init($this->view, $this->display, $options);
-      }
-      else {
-        $display_id = $this->is_defaulted($option_name) ? $this->display->id : 'default';
-        $plugin->localization_keys = array($display_id, $type);
-
-        if (!isset($this->base_field)) {
-          $views_data = views_fetch_data($this->view->base_table);
-          $this->view->base_field = !empty($views_data['table']['base']['field']) ? $views_data['table']['base']['field'] : '';
-        }
-        $plugin->init($this->view->base_table, $this->view->base_field, $options);
-      }
-      $cache[$type][$name] = $plugin;
-    }
-
-    return $cache[$type][$name];
-  }
-
-  /**
-   * Get the handler object for a single handler.
-   */
-  function &get_handler($type, $id) {
-    if (!isset($this->handlers[$type])) {
-      $this->get_handlers($type);
-    }
-
-    if (isset($this->handlers[$type][$id])) {
-      return $this->handlers[$type][$id];
-    }
-
-    // So we can return a reference.
-    $null = NULL;
-    return $null;
-  }
-
-  /**
-   * Get a full array of handlers for $type. This caches them.
-   */
-  function get_handlers($type) {
-    if (!isset($this->handlers[$type])) {
-      $this->handlers[$type] = array();
-      $types = View::views_object_types();
-      $plural = $types[$type]['plural'];
-
-      foreach ($this->get_option($plural) as $id => $info) {
-        // If this is during form submission and there are temporary options
-        // which can only appear if the view is in the edit cache, use those
-        // options instead. This is used for AJAX multi-step stuff.
-        if (isset($_POST['form_id']) && isset($this->view->temporary_options[$type][$id])) {
-          $info = $this->view->temporary_options[$type][$id];
-        }
-
-        if ($info['id'] != $id) {
-          $info['id'] = $id;
-        }
-
-        // If aggregation is on, the group type might override the actual
-        // handler that is in use. This piece of code checks that and,
-        // if necessary, sets the override handler.
-        $override = NULL;
-        if ($this->use_group_by() && !empty($info['group_type'])) {
-          if (empty($this->view->query)) {
-            $this->view->init_query();
-          }
-          $aggregate = $this->view->query->get_aggregation_info();
-          if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
-            $override = $aggregate[$info['group_type']]['handler'][$type];
-          }
-        }
-
-        if (!empty($types[$type]['type'])) {
-          $handler_type = $types[$type]['type'];
-        }
-        else {
-          $handler_type = $type;
-        }
-
-        $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
-        if ($handler) {
-          // Special override for area types so they know where they come from.
-          if ($handler_type == 'area') {
-            $handler->handler_type = $type;
-          }
-
-          $handler->init($this->view, $info);
-          $this->handlers[$type][$id] = &$handler;
-        }
-
-        // Prevent reference problems.
-        unset($handler);
-      }
-    }
-
-    return $this->handlers[$type];
-  }
-
-  /**
-   * Retrieve a list of fields for the current display with the
-   *  relationship associated if it exists.
-   */
-  function get_field_labels() {
-    $options = array();
-    foreach ($this->get_handlers('relationship') as $relationship => $handler) {
-      if ($label = $handler->label()) {
-        $relationships[$relationship] = $label;
-      }
-      else {
-        $relationships[$relationship] = $handler->ui_name();
-      }
-    }
-
-    foreach ($this->get_handlers('field') as $id => $handler) {
-      if ($label = $handler->label()) {
-        $options[$id] = $label;
-      }
-      else {
-        $options[$id] = $handler->ui_name();
-      }
-      if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) {
-        $options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id];
-      }
-    }
-    return $options;
-  }
-
-  /**
-   * Intelligently set an option either from this display or from the
-   * default display, if directed to do so.
-   */
-  function set_option($option, $value) {
-    if ($this->is_defaulted($option)) {
-      return $this->default_display->set_option($option, $value);
-    }
-
-    // Set this in two places: On the handler where we'll notice it
-    // but also on the display object so it gets saved. This should
-    // only be a temporary fix.
-    $this->display->display_options[$option] = $value;
-    return $this->options[$option] = $value;
-  }
-
-  /**
-   * Set an option and force it to be an override.
-   */
-  function override_option($option, $value) {
-    $this->set_override($option, FALSE);
-    $this->set_option($option, $value);
-  }
-
-  /**
-   * Because forms may be split up into sections, this provides
-   * an easy URL to exactly the right section. Don't override this.
-   */
-  function option_link($text, $section, $class = '', $title = '') {
-    views_add_js('ajax');
-    if (!empty($class)) {
-      $text = '<span>' . $text . '</span>';
-    }
-
-    if (!trim($text)) {
-      $text = t('Broken field');
-    }
-
-    if (empty($title)) {
-      $title = $text;
-    }
-
-    return l($text, 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title, 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section)), 'html' => TRUE));
-  }
-
-  /**
-   * Returns to tokens for arguments.
-   *
-   * This function is similar to views_handler_field::get_render_tokens()
-   * but without fields tokens.
-   */
-  function get_arguments_tokens() {
-    $tokens = array();
-    if (!empty($this->view->build_info['substitutions'])) {
-      $tokens = $this->view->build_info['substitutions'];
-    }
-    $count = 0;
-    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
-      $token = '%' . ++$count;
-      if (!isset($tokens[$token])) {
-        $tokens[$token] = '';
-      }
-
-      // Use strip tags as there should never be HTML in the path.
-      // However, we need to preserve special characters like " that
-      // were removed by check_plain().
-      $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(decode_entities($this->view->args[$count - 1])) : '';
-    }
-
-    return $tokens;
-  }
-
-  /**
-   * Provide the default summary for options in the views UI.
-   *
-   * This output is returned as an array.
-   */
-  function options_summary(&$categories, &$options) {
-    $categories = array(
-      'title' => array(
-        'title' => t('Title'),
-        'column' => 'first',
-      ),
-      'format' => array(
-        'title' => t('Format'),
-        'column' => 'first',
-      ),
-      'filters' => array(
-        'title' => t('Filters'),
-        'column' => 'first',
-      ),
-      'fields' => array(
-        'title' => t('Fields'),
-        'column' => 'first',
-      ),
-      'pager' => array(
-        'title' => t('Pager'),
-        'column' => 'second',
-      ),
-      'exposed' => array(
-        'title' => t('Exposed form'),
-        'column' => 'third',
-        'build' => array(
-          '#weight' => 1,
-        ),
-      ),
-      'access' => array(
-        'title' => '',
-        'column' => 'second',
-        'build' => array(
-          '#weight' => -5,
-        ),
-      ),
-      'other' => array(
-        'title' => t('Other'),
-        'column' => 'third',
-        'build' => array(
-          '#weight' => 2,
-        ),
-      ),
-    );
-
-    if ($this->display->id != 'default') {
-      $options['display_id'] = array(
-        'category' => 'other',
-        'title' => t('Machine Name'),
-        'value' => !empty($this->display->new_id) ? check_plain($this->display->new_id) : check_plain($this->display->id),
-        'desc' => t('Change the machine name of this display.'),
-      );
-    }
-
-    $display_comment = check_plain(drupal_substr($this->get_option('display_comment'), 0, 10));
-    $options['display_comment'] = array(
-      'category' => 'other',
-      'title' => t('Comment'),
-      'value' => !empty($display_comment) ? $display_comment : t('No comment'),
-      'desc' => t('Comment or document this display.'),
-    );
-
-    $title = strip_tags($this->get_option('title'));
-    if (!$title) {
-      $title = t('None');
-    }
-
-    $options['title'] = array(
-      'category' => 'title',
-      'title' => t('Title'),
-      'value' => $title,
-      'desc' => t('Change the title that this display will use.'),
-    );
-
-    $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
-    $style_plugin_instance = $this->get_plugin('style');
-    $style_summary = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->summary_title();
-    $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->plugin_title();
-
-    $style = '';
-
-    $options['style_plugin'] = array(
-      'category' => 'format',
-      'title' => t('Format'),
-      'value' => $style_title,
-      'setting' => $style_summary,
-      'desc' => t('Change the way content is formatted.'),
-    );
-
-    // This adds a 'Settings' link to the style_options setting if the style has options.
-    if (!empty($style_plugin['uses options'])) {
-      $options['style_plugin']['links']['style_options'] = t('Change settings for this format');
-    }
-
-    if (!empty($style_plugin['uses row plugin'])) {
-      $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
-      $row_plugin_instance = $this->get_plugin('row');
-      $row_summary = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->summary_title();
-      $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->plugin_title();
-
-      $options['row_plugin'] = array(
-        'category' => 'format',
-        'title' => t('Show'),
-        'value' => $row_title,
-        'setting' => $row_summary,
-        'desc' => t('Change the way each row in the view is styled.'),
-      );
-      // This adds a 'Settings' link to the row_options setting if the row style has options.
-      if (!empty($row_plugin['uses options'])) {
-        $options['row_plugin']['links']['row_options'] = t('Change settings for this style');
-      }
-    }
-    if (!empty($this->definition['use ajax'])) {
-      $options['use_ajax'] = array(
-        'category' => 'other',
-        'title' => t('Use AJAX'),
-        'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
-        'desc' => t('Change whether or not this display will use AJAX.'),
-      );
-    }
-    if (!empty($this->definition['accept attachments'])) {
-      $options['hide_attachment_summary'] = array(
-        'category' => 'other',
-        'title' => t('Hide attachments in summary'),
-        'value' => $this->get_option('hide_attachment_summary') ? t('Yes') : t('No'),
-        'desc' => t('Change whether or not to display attachments when displaying a contextual filter summary.'),
-      );
-    }
-
-    $pager_plugin = $this->get_plugin('pager');
-    if (!$pager_plugin) {
-      // default to the no pager plugin.
-      $pager_plugin = views_get_plugin('pager', 'none');
-    }
-
-    $pager_str = $pager_plugin->summary_title();
-
-    $options['pager'] = array(
-      'category' => 'pager',
-      'title' => t('Use pager'),
-      'value' => $pager_plugin->plugin_title(),
-      'setting' => $pager_str,
-      'desc' => t("Change this display's pager setting."),
-    );
-
-    // If pagers aren't allowed, change the text of the item:
-    if (empty($this->definition['use pager'])) {
-      $options['pager']['title'] = t('Items to display');
-    }
-
-    if (!empty($pager_plugin->definition['uses options'])) {
-      $options['pager']['links']['pager_options'] = t('Change settings for this pager type.');
-    }
-
-    if (!empty($this->definition['use more'])) {
-      $options['use_more'] = array(
-        'category' => 'pager',
-        'title' => t('More link'),
-        'value' => $this->get_option('use_more') ? t('Yes') : t('No'),
-        'desc' => t('Specify whether this display will provide a "more" link.'),
-      );
-    }
-
-    $this->view->init_query();
-    if ($this->view->query->get_aggregation_info()) {
-      $options['group_by'] = array(
-        'category' => 'other',
-        'title' => t('Use aggregation'),
-        'value' => $this->get_option('group_by') ? t('Yes') : t('No'),
-        'desc' => t('Allow grouping and aggregation (calculation) of fields.'),
-      );
-    }
-
-    $options['query'] = array(
-      'category' => 'other',
-      'title' => t('Query settings'),
-      'value' => t('Settings'),
-      'desc' => t('Allow to set some advanced settings for the query plugin'),
-    );
-
-    $languages = array(
-        '***CURRENT_LANGUAGE***' => t("Current user's language"),
-        '***DEFAULT_LANGUAGE***' => t("Default site language"),
-        LANGUAGE_NOT_SPECIFIED => t('Language neutral'),
-    );
-    if (module_exists('language')) {
-      $languages = array_merge($languages, language_list());
-    }
-    $field_language = array();
-    $options['field_language'] = array(
-      'category' => 'other',
-      'title' => t('Field Language'),
-      'value' => $languages[$this->get_option('field_language')],
-      'desc' => t('All fields which support translations will be displayed in the selected language.'),
-    );
-
-    $access_plugin = $this->get_plugin('access');
-    if (!$access_plugin) {
-      // default to the no access control plugin.
-      $access_plugin = views_get_plugin('access', 'none');
-    }
-
-    $access_str = $access_plugin->summary_title();
-
-    $options['access'] = array(
-      'category' => 'access',
-      'title' => t('Access'),
-      'value' => $access_plugin->plugin_title(),
-      'setting' => $access_str,
-      'desc' => t('Specify access control type for this display.'),
-    );
-
-    if (!empty($access_plugin->definition['uses options'])) {
-      $options['access']['links']['access_options'] = t('Change settings for this access type.');
-    }
-
-    $cache_plugin = $this->get_plugin('cache');
-    if (!$cache_plugin) {
-      // default to the no cache control plugin.
-      $cache_plugin = views_get_plugin('cache', 'none');
-    }
-
-    $cache_str = $cache_plugin->summary_title();
-
-    $options['cache'] = array(
-      'category' => 'other',
-      'title' => t('Caching'),
-      'value' => $cache_plugin->plugin_title(),
-      'setting' => $cache_str,
-      'desc' => t('Specify caching type for this display.'),
-    );
-
-    if (!empty($cache_plugin->definition['uses options'])) {
-      $options['cache']['links']['cache_options'] = t('Change settings for this caching type.');
-    }
-
-    if (!empty($access_plugin->definition['uses options'])) {
-      $options['access']['links']['access_options'] = t('Change settings for this access type.');
-    }
-
-    if ($this->uses_link_display()) {
-      $display_id = $this->get_link_display();
-      $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
-      $link_display =  $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display;
-      $options['link_display'] = array(
-        'category' => 'other',
-        'title' => t('Link display'),
-        'value' => $link_display,
-        'desc' => t('Specify which display or custom url this display will link to.'),
-      );
-    }
-
-    if ($this->uses_exposed_form_in_block()) {
-      $options['exposed_block'] = array(
-        'category' => 'exposed',
-        'title' => t('Exposed form in block'),
-        'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
-        'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
-      );
-    }
-
-    $exposed_form_plugin = $this->get_plugin('exposed_form');
-    if (!$exposed_form_plugin) {
-      // default to the no cache control plugin.
-      $exposed_form_plugin = views_get_plugin('exposed_form', 'basic');
-    }
-
-    $exposed_form_str = $exposed_form_plugin->summary_title();
-
-    $options['exposed_form'] = array(
-      'category' => 'exposed',
-      'title' => t('Exposed form style'),
-      'value' => $exposed_form_plugin->plugin_title(),
-      'setting' => $exposed_form_str,
-      'desc' => t('Select the kind of exposed filter to use.'),
-    );
-
-    if (!empty($exposed_form_plugin->definition['uses options'])) {
-      $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.');
-    }
-
-    $css_class = check_plain(trim($this->get_option('css_class')));
-    if (!$css_class) {
-      $css_class = t('None');
-    }
-
-    $options['css_class'] = array(
-      'category' => 'other',
-      'title' => t('CSS class'),
-      'value' => $css_class,
-      'desc' => t('Change the CSS class name(s) that will be added to this display.'),
-    );
-
-    $options['analyze-theme'] = array(
-      'category' => 'other',
-      'title' => t('Theme'),
-      'value' => t('Information'),
-      'desc' => t('Get information on how to theme this display'),
-    );
-
-    foreach ($this->extender as $extender) {
-      $extender->options_summary($categories, $options);
-    }
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    if ($this->defaultable_sections($form_state['section'])) {
-      views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
-    }
-    $form['#title'] = check_plain($this->display->display_title) . ': ';
-
-    // Set the 'section' to hilite on the form.
-    // If it's the item we're looking at is pulling from the default display,
-    // reflect that. Don't use is_defaulted since we want it to show up even
-    // on the default display.
-    if (!empty($this->options['defaults'][$form_state['section']])) {
-      $form['#section'] = 'default-' . $form_state['section'];
-    }
-    else {
-      $form['#section'] = $this->display->id . '-' . $form_state['section'];
-    }
-
-    switch ($form_state['section']) {
-      case 'display_id':
-        $form['#title'] .= t('The machine name of this display');
-        $form['display_id'] = array(
-          '#type' => 'textfield',
-          '#description' => t('This is machine name of the display.'),
-          '#default_value' => !empty($this->display->new_id) ? $this->display->new_id : $this->display->id,
-          '#required' => TRUE,
-          '#size' => 64,
-        );
-        break;
-      case 'display_title':
-        $form['#title'] .= t('The name and the description of this display');
-        $form['display_title'] = array(
-          '#title' => t('Name'),
-          '#type' => 'textfield',
-          '#description' => t('This name will appear only in the administrative interface for the View.'),
-          '#default_value' => $this->display->display_title,
-        );
-        $form['display_description'] = array(
-          '#title' => t('Description'),
-          '#type' => 'textfield',
-          '#description' => t('This description will appear only in the administrative interface for the View.'),
-          '#default_value' => $this->get_option('display_description'),
-        );
-        break;
-      case 'display_comment':
-        $form['#title'] .= t("This display's comments");
-        $form['display_comment'] = array(
-          '#type' => 'textarea',
-          '#description' => t('This value will be seen and used only within the Views UI and can be used to document this display. You can use this to provide notes for other or future maintainers of your site about how or why this display is configured.'),
-          '#default_value' => $this->get_option('display_comment'),
-        );
-        break;
-      case 'title':
-        $form['#title'] .= t('The title of this view');
-        $form['title'] = array(
-          '#type' => 'textfield',
-          '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'),
-          '#default_value' => $this->get_option('title'),
-        );
-        break;
-      case 'css_class':
-        $form['#title'] .= t('CSS class');
-        $form['css_class'] = array(
-          '#type' => 'textfield',
-          '#description' => t('The CSS class names will be added to the view. This enables you to use specific CSS code for each view. You may define multiples classes separated by spaces.'),
-          '#default_value' => $this->get_option('css_class'),
-        );
-        break;
-      case 'use_ajax':
-        $form['#title'] .= t('Use AJAX when available to load this view');
-        $form['description'] = array(
-          '#markup' => '<div class="description form-item">' . t('If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content.') . '</div>',
-        );
-        $form['use_ajax'] = array(
-          '#type' => 'radios',
-          '#options' => array(1 => t('Yes'), 0 => t('No')),
-          '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
-        );
-        break;
-      case 'hide_attachment_summary':
-        $form['#title'] .= t('Hide attachments when displaying a contextual filter summary');
-        $form['hide_attachment_summary'] = array(
-          '#type' => 'radios',
-          '#options' => array(1 => t('Yes'), 0 => t('No')),
-          '#default_value' => $this->get_option('hide_attachment_summary') ? 1 : 0,
-        );
-        break;
-      case 'use_more':
-        $form['#title'] .= t('Add a more link to the bottom of the display.');
-        $form['use_more'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Create more link'),
-          '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above. You can override the url at the link display setting."),
-          '#default_value' => $this->get_option('use_more'),
-        );
-        $form['use_more_always'] = array(
-          '#type' => 'checkbox',
-          '#title' => t("Display 'more' link only if there is more content"),
-          '#description' => t("Leave this unchecked to display the 'more' link even if there are no more items to display."),
-          '#default_value' => !$this->get_option('use_more_always'),
-          '#states' => array(
-            'visible' => array(
-              ':input[name="use_more"]' => array('checked' => TRUE),
-            ),
-          ),
-        );
-        $form['use_more_text'] = array(
-          '#type' => 'textfield',
-          '#title' => t('More link text'),
-          '#description' => t("The text to display for the more link."),
-          '#default_value' => $this->get_option('use_more_text'),
-          '#states' => array(
-            'visible' => array(
-              ':input[name="use_more"]' => array('checked' => TRUE),
-            ),
-          ),
-        );
-        break;
-      case 'group_by':
-        $form['#title'] .= t('Allow grouping and aggregation (calculation) of fields.');
-        $form['group_by'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Aggregate'),
-          '#description' => t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'),
-          '#default_value' => $this->get_option('group_by'),
-        );
-        break;
-      case 'access':
-        $form['#title'] .= t('Access restrictions');
-        $form['access'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-
-        $access = $this->get_option('access');
-        $form['access']['type'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('access', NULL, array($this->view->base_table)),
-          '#default_value' => $access['type'],
-        );
-
-        $access_plugin = views_fetch_plugin_data('access', $access['type']);
-        if (!empty($access_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#prefix' => '<div class="form-item description">',
-            '#markup' => t('You may also adjust the !settings for the currently selected access restriction.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
-            '#suffix' => '</div>',
-          );
-        }
-
-        break;
-      case 'access_options':
-        $access = $this->get_option('access');
-        $plugin = $this->get_plugin('access');
-        $form['#title'] .= t('Access options');
-        if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-          $form['#help_module'] = $plugin->definition['module'];
-
-          $form['access_options'] = array(
-            '#tree' => TRUE,
-          );
-          $form['access_options']['type'] = array(
-            '#type' => 'value',
-            '#value' => $access['type'],
-          );
-          $plugin->options_form($form['access_options'], $form_state);
-        }
-        break;
-      case 'cache':
-        $form['#title'] .= t('Caching');
-        $form['cache'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-
-        $cache = $this->get_option('cache');
-        $form['cache']['type'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('cache', NULL, array($this->view->base_table)),
-          '#default_value' => $cache['type'],
-        );
-
-        $cache_plugin = views_fetch_plugin_data('cache', $cache['type']);
-        if (!empty($cache_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#prefix' => '<div class="form-item description">',
-            '#suffix' => '</div>',
-            '#markup' => t('You may also adjust the !settings for the currently selected cache mechanism.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
-          );
-        }
-        break;
-      case 'cache_options':
-        $cache = $this->get_option('cache');
-        $plugin = $this->get_plugin('cache');
-        $form['#title'] .= t('Caching options');
-        if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-          $form['#help_module'] = $plugin->definition['module'];
-
-          $form['cache_options'] = array(
-            '#tree' => TRUE,
-          );
-          $form['cache_options']['type'] = array(
-            '#type' => 'value',
-            '#value' => $cache['type'],
-          );
-          $plugin->options_form($form['cache_options'], $form_state);
-        }
-        break;
-      case 'query':
-        $query_options = $this->get_option('query');
-        $plugin_name = $query_options['type'];
-
-        $form['#title'] .= t('Query options');
-        $this->view->init_query();
-        if ($this->view->query) {
-          if (isset($this->view->query->definition['help topic'])) {
-            $form['#help_topic'] = $this->view->query->definition['help topic'];
-          }
-
-          if (isset($this->view->query->definition['module'])) {
-            $form['#help_module'] = $this->view->query->definition['module'];
-          }
-
-          $form['query'] = array(
-            '#tree' => TRUE,
-            'type' => array(
-              '#type' => 'value',
-              '#value' => $plugin_name,
-            ),
-            'options' => array(
-              '#tree' => TRUE,
-            ),
-          );
-
-          $this->view->query->options_form($form['query']['options'], $form_state);
-        }
-        break;
-      case 'field_language':
-        $form['#title'] .= t('Field Language');
-
-        $entities = entity_get_info();
-        $entity_tables = array();
-        $has_translation_handlers = FALSE;
-        foreach ($entities as $type => $entity_info) {
-          $entity_tables[] = $entity_info['base table'];
-
-          if (!empty($entity_info['translation'])) {
-            $has_translation_handlers = TRUE;
-          }
-        }
-
-        // Doesn't make sense to show a field setting here if we aren't querying
-        // an entity base table. Also, we make sure that there's at least one
-        // entity type with a translation handler attached.
-        if (in_array($this->view->base_table, $entity_tables) && $has_translation_handlers) {
-          $languages = array(
-            '***CURRENT_LANGUAGE***' => t("Current user's language"),
-            '***DEFAULT_LANGUAGE***' => t("Default site language"),
-            LANGUAGE_NOT_SPECIFIED => t('Language neutral'),
-          );
-          $languages = array_merge($languages, views_language_list());
-
-          $form['field_language'] = array(
-            '#type' => 'select',
-            '#title' => t('Field Language'),
-            '#description' => t('All fields which support translations will be displayed in the selected language.'),
-            '#options' => $languages,
-            '#default_value' => $this->get_option('field_language'),
-          );
-          $form['field_language_add_to_query'] = array(
-            '#type' => 'checkbox',
-            '#title' => t('When needed, add the field language condition to the query'),
-            '#default_value' => $this->get_option('field_language_add_to_query'),
-          );
-        }
-        else {
-          $form['field_language']['#markup'] = t("You don't have translatable entity types.");
-        }
-        break;
-      case 'style_plugin':
-        $form['#title'] .= t('How should this view be styled');
-        $form['#help_topic'] = 'style';
-        $form['style_plugin'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)),
-          '#default_value' => $this->get_option('style_plugin'),
-          '#description' => t('If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary.'),
-        );
-
-        $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
-        if (!empty($style_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'style_options'))) . '</div>',
-          );
-        }
-
-        break;
-      case 'style_options':
-        $form['#title'] .= t('Style options');
-        $style = TRUE;
-        $type = 'style_plugin';
-        $name = $this->get_option('style_plugin');
-
-      case 'row_options':
-        if (!isset($name)) {
-          $name = $this->get_option('row_plugin');
-        }
-        // if row, $style will be empty.
-        if (empty($style)) {
-          $form['#title'] .= t('Row style options');
-          $type = 'row_plugin';
-        }
-        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
-        if ($plugin) {
-          if (isset($plugin->definition['help topic'])) {
-            $form['#help_topic'] = $plugin->definition['help topic'];
-            $form['#help_module'] = $plugin->definition['module'];
-          }
-          $form[$form_state['section']] = array(
-            '#tree' => TRUE,
-          );
-          $plugin->options_form($form[$form_state['section']], $form_state);
-        }
-        break;
-      case 'row_plugin':
-        $form['#title'] .= t('How should each row in this view be styled');
-        $form['#help_topic'] = 'style-row';
-        $form['row_plugin'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)),
-          '#default_value' => $this->get_option('row_plugin'),
-        );
-
-        $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
-        if (!empty($row_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected row style.', array('!settings' => $this->option_link(t('settings'), 'row_options'))) . '</div>',
-          );
-        }
-
-        break;
-      case 'link_display':
-        $form['#title'] .= t('Which display to use for path');
-        foreach ($this->view->display as $display_id => $display) {
-          if ($display->handler->has_path()) {
-            $options[$display_id] = $display->display_title;
-          }
-        }
-        $options['custom_url'] = t('Custom URL');
-        if (count($options)) {
-          $form['link_display'] = array(
-            '#type' => 'radios',
-            '#options' => $options,
-            '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
-            '#default_value' => $this->get_option('link_display'),
-          );
-        }
-
-        $options = array();
-        $count = 0; // This lets us prepare the key as we want it printed.
-        foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
-          $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
-          $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
-        }
-
-        // Default text.
-        // We have some options, so make a list.
-        $output = '';
-        if (!empty($options)) {
-          $output = t('<p>The following tokens are available for this link.</p>');
-          foreach (array_keys($options) as $type) {
-            if (!empty($options[$type])) {
-              $items = array();
-              foreach ($options[$type] as $key => $value) {
-                $items[] = $key . ' == ' . $value;
-              }
-              $output .= theme('item_list',
-                array(
-                  'items' => $items,
-                  'type' => $type
-                ));
-            }
-          }
-        }
-
-        $form['link_url'] = array(
-          '#type' => 'textfield',
-          '#title' => t('Custom URL'),
-          '#default_value' => $this->get_option('link_url'),
-          '#description' => t('A Drupal path or external URL the more link will point to. Note that this will override the link display setting above.') . $output,
-          '#states' => array(
-            'visible' => array(
-              ':input[name="link_display"]' => array('value' => 'custom_url'),
-            ),
-          ),
-        );
-        break;
-      case 'analyze-theme':
-        $form['#title'] .= t('Theming information');
-        $form['#help_topic'] = 'analyze-theme';
-
-        if (isset($_POST['theme'])) {
-          $this->theme = $_POST['theme'];
-        }
-        elseif (empty($this->theme)) {
-          $this->theme = variable_get('theme_default', 'bartik');
-        }
-
-        if (isset($GLOBALS['theme']) && $GLOBALS['theme'] == $this->theme) {
-          $this->theme_registry = theme_get_registry();
-          $theme_engine = $GLOBALS['theme_engine'];
-        }
-        else {
-          $themes = list_themes();
-          $theme = $themes[$this->theme];
-
-          // Find all our ancestor themes and put them in an array.
-          $base_theme = array();
-          $ancestor = $this->theme;
-          while ($ancestor && isset($themes[$ancestor]->base_theme)) {
-            $ancestor = $themes[$ancestor]->base_theme;
-            $base_theme[] = $themes[$ancestor];
-          }
-
-          // The base themes should be initialized in the right order.
-          $base_theme = array_reverse($base_theme);
-
-          // This code is copied directly from _drupal_theme_initialize()
-          $theme_engine = NULL;
-
-          // Initialize the theme.
-          if (isset($theme->engine)) {
-            // Include the engine.
-            include_once DRUPAL_ROOT . '/' . $theme->owner;
-
-            $theme_engine = $theme->engine;
-            if (function_exists($theme_engine . '_init')) {
-              foreach ($base_theme as $base) {
-                call_user_func($theme_engine . '_init', $base);
-              }
-              call_user_func($theme_engine . '_init', $theme);
-            }
-          }
-          else {
-            // include non-engine theme files
-            foreach ($base_theme as $base) {
-              // Include the theme file or the engine.
-              if (!empty($base->owner)) {
-                include_once DRUPAL_ROOT . '/' . $base->owner;
-              }
-            }
-            // and our theme gets one too.
-            if (!empty($theme->owner)) {
-              include_once DRUPAL_ROOT . '/' . $theme->owner;
-            }
-          }
-          $this->theme_registry = _theme_load_registry($theme, $base_theme, $theme_engine);
-        }
-
-        // If there's a theme engine involved, we also need to know its extension
-        // so we can give the proper filename.
-        $this->theme_extension = '.tpl.php';
-        if (isset($theme_engine)) {
-          $extension_function = $theme_engine . '_extension';
-          if (function_exists($extension_function)) {
-            $this->theme_extension = $extension_function();
-          }
-        }
-
-        $funcs = array();
-        // Get theme functions for the display. Note that some displays may
-        // not have themes. The 'feed' display, for example, completely
-        // delegates to the style.
-        if (!empty($this->definition['theme'])) {
-          $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': '  . $this->format_themes($this->theme_functions());
-          $themes = $this->additional_theme_functions();
-          if ($themes) {
-            foreach ($themes as $theme) {
-              $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': '  . $this->format_themes($theme);
-            }
-          }
-        }
-
-        $plugin = $this->get_plugin();
-        if ($plugin) {
-          $funcs[] = $this->option_link(t('Style output'), 'analyze-theme-style') . ': ' . $this->format_themes($plugin->theme_functions(), $plugin->additional_theme_functions());
-          $themes = $plugin->additional_theme_functions();
-          if ($themes) {
-            foreach ($themes as $theme) {
-              $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': '  . $this->format_themes($theme);
-            }
-          }
-
-          if ($plugin->uses_row_plugin()) {
-            $row_plugin = $this->get_plugin('row');
-            if ($row_plugin) {
-              $funcs[] = $this->option_link(t('Row style output'), 'analyze-theme-row') . ': ' . $this->format_themes($row_plugin->theme_functions());
-              $themes = $row_plugin->additional_theme_functions();
-              if ($themes) {
-                foreach ($themes as $theme) {
-                  $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': '  . $this->format_themes($theme);
-                }
-              }
-            }
-          }
-
-          if ($plugin->uses_fields()) {
-            foreach ($this->get_handlers('field') as $id => $handler) {
-              $funcs[] = $this->option_link(t('Field @field (ID: @id)', array('@field' => $handler->ui_name(), '@id' => $id)), 'analyze-theme-field') . ': ' . $this->format_themes($handler->theme_functions());
-            }
-          }
-        }
-
-        $form['important'] = array(
-          '#markup' => '<div class="form-item description"><p>' . t('This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold.') . '</p></div>',
-        );
-
-        if (isset($this->view->display[$this->view->current_display]->new_id)) {
-          $form['important']['new_id'] = array(
-            '#prefix' => '<div class="description">',
-            '#suffix' => '</div>',
-            '#value' => t("<strong>Important!</strong> You have changed the display's machine name. Anything that attached to this display specifically, such as theming, may stop working until it is updated. To see theme suggestions for it, you need to save the view."),
-          );
-        }
-
-        foreach (list_themes() as $key => $theme) {
-          if (!empty($theme->info['hidden'])) {
-            continue;
-          }
-          $options[$key] = $theme->info['name'];
-        }
-
-        $form['box'] = array(
-          '#prefix' => '<div class="container-inline">',
-          '#suffix' => '</div>',
-        );
-        $form['box']['theme'] = array(
-          '#type' => 'select',
-          '#options' => $options,
-          '#default_value' => $this->theme,
-        );
-
-        $form['box']['change'] = array(
-          '#type' => 'submit',
-          '#value' => t('Change theme'),
-          '#submit' => array('views_ui_edit_display_form_change_theme'),
-        );
-
-        $form['analysis'] = array(
-          '#markup' => '<div class="form-item">' . theme('item_list', array('items' => $funcs)) . '</div>',
-        );
-
-        $form['rescan_button'] = array(
-          '#prefix' => '<div class="form-item">',
-          '#suffix' => '</div>',
-        );
-        $form['rescan_button']['button'] = array(
-          '#type' => 'submit',
-          '#value' => t('Rescan template files'),
-          '#submit' => array('views_ui_config_item_form_rescan'),
-        );
-        $form['rescan_button']['markup'] = array(
-          '#markup' => '<div class="description">' . t("<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system.") . '</div>',
-        );
-
-        $form_state['ok_button'] = TRUE;
-        break;
-      case 'analyze-theme-display':
-        $form['#title'] .= t('Theming information (display)');
-        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
-
-        if (empty($this->definition['theme'])) {
-          $output .= t('This display has no theming information');
-        }
-        else {
-          $output .= '<p>' . t('This is the default theme template used for this display.') . '</p>';
-          $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($this->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
-        }
-
-        if (!empty($this->definition['additional themes'])) {
-          foreach ($this->definition['additional themes'] as $theme => $type) {
-            $output .= '<p>' . t('This is an alternative template for this display.') . '</p>';
-            $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
-          }
-        }
-
-        $form['analysis'] = array(
-          '#markup' => '<div class="form-item">' . $output . '</div>',
-        );
-
-        $form_state['ok_button'] = TRUE;
-        break;
-      case 'analyze-theme-style':
-        $form['#title'] .= t('Theming information (style)');
-        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
-
-        $plugin = $this->get_plugin();
-
-        if (empty($plugin->definition['theme'])) {
-          $output .= t('This display has no style theming information');
-        }
-        else {
-          $output .= '<p>' . t('This is the default theme template used for this style.') . '</p>';
-          $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
-        }
-
-        if (!empty($plugin->definition['additional themes'])) {
-          foreach ($plugin->definition['additional themes'] as $theme => $type) {
-            $output .= '<p>' . t('This is an alternative template for this style.') . '</p>';
-            $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
-          }
-        }
-
-        $form['analysis'] = array(
-          '#markup' => '<div class="form-item">' . $output . '</div>',
-        );
-
-        $form_state['ok_button'] = TRUE;
-        break;
-      case 'analyze-theme-row':
-        $form['#title'] .= t('Theming information (row style)');
-        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
-
-        $plugin = $this->get_plugin('row');
-
-        if (empty($plugin->definition['theme'])) {
-          $output .= t('This display has no row style theming information');
-        }
-        else {
-          $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
-          $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
-        }
-
-        if (!empty($plugin->definition['additional themes'])) {
-          foreach ($plugin->definition['additional themes'] as $theme => $type) {
-            $output .= '<p>' . t('This is an alternative template for this row style.') . '</p>';
-            $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
-          }
-        }
-
-        $form['analysis'] = array(
-          '#markup' => '<div class="form-item">' . $output . '</div>',
-        );
-
-        $form_state['ok_button'] = TRUE;
-        break;
-      case 'analyze-theme-field':
-        $form['#title'] .= t('Theming information (row style)');
-        $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
-
-        $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
-
-        // Field templates aren't registered the normal way...and they're always
-        // this one, anyhow.
-        $output .= '<pre>' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '</pre>';
-
-        $form['analysis'] = array(
-          '#markup' => '<div class="form-item">' . $output . '</div>',
-        );
-        $form_state['ok_button'] = TRUE;
-        break;
-
-      case 'exposed_block':
-        $form['#title'] .= t('Put the exposed form in a block');
-        $form['description'] = array(
-          '#markup' => '<div class="description form-item">' . t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.') . '</div>',
-        );
-        $form['exposed_block'] = array(
-          '#type' => 'radios',
-          '#options' => array(1 => t('Yes'), 0 => t('No')),
-          '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
-        );
-        break;
-      case 'exposed_form':
-        $form['#title'] .= t('Exposed Form');
-        $form['exposed_form'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-
-        $exposed_form = $this->get_option('exposed_form');
-        $form['exposed_form']['type'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('exposed_form', NULL, array($this->view->base_table)),
-          '#default_value' => $exposed_form['type'],
-        );
-
-        $exposed_form_plugin = views_fetch_plugin_data('exposed_form', $exposed_form['type']);
-        if (!empty($exposed_form_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#prefix' => '<div class="form-item description">',
-            '#suffix' => '</div>',
-            '#markup' => t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'exposed_form_options'))),
-          );
-        }
-        break;
-      case 'exposed_form_options':
-        $plugin = $this->get_plugin('exposed_form');
-        $form['#title'] .= t('Exposed form options');
-        if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-
-          $form['exposed_form_options'] = array(
-            '#tree' => TRUE,
-          );
-          $plugin->options_form($form['exposed_form_options'], $form_state);
-        }
-        break;
-      case 'pager':
-        $form['#title'] .= t('Select which pager, if any, to use for this view');
-        $form['pager'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-
-        $pager = $this->get_option('pager');
-        $form['pager']['type'] =  array(
-          '#type' => 'radios',
-          '#options' => views_fetch_plugin_names('pager', empty($this->definition['use pager']) ? 'basic' : NULL, array($this->view->base_table)),
-          '#default_value' => $pager['type'],
-        );
-
-        $pager_plugin = views_fetch_plugin_data('pager', $pager['type'], array($this->view->base_table));
-        if (!empty($pager_plugin['uses options'])) {
-          $form['markup'] = array(
-            '#prefix' => '<div class="form-item description">',
-            '#suffix' => '</div>',
-            '#markup' => t('You may also adjust the !settings for the currently selected pager.', array('!settings' => $this->option_link(t('settings'), 'pager_options'))),
-          );
-        }
-
-        break;
-      case 'pager_options':
-        $plugin = $this->get_plugin('pager');
-        $form['#title'] .= t('Pager options');
-        if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-
-          $form['pager_options'] = array(
-            '#tree' => TRUE,
-          );
-          $plugin->options_form($form['pager_options'], $form_state);
-        }
-        break;
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->options_form($form, $form_state);
-    }
-  }
-
-  /**
-   * Format a list of theme templates for output by the theme info helper.
-   */
-  function format_themes($themes) {
-    $registry = $this->theme_registry;
-    $extension = $this->theme_extension;
-
-    $output = '';
-    $picked = FALSE;
-    foreach ($themes as $theme) {
-      $template = strtr($theme, '_', '-') . $extension;
-      if (!$picked && !empty($registry[$theme])) {
-        $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './';
-        if (file_exists($template_path . $template)) {
-          $hint = t('File found in folder @template-path', array('@template-path' => $template_path));
-          $template = '<strong title="'. $hint .'">' . $template . '</strong>';
-        }
-        else {
-          $template = '<strong class="error">' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . '</strong>';
-        }
-        $picked = TRUE;
-      }
-      $fixed[] = $template;
-    }
-
-    return implode(', ', array_reverse($fixed));
-  }
-
-  /**
-   * Validate the options form.
-   */
-  function options_validate(&$form, &$form_state) {
-    switch ($form_state['section']) {
-      case 'display_title':
-        if (empty($form_state['values']['display_title'])) {
-          form_error($form['display_title'], t('Display title may not be empty.'));
-        }
-        break;
-      case 'css_class':
-        $css_class = $form_state['values']['css_class'];
-        if (preg_match('/[^a-zA-Z0-9-_ ]/', $css_class)) {
-          form_error($form['css_class'], t('CSS classes must be alphanumeric or dashes only.'));
-        }
-      break;
-      case 'display_id':
-        if ($form_state['values']['display_id']) {
-          if (preg_match('/[^a-z0-9_]/', $form_state['values']['display_id'])) {
-            form_error($form['display_id'], t('Display name must be letters, numbers, or underscores only.'));
-          }
-
-          foreach ($this->view->display as $id => $display) {
-            if ($id != $this->view->current_display && ($form_state['values']['display_id'] == $id || (isset($display->new_id) && $form_state['values']['display_id'] == $display->new_id))) {
-              form_error($form['display_id'], t('Display id should be unique.'));
-            }
-          }
-        }
-        break;
-      case 'style_options':
-        $style = TRUE;
-      case 'row_options':
-        // if row, $style will be empty.
-        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
-        if ($plugin) {
-          $plugin->options_validate($form[$form_state['section']], $form_state);
-        }
-        break;
-      case 'access_options':
-        $plugin = $this->get_plugin('access');
-        if ($plugin) {
-          $plugin->options_validate($form['access_options'], $form_state);
-        }
-        break;
-      case 'query':
-        if ($this->view->query) {
-          $this->view->query->options_validate($form['query'], $form_state);
-        }
-        break;
-      case 'cache_options':
-        $plugin = $this->get_plugin('cache');
-        if ($plugin) {
-          $plugin->options_validate($form['cache_options'], $form_state);
-        }
-        break;
-      case 'exposed_form_options':
-        $plugin = $this->get_plugin('exposed_form');
-        if ($plugin) {
-          $plugin->options_validate($form['exposed_form_options'], $form_state);
-        }
-        break;
-      case 'pager_options':
-        $plugin = $this->get_plugin('pager');
-        if ($plugin) {
-          $plugin->options_validate($form['pager_options'], $form_state);
-        }
-        break;
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->options_validate($form, $form_state);
-    }
-  }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) {
-    // Not sure I like this being here, but it seems (?) like a logical place.
-    $cache_plugin = $this->get_plugin('cache');
-    if ($cache_plugin) {
-      $cache_plugin->cache_flush();
-    }
-
-    $section = $form_state['section'];
-    switch ($section) {
-      case 'display_id':
-        if (isset($form_state['values']['display_id'])) {
-          $this->display->new_id = $form_state['values']['display_id'];
-        }
-        break;
-      case 'display_title':
-        $this->display->display_title = $form_state['values']['display_title'];
-        $this->set_option('display_description', $form_state['values']['display_description']);
-        break;
-      case 'access':
-        $access = $this->get_option('access');
-        if ($access['type'] != $form_state['values']['access']['type']) {
-          $plugin = views_get_plugin('access', $form_state['values']['access']['type']);
-          if ($plugin) {
-            $access = array('type' => $form_state['values']['access']['type']);
-            $this->set_option('access', $access);
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options'));
-            }
-          }
-        }
-
-        break;
-      case 'access_options':
-        $plugin = views_get_plugin('access', $form_state['values'][$section]['type']);
-        if ($plugin) {
-          $plugin->options_submit($form['access_options'], $form_state);
-          $this->set_option('access', $form_state['values'][$section]);
-        }
-        break;
-      case 'cache':
-        $cache = $this->get_option('cache');
-        if ($cache['type'] != $form_state['values']['cache']['type']) {
-          $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']);
-          if ($plugin) {
-            $cache = array('type' => $form_state['values']['cache']['type']);
-            $this->set_option('cache', $cache);
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options'));
-            }
-          }
-        }
-
-        break;
-      case 'cache_options':
-        $plugin = views_get_plugin('cache', $form_state['values'][$section]['type']);
-        if ($plugin) {
-          $plugin->options_submit($form['cache_options'], $form_state);
-          $this->set_option('cache', $form_state['values'][$section]);
-        }
-        break;
-      case 'query':
-        $plugin = $this->get_plugin('query');
-        if ($plugin) {
-          $plugin->options_submit($form['query']['options'], $form_state);
-          $this->set_option('query', $form_state['values'][$section]);
-        }
-        break;
-
-      case 'link_display':
-        $this->set_option('link_url', $form_state['values']['link_url']);
-      case 'title':
-      case 'css_class':
-      case 'display_comment':
-        $this->set_option($section, $form_state['values'][$section]);
-        break;
-      case 'field_language':
-        $this->set_option('field_language', $form_state['values']['field_language']);
-        $this->set_option('field_language_add_to_query', $form_state['values']['field_language_add_to_query']);
-        break;
-      case 'use_ajax':
-      case 'hide_attachment_summary':
-        $this->set_option($section, (bool)$form_state['values'][$section]);
-        break;
-      case 'use_more':
-        $this->set_option($section, intval($form_state['values'][$section]));
-        $this->set_option('use_more_always', !intval($form_state['values']['use_more_always']));
-        $this->set_option('use_more_text', $form_state['values']['use_more_text']);
-      case 'distinct':
-        $this->set_option($section, $form_state['values'][$section]);
-        break;
-      case 'group_by':
-        $this->set_option($section, $form_state['values'][$section]);
-        break;
-      case 'row_plugin':
-        // This if prevents resetting options to default if they don't change
-        // the plugin.
-        if ($this->get_option($section) != $form_state['values'][$section]) {
-          $plugin = views_get_plugin('row', $form_state['values'][$section]);
-          if ($plugin) {
-            $this->set_option($section, $form_state['values'][$section]);
-            $this->set_option('row_options', array());
-
-            // send ajax form to options page if we use it.
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options'));
-            }
-          }
-        }
-        break;
-      case 'style_plugin':
-        // This if prevents resetting options to default if they don't change
-        // the plugin.
-        if ($this->get_option($section) != $form_state['values'][$section]) {
-          $plugin = views_get_plugin('style', $form_state['values'][$section]);
-          if ($plugin) {
-            $this->set_option($section, $form_state['values'][$section]);
-            $this->set_option('style_options', array());
-            // send ajax form to options page if we use it.
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options'));
-            }
-          }
-        }
-        break;
-      case 'style_options':
-        $style = TRUE;
-      case 'row_options':
-        // if row, $style will be empty.
-        $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
-        if ($plugin) {
-          $plugin->options_submit($form['options'][$section], $form_state);
-        }
-        $this->set_option($section, $form_state['values'][$section]);
-        break;
-      case 'exposed_block':
-        $this->set_option($section, (bool) $form_state['values'][$section]);
-        break;
-      case 'exposed_form':
-        $exposed_form = $this->get_option('exposed_form');
-        if ($exposed_form['type'] != $form_state['values']['exposed_form']['type']) {
-          $plugin = views_get_plugin('exposed_form', $form_state['values']['exposed_form']['type']);
-          if ($plugin) {
-            $exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array());
-            $this->set_option('exposed_form', $exposed_form);
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('exposed_form_options'));
-            }
-          }
-        }
-
-        break;
-      case 'exposed_form_options':
-        $plugin = $this->get_plugin('exposed_form');
-        if ($plugin) {
-          $exposed_form = $this->get_option('exposed_form');
-          $plugin->options_submit($form['exposed_form_options'], $form_state);
-          $exposed_form['options'] = $form_state['values'][$section];
-          $this->set_option('exposed_form', $exposed_form);
-        }
-        break;
-      case 'pager':
-        $pager = $this->get_option('pager');
-        if ($pager['type'] != $form_state['values']['pager']['type']) {
-          $plugin = views_get_plugin('pager', $form_state['values']['pager']['type']);
-          if ($plugin) {
-            // Because pagers have very similar options, let's allow pagers to
-            // try to carry the options over.
-            $plugin->init($this->view, $this->display, $pager['options']);
-
-            $pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options);
-            $this->set_option('pager', $pager);
-            if (!empty($plugin->definition['uses options'])) {
-              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('pager_options'));
-            }
-          }
-        }
-
-        break;
-      case 'pager_options':
-        $plugin = $this->get_plugin('pager');
-        if ($plugin) {
-          $pager = $this->get_option('pager');
-          $plugin->options_submit($form['pager_options'], $form_state);
-          $pager['options'] = $form_state['values'][$section];
-          $this->set_option('pager', $pager);
-        }
-        break;
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->options_submit($form, $form_state);
-    }
-  }
-
-  /**
-   * If override/revert was clicked, perform the proper toggle.
-   */
-  function options_override($form, &$form_state) {
-    $this->set_override($form_state['section']);
-  }
-
-  /**
-   * Flip the override setting for the given section.
-   *
-   * @param string $section
-   *   Which option should be marked as overridden, for example "filters".
-   * @param bool $new_state
-   *   Select the new state of the option.
-   *     - TRUE: Revert to default.
-   *     - FALSE: Mark it as overridden.
-   */
-  function set_override($section, $new_state = NULL) {
-    $options = $this->defaultable_sections($section);
-    if (!$options) {
-      return;
-    }
-
-    if (!isset($new_state)) {
-      $new_state = empty($this->options['defaults'][$section]);
-    }
-
-    // For each option that is part of this group, fix our settings.
-    foreach ($options as $option) {
-      if ($new_state) {
-        // Revert to defaults.
-        unset($this->options[$option]);
-        unset($this->display->display_options[$option]);
-      }
-      else {
-        // copy existing values into our display.
-        $this->options[$option] = $this->get_option($option);
-        $this->display->display_options[$option] = $this->options[$option];
-      }
-      $this->options['defaults'][$option] = $new_state;
-      $this->display->display_options['defaults'][$option] = $new_state;
-    }
-  }
-
-  /**
-   * Inject anything into the query that the display handler needs.
-   */
-  function query() {
-    foreach ($this->extender as $extender) {
-      $extender->query();
-    }
-  }
-
-  /**
-   * Not all display plugins will support filtering
-   */
-  function render_filters() { }
-
-  /**
-   * Not all display plugins will suppert pager rendering.
-   */
-  function render_pager() {
-    return TRUE;
-  }
-
-  /**
-   * Render the 'more' link
-   */
-  function render_more_link() {
-    if ($this->use_more() && ($this->use_more_always() || (!empty($this->view->query->pager) && $this->view->query->pager->has_more_records()))) {
-      $path = $this->get_path();
-
-      if ($this->get_option('link_display') == 'custom_url' && $override_path = $this->get_option('link_url')) {
-        $tokens = $this->get_arguments_tokens();
-        $path = strtr($override_path, $tokens);
-      }
-
-      if ($path) {
-        if (empty($override_path)) {
-          $path = $this->view->get_url(NULL, $path);
-        }
-        $url_options = array();
-        if (!empty($this->view->exposed_raw_input)) {
-          $url_options['query'] = $this->view->exposed_raw_input;
-        }
-        $theme = views_theme_functions('views_more', $this->view, $this->display);
-        $path = check_url(url($path, $url_options));
-
-        return theme($theme, array('more_url' => $path, 'link_text' => check_plain($this->use_more_text()), 'view' => $this->view));
-      }
-    }
-  }
-
-
-  /**
-   * Legacy functions.
-   */
-
-  /**
-   * Render the header of the view.
-   */
-  function render_header() {
-    $empty = !empty($this->view->result);
-    return $this->render_area('header', $empty);
-  }
-
-  /**
-   * Render the footer of the view.
-   */
-  function render_footer() {
-    $empty = !empty($this->view->result);
-    return $this->render_area('footer', $empty);
-  }
-
-  function render_empty() {
-    return $this->render_area('empty');
-  }
-
-  /**
-   * If this display creates a block, implement one of these.
-   */
-  function hook_block_list($delta = 0, $edit = array()) { return array(); }
-
-  /**
-   * If this display creates a page with a menu item, implement it here.
-   */
-  function hook_menu() { return array(); }
-
-  /**
-   * Render this display.
-   */
-  function render() {
-    return theme($this->theme_functions(), array('view' => $this->view));
-  }
-
-  function render_area($area, $empty = FALSE) {
-    $return = '';
-    foreach ($this->get_handlers($area) as $area) {
-      $return .= $area->render($empty);
-    }
-    return $return;
-  }
-
-
-  /**
-   * Determine if the user has access to this display of the view.
-   */
-  function access($account = NULL) {
-    if (!isset($account)) {
-      global $user;
-      $account = $user;
-    }
-
-    // Full override.
-    if (user_access('access all views', $account)) {
-      return TRUE;
-    }
-
-    $plugin = $this->get_plugin('access');
-    if ($plugin) {
-      return $plugin->access($account);
-    }
-
-    // fallback to all access if no plugin.
-    return TRUE;
-  }
-
-  /**
-   * Set up any variables on the view prior to execution. These are separated
-   * from execute because they are extremely common and unlikely to be
-   * overridden on an individual display.
-   */
-  function pre_execute() {
-    $this->view->set_use_ajax($this->use_ajax());
-    if ($this->use_more() && !$this->use_more_always()) {
-      $this->view->get_total_rows = TRUE;
-    }
-    $this->view->init_handlers();
-    if ($this->uses_exposed()) {
-      $exposed_form = $this->get_plugin('exposed_form');
-      $exposed_form->pre_execute();
-    }
-
-    foreach ($this->extender as $extender) {
-      $extender->pre_execute();
-    }
-  }
-
-  /**
-   * When used externally, this is how a view gets run and returns
-   * data in the format required.
-   *
-   * The base class cannot be executed.
-   */
-  function execute() { }
-
-  /**
-   * Fully render the display for the purposes of a live preview or
-   * some other AJAXy reason.
-   */
-  function preview() { return $this->view->render(); }
-
-  /**
-   * Displays can require a certain type of style plugin. By default, they will
-   * be 'normal'.
-   */
-  function get_style_type() { return 'normal'; }
-
-  /**
-   * Make sure the display and all associated handlers are valid.
-   *
-   * @return
-   *   Empty array if the display is valid; an array of error strings if it is not.
-   */
-  function validate() {
-    $errors = array();
-    // Make sure displays that use fields HAVE fields.
-    if ($this->uses_fields()) {
-      $fields = FALSE;
-      foreach ($this->get_handlers('field') as $field) {
-        if (empty($field->options['exclude'])) {
-          $fields = TRUE;
-        }
-      }
-
-      if (!$fields) {
-        $errors[] = t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display->display_title));
-      }
-    }
-
-    if ($this->has_path() && !$this->get_option('path')) {
-      $errors[] = t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display->display_title));
-    }
-
-    // Validate style plugin
-    $style = $this->get_plugin();
-    if (empty($style)) {
-      $errors[] = t('Display "@display" has an invalid style plugin.', array('@display' => $this->display->display_title));
-    }
-    else {
-      $result = $style->validate();
-      if (!empty($result) && is_array($result)) {
-        $errors = array_merge($errors, $result);
-      }
-    }
-
-    // Validate query plugin.
-    $query = $this->get_plugin('query');
-    $result = $query->validate();
-    if (!empty($result) && is_array($result)) {
-      $errors = array_merge($errors, $result);
-    }
-
-    // Validate handlers
-    foreach (View::views_object_types() as $type => $info) {
-      foreach ($this->get_handlers($type) as $handler) {
-        $result = $handler->validate();
-        if (!empty($result) && is_array($result)) {
-          $errors = array_merge($errors, $result);
-        }
-      }
-    }
-
-    return $errors;
-  }
-
-  /**
-   * Check if the provided identifier is unique.
-   *
-   * @param string $id
-   *   The id of the handler which is checked.
-   * @param string $identifier
-   *   The actual get identifier configured in the exposed settings.
-   *
-   * @return bool
-   *   Returns whether the identifier is unique on all handlers.
-   *
-   */
-  function is_identifier_unique($id, $identifier) {
-    foreach (View::views_object_types() as $type => $info) {
-      foreach ($this->get_handlers($type) as $key => $handler) {
-        if ($handler->can_expose() && $handler->is_exposed()) {
-          if ($id != $key && $identifier == $handler->options['expose']['identifier']) {
-            return FALSE;
-          }
-        }
-      }
-    }
-    return TRUE;
-  }
-
-  /**
-   * Provide the block system with any exposed widget blocks for this display.
-   */
-  function get_special_blocks() {
-    $blocks = array();
-
-    if ($this->uses_exposed_form_in_block()) {
-      $delta = '-exp-' . $this->view->name . '-' . $this->display->id;
-      $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id));
-
-      $blocks[$delta] = array(
-        'info' => $desc,
-        'cache' => DRUPAL_NO_CACHE,
-      );
-    }
-
-    return $blocks;
-  }
-
-  /**
-   * Render any special blocks provided for this display.
-   */
-  function view_special_blocks($type) {
-    if ($type == '-exp') {
-      // avoid interfering with the admin forms.
-      if (arg(0) == 'admin' && arg(1) == 'structure' && arg(2) == 'views') {
-        return;
-      }
-      $this->view->init_handlers();
-
-      if ($this->uses_exposed() && $this->get_option('exposed_block')) {
-        $exposed_form = $this->get_plugin('exposed_form');
-        return array(
-          'content' => $exposed_form->render_exposed_form(TRUE),
-        );
-      }
-    }
-  }
-
-  /**
-   * Override of export_option()
-   *
-   * Because displays do not want to export options that are NOT overridden from the
-   * default display, we need some special handling during the export process.
-   */
-  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
-    // The $prefix is wrong because we store our actual options a little differently:
-    $prefix = '$handler->display->display_options';
-    $output = '';
-    if (!$parents && !$this->is_default_display()) {
-      // Do not export items that are not overridden.
-      if ($this->is_defaulted($option)) {
-        return;
-      }
-
-      // If this is not defaulted and is overrideable, flip the switch to say this
-      // is overridden.
-      if ($this->defaultable_sections($option)) {
-        $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n";
-      }
-    }
-
-    $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
-    return $output;
-  }
-
-  /**
-   * Special method to export items that have handlers.
-   *
-   * This method was specified in the option_definition() as the method to utilize to
-   * export fields, filters, sort criteria, relationships and arguments. This passes
-   * the export off to the individual handlers so that they can export themselves
-   * properly.
-   */
-  function export_handler($indent, $prefix, $storage, $option, $definition, $parents) {
-    $output = '';
-
-    // cut the 's' off because the data is stored as the plural form but we need
-    // the singular form. Who designed that anyway? Oh yeah, I did. :(
-    if ($option != 'header' && $option != 'footer' && $option != 'empty') {
-      $type = substr($option, 0, -1);
-    }
-    else {
-      $type = $option;
-    }
-    $types = View::views_object_types();
-    foreach ($storage[$option] as $id => $info) {
-      if (!empty($types[$type]['type'])) {
-        $handler_type = $types[$type]['type'];
-      }
-      else {
-        $handler_type = $type;
-      }
-      // If aggregation is on, the group type might override the actual
-      // handler that is in use. This piece of code checks that and,
-      // if necessary, sets the override handler.
-      $override = NULL;
-      if ($this->use_group_by() && !empty($info['group_type'])) {
-        if (empty($this->view->query)) {
-          $this->view->init_query();
-        }
-        $aggregate = $this->view->query->get_aggregation_info();
-        if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
-          $override = $aggregate[$info['group_type']]['handler'][$type];
-        }
-      }
-      $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
-      if ($handler) {
-        $handler->init($this->view, $info);
-        $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n";
-        $output .= $handler->export_options($indent, $prefix . "['$option']['$id']");
-      }
-
-      // Prevent reference problems.
-      unset($handler);
-    }
-
-    return $output;
-  }
-
-  /**
-   * Special handling for the style export.
-   *
-   * Styles are stored as style_plugin and style_options or row_plugin and
-   * row_options accordingly. The options are told not to export, and the
-   * export for the plugin should export both.
-   */
-  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
-    $output = '';
-    $style_plugin = $this->get_plugin();
-    if ($option == 'style_plugin') {
-      $type = 'style';
-      $options_field = 'style_options';
-      $plugin = $style_plugin;
-    }
-    else {
-      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
-        return;
-      }
-
-      $type = 'row';
-      $options_field = 'row_options';
-      $plugin = $this->get_plugin('row');
-      // If the style plugin doesn't use row plugins, don't even bother.
-    }
-
-    if ($plugin) {
-      // Write which plugin to use.
-      $value = $this->get_option($option);
-      $output .= $indent . $prefix . "['$option'] = '$value';\n";
-
-      // Pass off to the plugin to export itself.
-      $output .= $plugin->export_options($indent, $prefix . "['$options_field']");
-    }
-
-    return $output;
-  }
-
-  /**
-   * Special handling for plugin export
-   *
-   * Plugins other than styles are stored in array with 'type' being the key
-   * to the plugin. For modern plugins, the options are stored in the 'options'
-   * array, but for legacy plugins (access and cache) options are stored as
-   * siblings to the type.
-   */
-  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
-    $output = '';
-    $plugin_type = end($parents);
-    $plugin = $this->get_plugin($plugin_type);
-    if ($plugin) {
-      // Write which plugin to use.
-      $value = $storage[$option];
-      $new_prefix = $prefix . "['$plugin_type']";
-
-      $output .= $indent . $new_prefix . "['$option'] = '$value';\n";
-
-      if ($plugin_type != 'access' && $plugin_type!= 'cache') {
-        $new_prefix .= "['options']";
-      }
-
-      // Pass off to the plugin to export itself.
-      $output .= $plugin->export_options($indent, $new_prefix);
-    }
-
-    return $output;
-  }
-
-  function unpack_style($indent, $prefix, $storage, $option, $definition, $parents) {
-    $output = '';
-    $style_plugin = $this->get_plugin();
-    if ($option == 'style_plugin') {
-      $type = 'style';
-      $options_field = 'style_options';
-      $plugin = $style_plugin;
-    }
-    else {
-      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
-        return;
-      }
-
-      $type = 'row';
-      $options_field = 'row_options';
-      $plugin = $this->get_plugin('row');
-      // If the style plugin doesn't use row plugins, don't even bother.
-    }
-
-    if ($plugin) {
-      return $plugin->unpack_translatables($translatable, $parents);
-    }
-  }
-
-  /**
-   * Special handling for plugin unpacking.
-   */
-  function unpack_plugin(&$translatable, $storage, $option, $definition, $parents) {
-    $plugin_type = end($parents);
-    $plugin = $this->get_plugin($plugin_type);
-    if ($plugin) {
-      // Write which plugin to use.
-      return $plugin->unpack_translatables($translatable, $parents);
-    }
-  }
-
-    /**
-   * Special method to unpack items that have handlers.
-   *
-   * This method was specified in the option_definition() as the method to utilize to
-   * export fields, filters, sort criteria, relationships and arguments. This passes
-   * the export off to the individual handlers so that they can export themselves
-   * properly.
-   */
-  function unpack_handler(&$translatable, $storage, $option, $definition, $parents) {
-    $output = '';
-
-    // cut the 's' off because the data is stored as the plural form but we need
-    // the singular form. Who designed that anyway? Oh yeah, I did. :(
-    if ($option != 'header' && $option != 'footer' && $option != 'empty') {
-      $type = substr($option, 0, -1);
-    }
-    else {
-      $type = $option;
-    }
-    $types = View::views_object_types();
-    foreach ($storage[$option] as $id => $info) {
-      if (!empty($types[$type]['type'])) {
-        $handler_type = $types[$type]['type'];
-      }
-      else {
-        $handler_type = $type;
-      }
-      $handler = views_get_handler($info['table'], $info['field'], $handler_type);
-      if ($handler) {
-        $handler->init($this->view, $info);
-        $handler->unpack_translatables($translatable, array_merge($parents, array($type, $info['table'], $info['id'])));
-      }
-
-      // Prevent reference problems.
-      unset($handler);
-    }
-
-    return $output;
-  }
-
-  /**
-   * Provide some helpful text for the arguments.
-   * The result should contain of an array with
-   *   - filter value present: The title of the fieldset in the argument
-   *     where you can configure what should be done with a given argument.
-   *   - filter value not present: The tiel of the fieldset in the argument
-   *     where you can configure what should be done if the argument does not
-   *     exist.
-   *   - description: A description about how arguments comes to the display.
-   *     For example blocks don't get it from url.
-   */
-  function get_argument_text() {
-    return array(
-      'filter value not present' => t('When the filter value is <em>NOT</em> available'),
-      'filter value present' => t('When the filter value <em>IS</em> available or a default is provided'),
-      'description' => t("This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default'."),
-    );
-  }
-
-  /**
-   * Provide some helpful text for pagers.
-   *
-   * The result should contain of an array within
-   *   - items per page title
-   */
-  function get_pager_text() {
-    return array(
-      'items per page title' => t('Items to display'),
-      'items per page description' => t('The number of items to display. Enter 0 for no limit.')
-    );
-  }
-}
-
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_display_attachment.inc b/plugins/views_plugin_display_attachment.inc
deleted file mode 100644
index 91c8d1f..0000000
--- a/plugins/views_plugin_display_attachment.inc
+++ /dev/null
@@ -1,282 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the attachment display plugin.
- */
-
-/**
- * The plugin that handles an attachment display.
- *
- * Attachment displays are secondary displays that are 'attached' to a primary
- * display. Effectively they are a simple way to get multiple views within
- * the same view. They can share some information.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_attachment extends views_plugin_display {
-  function option_definition () {
-    $options = parent::option_definition();
-
-    $options['displays'] = array('default' => array());
-    $options['attachment_position'] = array('default' => 'before');
-    $options['inherit_arguments'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['inherit_exposed_filters'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['inherit_pager'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['render_pager'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  function execute() {
-    return $this->view->render($this->display->id);
-  }
-
-  function attachment_positions($position = NULL) {
-    $positions = array(
-      'before' => t('Before'),
-      'after' => t('After'),
-      'both' => t('Both'),
-    );
-
-    if ($position) {
-      return $positions[$position];
-    }
-
-    return $positions;
-  }
-
-  /**
-   * Provide the summary for attachment options in the views UI.
-   *
-   * This output is returned as an array.
-   */
-  function options_summary(&$categories, &$options) {
-    // It is very important to call the parent function here:
-    parent::options_summary($categories, $options);
-
-    $categories['attachment'] = array(
-      'title' => t('Attachment settings'),
-      'column' => 'second',
-      'build' => array(
-        '#weight' => -10,
-      ),
-    );
-
-    $displays = array_filter($this->get_option('displays'));
-    if (count($displays) > 1) {
-      $attach_to = t('Multiple displays');
-    }
-    elseif (count($displays) == 1) {
-      $display = array_shift($displays);
-      if (!empty($this->view->display[$display])) {
-        $attach_to = check_plain($this->view->display[$display]->display_title);
-      }
-    }
-
-    if (!isset($attach_to)) {
-      $attach_to = t('Not defined');
-    }
-
-    $options['displays'] = array(
-      'category' => 'attachment',
-      'title' => t('Attach to'),
-      'value' => $attach_to,
-    );
-
-    $options['attachment_position'] = array(
-      'category' => 'attachment',
-      'title' => t('Attachment position'),
-      'value' => $this->attachment_positions($this->get_option('attachment_position')),
-    );
-
-    $options['inherit_arguments'] = array(
-      'category' => 'attachment',
-      'title' => t('Inherit contextual filters'),
-      'value' => $this->get_option('inherit_arguments') ? t('Yes') : t('No'),
-    );
-
-    $options['inherit_exposed_filters'] = array(
-      'category' => 'attachment',
-      'title' => t('Inherit exposed filters'),
-      'value' => $this->get_option('inherit_exposed_filters') ? t('Yes') : t('No'),
-    );
-
-    $options['inherit_pager'] = array(
-      'category' => 'pager',
-      'title' => t('Inherit pager'),
-      'value' => $this->get_option('inherit_pager') ? t('Yes') : t('No'),
-    );
-
-    $options['render_pager'] = array(
-      'category' => 'pager',
-      'title' => t('Render pager'),
-      'value' => $this->get_option('render_pager') ? t('Yes') : t('No'),
-    );
-
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_form($form, $form_state);
-
-    switch ($form_state['section']) {
-      case 'inherit_arguments':
-        $form['#title'] .= t('Inherit contextual filters');
-        $form['inherit_arguments'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Inherit'),
-          '#description' => t('Should this display inherit its contextual filter values from the parent display to which it is attached?'),
-          '#default_value' => $this->get_option('inherit_arguments'),
-        );
-        break;
-      case 'inherit_exposed_filters':
-        $form['#title'] .= t('Inherit exposed filters');
-        $form['inherit_exposed_filters'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Inherit'),
-          '#description' => t('Should this display inherit its exposed filter values from the parent display to which it is attached?'),
-          '#default_value' => $this->get_option('inherit_exposed_filters'),
-        );
-        break;
-      case 'inherit_pager':
-        $form['#title'] .= t('Inherit pager');
-        $form['inherit_pager'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Inherit'),
-          '#description' => t('Should this display inherit its paging values from the parent display to which it is attached?'),
-          '#default_value' => $this->get_option('inherit_pager'),
-        );
-        break;
-      case 'render_pager':
-        $form['#title'] .= t('Render pager');
-        $form['render_pager'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Render'),
-          '#description' => t('Should this display render the pager values? This is only meaningful if inheriting a pager.'),
-          '#default_value' => $this->get_option('render_pager'),
-        );
-        break;
-      case 'attachment_position':
-        $form['#title'] .= t('Position');
-        $form['attachment_position'] = array(
-          '#type' => 'radios',
-          '#description' => t('Attach before or after the parent display?'),
-          '#options' => $this->attachment_positions(),
-          '#default_value' => $this->get_option('attachment_position'),
-        );
-        break;
-      case 'displays':
-        $form['#title'] .= t('Attach to');
-        $displays = array();
-        foreach ($this->view->display as $display_id => $display) {
-          if (!empty($display->handler) && $display->handler->accept_attachments()) {
-            $displays[$display_id] = $display->display_title;
-          }
-        }
-        $form['displays'] = array(
-          '#type' => 'checkboxes',
-          '#description' => t('Select which display or displays this should attach to.'),
-          '#options' => $displays,
-          '#default_value' => $this->get_option('displays'),
-        );
-        break;
-    }
-  }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_submit($form, $form_state);
-    switch ($form_state['section']) {
-      case 'inherit_arguments':
-      case 'inherit_pager':
-      case 'render_pager':
-      case 'inherit_exposed_filters':
-      case 'attachment_position':
-      case 'displays':
-        $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
-        break;
-    }
-  }
-
-  /**
-   * Attach to another view.
-   */
-  function attach_to($display_id) {
-    $displays = $this->get_option('displays');
-
-    if (empty($displays[$display_id])) {
-      return;
-    }
-
-    if (!$this->access()) {
-      return;
-    }
-
-    // Get a fresh view because our current one has a lot of stuff on it because it's
-    // already been executed.
-    $view = $this->view->clone_view();
-    $view->original_args = $view->args;
-
-    $args = $this->get_option('inherit_arguments') ? $this->view->args : array();
-    $view->set_arguments($args);
-    $view->set_display($this->display->id);
-    if ($this->get_option('inherit_pager')) {
-      $view->display_handler->use_pager = $this->view->display[$display_id]->handler->use_pager();
-      $view->display_handler->set_option('pager', $this->view->display[$display_id]->handler->get_option('pager'));
-    }
-
-    $attachment = $view->execute_display($this->display->id, $args);
-
-    switch ($this->get_option('attachment_position')) {
-      case 'before':
-        $this->view->attachment_before .= $attachment;
-        break;
-      case 'after':
-        $this->view->attachment_after .= $attachment;
-        break;
-      case 'both':
-        $this->view->attachment_before .= $attachment;
-        $this->view->attachment_after .= $attachment;
-        break;
-    }
-
-    $view->destroy();
-  }
-
-  /**
-   * Attachment displays only use exposed widgets if
-   * they are set to inherit the exposed filter settings
-   * of their parent display.
-   */
-  function uses_exposed() {
-    if (!empty($this->options['inherit_exposed_filters']) && parent::uses_exposed()) {
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  /**
-   * If an attachment is set to inherit the exposed filter
-   * settings from its parent display, then don't render and
-   * display a second set of exposed filter widgets.
-   */
-  function displays_exposed() {
-    return $this->options['inherit_exposed_filters'] ? FALSE : TRUE;
-  }
-
-  function use_pager() {
-    return !empty($this->use_pager);
-  }
-
-  function render_pager() {
-    return !empty($this->use_pager) && $this->get_option('render_pager');
-  }
-}
diff --git a/plugins/views_plugin_display_block.inc b/plugins/views_plugin_display_block.inc
deleted file mode 100644
index 2033100..0000000
--- a/plugins/views_plugin_display_block.inc
+++ /dev/null
@@ -1,238 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the block display plugin.
- */
-
-/**
- * The plugin that handles a block.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_block extends views_plugin_display {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['block_description'] = array('default' => '', 'translatable' => TRUE);
-    $options['block_caching'] = array('default' => DRUPAL_NO_CACHE);
-
-    return $options;
-  }
-
-  /**
-   * The default block handler doesn't support configurable items,
-   * but extended block handlers might be able to do interesting
-   * stuff with it.
-   */
-  function execute_hook_block_list($delta = 0, $edit = array()) {
-    $delta = $this->view->name . '-' . $this->display->id;
-    $desc = $this->get_option('block_description');
-
-    if (empty($desc)) {
-      if ($this->display->display_title == $this->definition['title']) {
-        $desc = t('View: !view', array('!view' => $this->view->get_human_name()));
-      }
-      else {
-        $desc = t('View: !view: !display', array('!view' => $this->view->get_human_name(), '!display' => $this->display->display_title));
-      }
-    }
-    return array(
-      $delta => array(
-        'info' => $desc,
-        'cache' => $this->get_cache_type()
-      ),
-    );
-  }
-
-  /**
-   * The display block handler returns the structure necessary for a block.
-   */
-  function execute() {
-    // Prior to this being called, the $view should already be set to this
-    // display, and arguments should be set on the view.
-    $info['content'] = $this->view->render();
-    $info['subject'] = filter_xss_admin($this->view->get_title());
-    if (!empty($this->view->result) || $this->get_option('empty') || !empty($this->view->style_plugin->definition['even empty'])) {
-      return $info;
-    }
-  }
-
-  /**
-   * Provide the summary for page options in the views UI.
-   *
-   * This output is returned as an array.
-   */
-  function options_summary(&$categories, &$options) {
-    // It is very important to call the parent function here:
-    parent::options_summary($categories, $options);
-
-    $categories['block'] = array(
-      'title' => t('Block settings'),
-      'column' => 'second',
-      'build' => array(
-        '#weight' => -10,
-      ),
-    );
-
-    $block_description = strip_tags($this->get_option('block_description'));
-    if (empty($block_description)) {
-      $block_description = t('None');
-    }
-
-    $options['block_description'] = array(
-      'category' => 'block',
-      'title' => t('Block name'),
-      'value' => views_ui_truncate($block_description, 24),
-    );
-
-    $types = $this->block_caching_modes();
-    $options['block_caching'] = array(
-      'category' => 'other',
-      'title' => t('Block caching'),
-      'value' => $types[$this->get_cache_type()],
-    );
-  }
-
-  /**
-   * Provide a list of core's block caching modes.
-   */
-  function block_caching_modes() {
-    return array(
-      DRUPAL_NO_CACHE => t('Do not cache'),
-      DRUPAL_CACHE_GLOBAL => t('Cache once for everything (global)'),
-      DRUPAL_CACHE_PER_PAGE => t('Per page'),
-      DRUPAL_CACHE_PER_ROLE => t('Per role'),
-      DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE => t('Per role per page'),
-      DRUPAL_CACHE_PER_USER => t('Per user'),
-      DRUPAL_CACHE_PER_USER | DRUPAL_CACHE_PER_PAGE => t('Per user per page'),
-    );
-  }
-
-  /**
-   * Provide a single method to figure caching type, keeping a sensible default
-   * for when it's unset.
-   */
-  function get_cache_type() {
-    $cache_type = $this->get_option('block_caching');
-    if (empty($cache_type)) {
-      $cache_type = DRUPAL_NO_CACHE;
-    }
-    return $cache_type;
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_form($form, $form_state);
-
-    switch ($form_state['section']) {
-      case 'block_description':
-        $form['#title'] .= t('Block admin description');
-        $form['block_description'] = array(
-          '#type' => 'textfield',
-          '#description' => t('This will appear as the name of this block in administer >> structure >> blocks.'),
-          '#default_value' => $this->get_option('block_description'),
-        );
-        break;
-      case 'block_caching':
-        $form['#title'] .= t('Block caching type');
-
-        $form['block_caching'] = array(
-          '#type' => 'radios',
-          '#description' => t("This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed."),
-          '#options' => $this->block_caching_modes(),
-          '#default_value' => $this->get_cache_type(),
-        );
-        break;
-      case 'exposed_form_options':
-        $this->view->init_handlers();
-        if (!$this->uses_exposed() && parent::uses_exposed()) {
-          $form['exposed_form_options']['warning'] = array(
-            '#weight' => -10,
-            '#markup' => '<div class="messages warning">' . t('Exposed filters in block displays require "Use AJAX" to be set to work correctly.') . '</div>',
-          );
-        }
-    }
-  }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_submit($form, $form_state);
-    switch ($form_state['section']) {
-      case 'display_id':
-        $this->update_block_bid($form_state['view']->name, $this->display->id, $this->display->new_id);
-        break;
-      case 'block_description':
-        $this->set_option('block_description', $form_state['values']['block_description']);
-        break;
-      case 'block_caching':
-        $this->set_option('block_caching', $form_state['values']['block_caching']);
-        $this->save_block_cache($form_state['view']->name . '-'. $form_state['display_id'], $form_state['values']['block_caching']);
-        break;
-    }
-  }
-
-  /**
-   * Block views use exposed widgets only if AJAX is set.
-   */
-    function uses_exposed() {
-      if ($this->use_ajax()) {
-        return parent::uses_exposed();
-      }
-      return FALSE;
-    }
-
-  /**
-   * Update the block delta when you change the machine readable name of the display.
-   */
-  function update_block_bid($name, $old_delta, $delta) {
-    $old_hashes = $hashes = variable_get('views_block_hashes', array());
-
-    $old_delta = $name . '-' . $old_delta;
-    $delta = $name . '-' . $delta;
-    if (strlen($old_delta) >= 32) {
-      $old_delta = md5($old_delta);
-      unset($hashes[$old_delta]);
-    }
-    if (strlen($delta) >= 32) {
-      $md5_delta = md5($delta);
-      $hashes[$md5_delta] = $delta;
-      $delta = $md5_delta;
-    }
-    db_update('block')
-      ->fields(array('delta' => $delta))
-      ->condition('delta', $old_delta)
-      ->execute();
-
-    // Update the hashes if needed.
-    if ($hashes != $old_hashes) {
-      variable_set('views_block_hashes', $hashes);
-    }
-  }
-  /**
-   * Save the block cache setting in the blocks table if this block allready
-   * exists in the blocks table. Dirty fix untill http://drupal.org/node/235673 gets in.
-   */
-  function save_block_cache($delta, $cache_setting) {
-    if (strlen($delta) >= 32) {
-      $delta = md5($delta);
-    }
-    if (db_table_exists('block') && $bid = db_query("SELECT bid FROM {block} WHERE module = 'views' AND delta = :delta", array(
-        ':delta' => $delta))->fetchField()) {
-      db_update('block')
-        ->fields(array(
-        'cache' => $cache_setting,
-        ))
-        ->condition('module','views')
-        ->condition('delta', $delta)
-        ->execute();
-    }
-  }
-}
diff --git a/plugins/views_plugin_display_default.inc b/plugins/views_plugin_display_default.inc
deleted file mode 100644
index 4b1fc08..0000000
--- a/plugins/views_plugin_display_default.inc
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the default display plugin.
- */
-
-/**
- * A plugin to handle defaults on a view.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_default extends views_plugin_display {
-  /**
-   * Determine if this display is the 'default' display which contains
-   * fallback settings
-   */
-  function is_default_display() { return TRUE; }
-
-  /**
-   * The default execute handler fully renders the view.
-   *
-   * For the simplest use:
-   * @code
-   *   $output = $view->execute_display('default', $args);
-   * @endcode
-   *
-   * For more complex usages, a view can be partially built:
-   * @code
-   *   $view->set_arguments($args);
-   *   $view->build('default'); // Build the query
-   *   $view->pre_execute(); // Pre-execute the query.
-   *   $view->execute(); // Run the query
-   *   $output = $view->render(); // Render the view
-   * @endcode
-   *
-   * If short circuited at any point, look in $view->build_info for
-   * information about the query. After execute, look in $view->result
-   * for the array of objects returned from db_query.
-   *
-   * You can also do:
-   * @code
-   *   $view->set_arguments($args);
-   *   $output = $view->render('default'); // Render the view
-   * @endcode
-   *
-   * This illustrates that render is smart enough to call build and execute
-   * if these items have not already been accomplished.
-   *
-   * Note that execute also must accomplish other tasks, such
-   * as setting page titles, breadcrumbs, and generating exposed filter
-   * data if necessary.
-   */
-  function execute() {
-    return $this->view->render($this->display->id);
-  }
-}
diff --git a/plugins/views_plugin_display_extender.inc b/plugins/views_plugin_display_extender.inc
deleted file mode 100644
index 08e981a..0000000
--- a/plugins/views_plugin_display_extender.inc
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_display_extender.
- */
-
-/**
- * @todo.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_extender extends views_plugin {
-  function init(&$view, &$display) {
-    $this->view = $view;
-    $this->display = $display;
-  }
-
-
-  /**
-   * Provide a form to edit options for this plugin.
-   */
-  function options_definition_alter(&$options) { }
-
-  /**
-   * Provide a form to edit options for this plugin.
-   */
-  function options_form(&$form, &$form_state) { }
-
-  /**
-   * Validate the options form.
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Handle any special handling on the validate form.
-   */
-  function options_submit(&$form, &$form_state) { }
-
-  /**
-   * Set up any variables on the view prior to execution.
-   */
-  function pre_execute() { }
-
-  /**
-   * Inject anything into the query that the display_extender handler needs.
-   */
-  function query() { }
-
-  /**
-   * Provide the default summary for options in the views UI.
-   *
-   * This output is returned as an array.
-   */
-  function options_summary(&$categories, &$options) { }
-
-  /**
-   * Static member function to list which sections are defaultable
-   * and what items each section contains.
-   */
-  function defaultable_sections(&$sections, $section = NULL) { }
-}
diff --git a/plugins/views_plugin_display_feed.inc b/plugins/views_plugin_display_feed.inc
deleted file mode 100644
index c8101ba..0000000
--- a/plugins/views_plugin_display_feed.inc
+++ /dev/null
@@ -1,232 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the feed display plugin.
- */
-
-use Symfony\Component\HttpFoundation\Response;
-
-/**
- * The plugin that handles a feed, such as RSS or atom.
- *
- * For the most part, feeds are page displays but with some subtle differences.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_feed extends views_plugin_display_page {
-  function init(&$view, &$display, $options = NULL) {
-    parent::init($view, $display, $options);
-
-    // Set the default row style. Ideally this would be part of the option
-    // definition, but in this case it's dependent on the view's base table,
-    // which we don't know until init().
-    $row_plugins = views_fetch_plugin_names('row', $this->get_style_type(), array($view->base_table));
-    $default_row_plugin = key($row_plugins);
-    if ($this->options['row_plugin'] == '') {
-      $this->options['row_plugin'] = $default_row_plugin;
-    }
-  }
-
-  function uses_breadcrumb() { return FALSE; }
-  function get_style_type() { return 'feed'; }
-
-  /**
-   * Feeds do not go through the normal page theming mechanism. Instead, they
-   * go through their own little theme function and then return NULL so that
-   * Drupal believes that the page has already rendered itself...which it has.
-   */
-  function execute() {
-    $output = $this->view->render();
-    if (empty($output)) {
-      return drupal_not_found();
-    }
-
-    $response = $this->view->getResponse();
-    $response->setContent($output);
-    return $response;
-  }
-
-  function preview() {
-    if (!empty($this->view->live_preview)) {
-      return '<pre>' . check_plain($this->view->render()) . '</pre>';
-    }
-    return $this->view->render();
-  }
-
-  /**
-   * Instead of going through the standard views_view.tpl.php, delegate this
-   * to the style handler.
-   */
-  function render() {
-    return $this->view->style_plugin->render($this->view->result);
-  }
-
-  function defaultable_sections($section = NULL) {
-    if (in_array($section, array('style_options', 'style_plugin', 'row_options', 'row_plugin',))) {
-      return FALSE;
-    }
-
-    $sections = parent::defaultable_sections($section);
-
-    // Tell views our sitename_title option belongs in the title section.
-    if ($section == 'title') {
-      $sections[] = 'sitename_title';
-    }
-    elseif (!$section) {
-      $sections['title'][] = 'sitename_title';
-    }
-    return $sections;
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['displays'] = array('default' => array());
-
-    // Overrides for standard stuff:
-    $options['style_plugin']['default'] = 'rss';
-    $options['style_options']['default']  = array('description' => '');
-    $options['sitename_title']['default'] = FALSE;
-    $options['row_plugin']['default'] = '';
-    $options['defaults']['default']['style_plugin'] = FALSE;
-    $options['defaults']['default']['style_options'] = FALSE;
-    $options['defaults']['default']['row_plugin'] = FALSE;
-    $options['defaults']['default']['row_options'] = FALSE;
-
-    return $options;
-  }
-
-  function options_summary(&$categories, &$options) {
-    // It is very important to call the parent function here:
-    parent::options_summary($categories, $options);
-
-    // Since we're childing off the 'page' type, we'll still *call* our
-    // category 'page' but let's override it so it says feed settings.
-    $categories['page'] = array(
-      'title' => t('Feed settings'),
-      'column' => 'second',
-      'build' => array(
-        '#weight' => -10,
-      ),
-    );
-
-    if ($this->get_option('sitename_title')) {
-      $options['title']['value'] = t('Using the site name');
-    }
-
-    // I don't think we want to give feeds menus directly.
-    unset($options['menu']);
-
-    $displays = array_filter($this->get_option('displays'));
-    if (count($displays) > 1) {
-      $attach_to = t('Multiple displays');
-    }
-    elseif (count($displays) == 1) {
-      $display = array_shift($displays);
-      if (!empty($this->view->display[$display])) {
-        $attach_to = check_plain($this->view->display[$display]->display_title);
-      }
-    }
-
-    if (!isset($attach_to)) {
-      $attach_to = t('None');
-    }
-
-    $options['displays'] = array(
-      'category' => 'page',
-      'title' => t('Attach to'),
-      'value' => $attach_to,
-    );
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    // It is very important to call the parent function here.
-    parent::options_form($form, $form_state);
-
-    switch ($form_state['section']) {
-      case 'title':
-        $title = $form['title'];
-        // A little juggling to move the 'title' field beyond our checkbox.
-        unset($form['title']);
-        $form['sitename_title'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Use the site name for the title'),
-          '#default_value' => $this->get_option('sitename_title'),
-        );
-        $form['title'] = $title;
-        $form['title']['#states'] = array(
-          'visible' => array(
-            ':input[name="sitename_title"]' => array('checked' => FALSE),
-          ),
-        );
-        break;
-      case 'displays':
-        $form['#title'] .= t('Attach to');
-        $displays = array();
-        foreach ($this->view->display as $display_id => $display) {
-          if (!empty($display->handler) && $display->handler->accept_attachments()) {
-            $displays[$display_id] = $display->display_title;
-          }
-        }
-        $form['displays'] = array(
-          '#type' => 'checkboxes',
-          '#description' => t('The feed icon will be available only to the selected displays.'),
-          '#options' => $displays,
-          '#default_value' => $this->get_option('displays'),
-        );
-        break;
-      case 'path':
-        $form['path']['#description'] = t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss.xml", putting one % in the path for each contextual filter you have defined in the view.');
-    }
-  }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_submit($form, $form_state);
-    switch ($form_state['section']) {
-      case 'title':
-        $this->set_option('sitename_title', $form_state['values']['sitename_title']);
-        break;
-      case 'displays':
-        $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
-        break;
-    }
-  }
-
-  /**
-   * Attach to another view.
-   */
-  function attach_to($display_id) {
-    $displays = $this->get_option('displays');
-    if (empty($displays[$display_id])) {
-      return;
-    }
-
-    // Defer to the feed style; it may put in meta information, and/or
-    // attach a feed icon.
-    $plugin = $this->get_plugin();
-    if ($plugin) {
-      $clone = $this->view->clone_view();
-      $clone->set_display($this->display->id);
-      $clone->build_title();
-      $plugin->attach_to($display_id, $this->get_path(), $clone->get_title());
-
-      // Clean up
-      $clone->destroy();
-      unset($clone);
-    }
-  }
-
-  function uses_link_display() {
-    return TRUE;
-  }
-}
diff --git a/plugins/views_plugin_display_page.inc b/plugins/views_plugin_display_page.inc
deleted file mode 100644
index 5c41463..0000000
--- a/plugins/views_plugin_display_page.inc
+++ /dev/null
@@ -1,632 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the page display plugin.
- */
-
-/**
- * The plugin that handles a full page.
- *
- * @ingroup views_display_plugins
- */
-class views_plugin_display_page extends views_plugin_display {
-  /**
-   * The page display has a path.
-   */
-  function has_path() { return TRUE; }
-  function uses_breadcrumb() { return TRUE; }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['path'] = array('default' => '');
-    $options['menu'] = array(
-      'contains' => array(
-        'type' => array('default' => 'none'),
-        // Do not translate menu and title as menu system will.
-        'title' => array('default' => '', 'translatable' => FALSE),
-        'description' => array('default' => '', 'translatable' => FALSE),
-        'weight' => array('default' => 0),
-        'name' => array('default' => variable_get('menu_default_node_menu', 'navigation')),
-        'context' => array('default' => ''),
-       ),
-    );
-    $options['tab_options'] = array(
-      'contains' => array(
-        'type' => array('default' => 'none'),
-        // Do not translate menu and title as menu system will.
-        'title' => array('default' => '', 'translatable' => FALSE),
-        'description' => array('default' => '', 'translatable' => FALSE),
-        'weight' => array('default' => 0),
-        'name' => array('default' => 'navigation'),
-       ),
-    );
-
-    return $options;
-  }
-
-  /**
-   * Add this display's path information to Drupal's menu system.
-   */
-  function execute_hook_menu($callbacks) {
-    $items = array();
-    // Replace % with the link to our standard views argument loader
-    // views_arg_load -- which lives in views.module
-
-    $bits = explode('/', $this->get_option('path'));
-    $page_arguments = array($this->view->name, $this->display->id);
-    $this->view->init_handlers();
-    $view_arguments = $this->view->argument;
-
-    // Replace % with %views_arg for menu autoloading and add to the
-    // page arguments so the argument actually comes through.
-    foreach ($bits as $pos => $bit) {
-      if ($bit == '%') {
-        $argument = array_shift($view_arguments);
-        if (!empty($argument->options['specify_validation']) && $argument->options['validate']['type'] != 'none') {
-          $bits[$pos] = '%views_arg';
-        }
-        $page_arguments[] = $pos;
-      }
-    }
-
-    $path = implode('/', $bits);
-
-    $access_plugin = $this->get_plugin('access');
-    if (!isset($access_plugin)) {
-      $access_plugin = views_get_plugin('access', 'none');
-    }
-
-    // Get access callback might return an array of the callback + the dynamic arguments.
-    $access_plugin_callback = $access_plugin->get_access_callback();
-
-    if (is_array($access_plugin_callback)) {
-      $access_arguments = array();
-
-      // Find the plugin arguments.
-      $access_plugin_method = array_shift($access_plugin_callback);
-      $access_plugin_arguments = array_shift($access_plugin_callback);
-      if (!is_array($access_plugin_arguments)) {
-        $access_plugin_arguments = array();
-      }
-
-      $access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments);
-
-      // Move the plugin arguments to the access arguments array.
-      $i = 1;
-      foreach ($access_plugin_arguments as $key => $value) {
-        if (is_int($value)) {
-          $access_arguments[$i] = $value;
-          $access_plugin_arguments[$key] = $i;
-          $i++;
-        }
-      }
-    }
-    else {
-      $access_arguments = array($access_plugin_callback);
-    }
-
-    if ($path) {
-      $items[$path] = array(
-        // default views page entry
-        'page callback' => 'views_page',
-        'page arguments' => $page_arguments,
-        // Default access check (per display)
-        'access callback' => 'views_access',
-        'access arguments' => $access_arguments,
-        // Identify URL embedded arguments and correlate them to a handler
-        'load arguments'  => array($this->view->name, $this->display->id, '%index'),
-      );
-      $menu = $this->get_option('menu');
-      if (empty($menu)) {
-        $menu = array('type' => 'none');
-      }
-      // Set the title and description if we have one.
-      if ($menu['type'] != 'none') {
-        $items[$path]['title'] = $menu['title'];
-        $items[$path]['description'] = $menu['description'];
-      }
-
-      if (isset($menu['weight'])) {
-        $items[$path]['weight'] = intval($menu['weight']);
-      }
-
-      switch ($menu['type']) {
-        case 'none':
-        default:
-          $items[$path]['type'] = MENU_CALLBACK;
-          break;
-        case 'normal':
-          $items[$path]['type'] = MENU_NORMAL_ITEM;
-          // Insert item into the proper menu
-          $items[$path]['menu_name'] = $menu['name'];
-          break;
-        case 'tab':
-          $items[$path]['type'] = MENU_LOCAL_TASK;
-          break;
-        case 'default tab':
-          $items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK;
-          break;
-      }
-
-      // Add context for contextual links.
-      // @see menu_contextual_links()
-      if (!empty($menu['context'])) {
-        $items[$path]['context'] = MENU_CONTEXT_INLINE;
-      }
-
-      // If this is a 'default' tab, check to see if we have to create teh
-      // parent menu item.
-      if ($menu['type'] == 'default tab') {
-        $tab_options = $this->get_option('tab_options');
-        if (!empty($tab_options['type']) && $tab_options['type'] != 'none') {
-          $bits = explode('/', $path);
-          // Remove the last piece.
-          $bit = array_pop($bits);
-
-          // we can't do this if they tried to make the last path bit variable.
-          // @todo: We can validate this.
-          if ($bit != '%views_arg' && !empty($bits)) {
-            $default_path = implode('/', $bits);
-            $items[$default_path] = array(
-              // default views page entry
-              'page callback' => 'views_page',
-              'page arguments' => $page_arguments,
-              // Default access check (per display)
-              'access callback' => 'views_access',
-              'access arguments' => $access_arguments,
-              // Identify URL embedded arguments and correlate them to a handler
-              'load arguments'  => array($this->view->name, $this->display->id, '%index'),
-              'title' => $tab_options['title'],
-              'description' => $tab_options['description'],
-              'menu_name' => $tab_options['name'],
-            );
-            switch ($tab_options['type']) {
-              default:
-              case 'normal':
-                $items[$default_path]['type'] = MENU_NORMAL_ITEM;
-                break;
-              case 'tab':
-                $items[$default_path]['type'] = MENU_LOCAL_TASK;
-                break;
-            }
-            if (isset($tab_options['weight'])) {
-              $items[$default_path]['weight'] = intval($tab_options['weight']);
-            }
-          }
-        }
-      }
-    }
-
-    return $items;
-  }
-
-  /**
-   * The display page handler returns a normal view, but it also does
-   * a drupal_set_title for the page, and does a views_set_page_view
-   * on the view.
-   */
-  function execute() {
-    // Let the world know that this is the page view we're using.
-    views_set_page_view($this->view);
-
-    // Prior to this being called, the $view should already be set to this
-    // display, and arguments should be set on the view.
-    $this->view->build();
-    if (!empty($this->view->build_info['fail'])) {
-      return drupal_not_found();
-    }
-
-    if (!empty($this->view->build_info['denied'])) {
-      return drupal_access_denied();
-    }
-
-    $this->view->get_breadcrumb(TRUE);
-
-
-    // And now render the view.
-    $render = $this->view->render();
-
-    // First execute the view so it's possible to get tokens for the title.
-    // And the title, which is much easier.
-    drupal_set_title(filter_xss_admin($this->view->get_title()), PASS_THROUGH);
-    return $render;
-  }
-
-  /**
-   * Provide the summary for page options in the views UI.
-   *
-   * This output is returned as an array.
-   */
-  function options_summary(&$categories, &$options) {
-    // It is very important to call the parent function here:
-    parent::options_summary($categories, $options);
-
-    $categories['page'] = array(
-      'title' => t('Page settings'),
-      'column' => 'second',
-      'build' => array(
-        '#weight' => -10,
-      ),
-    );
-
-    $path = strip_tags('/' . $this->get_option('path'));
-    if (empty($path)) {
-      $path = t('None');
-    }
-
-    $options['path'] = array(
-      'category' => 'page',
-      'title' => t('Path'),
-      'value' => views_ui_truncate($path, 24),
-    );
-
-    $menu = $this->get_option('menu');
-    if (!is_array($menu)) {
-      $menu = array('type' => 'none');
-    }
-    switch($menu['type']) {
-      case 'none':
-      default:
-        $menu_str = t('No menu');
-        break;
-      case 'normal':
-        $menu_str = t('Normal: @title', array('@title' => $menu['title']));
-        break;
-      case 'tab':
-      case 'default tab':
-        $menu_str = t('Tab: @title', array('@title' => $menu['title']));
-        break;
-    }
-
-    $options['menu'] = array(
-      'category' => 'page',
-      'title' => t('Menu'),
-      'value' => views_ui_truncate($menu_str, 24),
-    );
-
-    // This adds a 'Settings' link to the style_options setting if the style has options.
-    if ($menu['type'] == 'default tab') {
-      $options['menu']['setting'] = t('Parent menu item');
-      $options['menu']['links']['tab_options'] = t('Change settings for the parent menu');
-    }
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    // It is very important to call the parent function here:
-    parent::options_form($form, $form_state);
-
-    switch ($form_state['section']) {
-      case 'path':
-        $form['#title'] .= t('The menu path or URL of this view');
-        $form['#help_topic'] = 'path';
-        $form['path'] = array(
-          '#type' => 'textfield',
-          '#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
-          '#default_value' => $this->get_option('path'),
-	  '#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='),
-	  '#field_suffix' => '</span>&lrm;',
-	  '#attributes' => array('dir'=>'ltr'),
-        );
-        break;
-      case 'menu':
-        $form['#title'] .= t('Menu item entry');
-        $form['#help_topic'] = 'menu';
-        $form['menu'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-        $menu = $this->get_option('menu');
-        if (empty($menu)) {
-          $menu = array('type' => 'none', 'title' => '', 'weight' => 0);
-        }
-        $form['menu']['type'] = array(
-          '#prefix' => '<div class="views-left-30">',
-          '#suffix' => '</div>',
-          '#title' => t('Type'),
-          '#type' => 'radios',
-          '#options' => array(
-            'none' => t('No menu entry'),
-            'normal' => t('Normal menu entry'),
-            'tab' => t('Menu tab'),
-            'default tab' => t('Default menu tab')
-          ),
-          '#default_value' => $menu['type'],
-        );
-
-        $form['menu']['title'] = array(
-          '#prefix' => '<div class="views-left-50">',
-          '#title' => t('Title'),
-          '#type' => 'textfield',
-          '#default_value' => $menu['title'],
-          '#description' => t('If set to normal or tab, enter the text to use for the menu item.'),
-          '#states' => array(
-            'visible' => array(
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'normal'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'tab'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'default tab'),
-              ),
-            ),
-          ),
-        );
-        $form['menu']['description'] = array(
-          '#title' => t('Description'),
-          '#type' => 'textfield',
-          '#default_value' => $menu['description'],
-          '#description' => t("If set to normal or tab, enter the text to use for the menu item's description."),
-          '#states' => array(
-            'visible' => array(
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'normal'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'tab'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'default tab'),
-              ),
-            ),
-          ),
-        );
-
-        // Only display the menu selector if menu module is enabled.
-        if (module_exists('menu')) {
-          $form['menu']['name'] = array(
-            '#title' => t('Menu'),
-            '#type' => 'select',
-            '#options' => menu_get_menus(),
-            '#default_value' => $menu['name'],
-            '#description' => t('Insert item into an available menu.'),
-            '#states' => array(
-              'visible' => array(
-                array(
-                  ':input[name="menu[type]"]' => array('value' => 'normal'),
-                ),
-                array(
-                  ':input[name="menu[type]"]' => array('value' => 'tab'),
-                ),
-              ),
-            ),
-          );
-        }
-        else {
-          $form['menu']['name'] = array(
-            '#type' => 'value',
-            '#value' => $menu['name'],
-          );
-          $form['menu']['markup'] = array(
-            '#markup' => t('Menu selection requires the activation of menu module.'),
-          );
-        }
-        $form['menu']['weight'] = array(
-          '#title' => t('Weight'),
-          '#type' => 'textfield',
-          '#default_value' => isset($menu['weight']) ? $menu['weight'] : 0,
-          '#description' => t('The lower the weight the higher/further left it will appear.'),
-          '#states' => array(
-            'visible' => array(
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'normal'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'tab'),
-              ),
-              array(
-                ':input[name="menu[type]"]' => array('value' => 'default tab'),
-              ),
-            ),
-          ),
-        );
-        $form['menu']['context'] = array(
-          '#title' => t('Context'),
-          '#suffix' => '</div>',
-          '#type' => 'checkbox',
-          '#default_value' => !empty($menu['context']),
-          '#description' => t('Displays the link in contextual links'),
-          '#states' => array(
-            'visible' => array(
-              ':input[name="menu[type]"]' => array('value' => 'tab'),
-            ),
-          ),
-        );
-        break;
-      case 'tab_options':
-        $form['#title'] .= t('Default tab options');
-        $tab_options = $this->get_option('tab_options');
-        if (empty($tab_options)) {
-          $tab_options = array('type' => 'none', 'title' => '', 'weight' => 0);
-        }
-
-        $form['tab_markup'] = array(
-          '#markup' => '<div class="form-item description">' . t('When providing a menu item as a tab, Drupal needs to know what the parent menu item of that tab will be. Sometimes the parent will already exist, but other times you will need to have one created. The path of a parent item will always be the same path with the last part left off. i.e, if the path to this view is <em>foo/bar/baz</em>, the parent path would be <em>foo/bar</em>.') . '</div>',
-        );
-
-        $form['tab_options'] = array(
-          '#prefix' => '<div class="clearfix">',
-          '#suffix' => '</div>',
-          '#tree' => TRUE,
-        );
-        $form['tab_options']['type'] = array(
-          '#prefix' => '<div class="views-left-25">',
-          '#suffix' => '</div>',
-          '#title' => t('Parent menu item'),
-          '#type' => 'radios',
-          '#options' => array('none' => t('Already exists'), 'normal' => t('Normal menu item'), 'tab' => t('Menu tab')),
-          '#default_value' => $tab_options['type'],
-        );
-        $form['tab_options']['title'] = array(
-          '#prefix' => '<div class="views-left-75">',
-          '#title' => t('Title'),
-          '#type' => 'textfield',
-          '#default_value' => $tab_options['title'],
-          '#description' => t('If creating a parent menu item, enter the title of the item.'),
-          '#states' => array(
-            'visible' => array(
-              array(
-                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
-              ),
-              array(
-                ':input[name="tab_options[type]"]' => array('value' => 'tab'),
-              ),
-            ),
-          ),
-        );
-        $form['tab_options']['description'] = array(
-          '#title' => t('Description'),
-          '#type' => 'textfield',
-          '#default_value' => $tab_options['description'],
-          '#description' => t('If creating a parent menu item, enter the description of the item.'),
-          '#states' => array(
-            'visible' => array(
-              array(
-                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
-              ),
-              array(
-                ':input[name="tab_options[type]"]' => array('value' => 'tab'),
-              ),
-            ),
-          ),
-        );
-        // Only display the menu selector if menu module is enabled.
-        if (module_exists('menu')) {
-          $form['tab_options']['name'] = array(
-            '#title' => t('Menu'),
-            '#type' => 'select',
-            '#options' => menu_get_menus(),
-            '#default_value' => $tab_options['name'],
-            '#description' => t('Insert item into an available menu.'),
-            '#states' => array(
-              'visible' => array(
-                ':input[name="tab_options[type]"]' => array('value' => 'normal'),
-              ),
-            ),
-          );
-        }
-        else {
-          $form['tab_options']['name'] = array(
-            '#type' => 'value',
-            '#value' => $tab_options['name'],
-          );
-          $form['tab_options']['markup'] = array(
-            '#markup' => t('Menu selection requires the activation of menu module.'),
-          );
-        }
-        $form['tab_options']['weight'] = array(
-          '#suffix' => '</div>',
-          '#title' => t('Tab weight'),
-          '#type' => 'textfield',
-          '#default_value' => $tab_options['weight'],
-          '#size' => 5,
-          '#description' => t('If the parent menu item is a tab, enter the weight of the tab. The lower the number, the more to the left it will be.'),
-          '#states' => array(
-            'visible' => array(
-              ':input[name="tab_options[type]"]' => array('value' => 'tab'),
-            ),
-          ),
-        );
-        break;
-    }
-  }
-
-  function options_validate(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_validate($form, $form_state);
-    switch ($form_state['section']) {
-      case 'path':
-        if (strpos($form_state['values']['path'], '$arg') !== FALSE) {
-          form_error($form['path'], t('"$arg" is no longer supported. Use % instead.'));
-        }
-
-        if (strpos($form_state['values']['path'], '%') === 0) {
-          form_error($form['path'], t('"%" may not be used for the first segment of a path.'));
-        }
-
-        // automatically remove '/' from path.
-        $form_state['values']['path'] = trim($form_state['values']['path'], '/');
-
-        break;
-      case 'menu':
-        $path = $this->get_option('path');
-        if ($form_state['values']['menu']['type'] == 'normal' && strpos($path, '%') !== FALSE) {
-          form_error($form['menu']['type'], t('Views cannot create normal menu items for paths with a % in them.'));
-        }
-
-        if ($form_state['values']['menu']['type'] == 'default tab' || $form_state['values']['menu']['type'] == 'tab') {
-          $bits = explode('/', $path);
-          $last = array_pop($bits);
-          if ($last == '%') {
-            form_error($form['menu']['type'], t('A display whose path ends with a % cannot be a tab.'));
-          }
-        }
-
-        if ($form_state['values']['menu']['type'] != 'none' && empty($form_state['values']['menu']['title'])) {
-          form_error($form['menu']['title'], t('Title is required for this menu type.'));
-        }
-        break;
-    }
-  }
-
-  function options_submit(&$form, &$form_state) {
-    // It is very important to call the parent function here:
-    parent::options_submit($form, $form_state);
-    switch ($form_state['section']) {
-      case 'path':
-        $this->set_option('path', $form_state['values']['path']);
-        break;
-      case 'menu':
-        $this->set_option('menu', $form_state['values']['menu']);
-        // send ajax form to options page if we use it.
-        if ($form_state['values']['menu']['type'] == 'default tab') {
-          views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('tab_options'));
-        }
-        break;
-      case 'tab_options':
-        $this->set_option('tab_options', $form_state['values']['tab_options']);
-        break;
-    }
-  }
-
-  function validate() {
-    $errors = parent::validate();
-
-    $menu = $this->get_option('menu');
-    if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) {
-      $errors[] = t('Display @display is set to use a menu but the menu link text is not set.', array('@display' => $this->display->display_title));
-    }
-
-    if ($menu['type'] == 'default tab') {
-      $tab_options = $this->get_option('tab_options');
-      if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) {
-        $errors[] = t('Display @display is set to use a parent menu but the parent menu link text is not set.', array('@display' => $this->display->display_title));
-      }
-    }
-
-    return $errors;
-  }
-
-  function get_argument_text() {
-    return array(
-      'filter value not present' => t('When the filter value is <em>NOT</em> in the URL'),
-      'filter value present' => t('When the filter value <em>IS</em> in the URL or a default is provided'),
-      'description' => t('The contextual filter values is provided by the URL.'),
-    );
-  }
-
-  function get_pager_text() {
-    return array(
-      'items per page title' => t('Items per page'),
-      'items per page description' => t('The number of items to display per page. Enter 0 for no limit.')
-    );
-  }
-}
diff --git a/plugins/views_plugin_exposed_form.inc b/plugins/views_plugin_exposed_form.inc
deleted file mode 100644
index 8ba5919..0000000
--- a/plugins/views_plugin_exposed_form.inc
+++ /dev/null
@@ -1,325 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_exposed_form.
- */
-
-/**
- * @defgroup views_exposed_form_plugins Views exposed form plugins
- * @{
- * Plugins that handle the validation/submission and rendering of exposed forms.
- *
- * If needed, it is possible to use them to add additional form elements.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The base plugin to handle exposed filter forms.
- */
-class views_plugin_exposed_form extends views_plugin {
-
-  /**
-   * Initialize the plugin.
-   *
-   * @param $view
-   *   The view object.
-   * @param $display
-   *   The display handler.
-   */
-  function init(&$view, &$display, $options = array()) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    $this->unpack_options($this->options, $options);
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['submit_button'] = array('default' => t('Apply'), 'translatable' => TRUE);
-    $options['reset_button'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['reset_button_label'] = array('default' => 'Reset', 'translatable' => TRUE);
-    $options['exposed_sorts_label'] = array('default' => 'Sort by', 'translatable' => TRUE);
-    $options['sort_asc_label'] = array('default' => 'Asc', 'translatable' => TRUE);
-    $options['sort_desc_label'] = array('default' => 'Desc', 'translatable' => TRUE);
-    $options['autosubmit'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['autosubmit_hide'] = array('default' => TRUE, 'bool' => TRUE);
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['submit_button'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Submit button text'),
-      '#description' => t('Text to display in the submit button of the exposed form.'),
-      '#default_value' => $this->options['submit_button'],
-      '#required' => TRUE,
-    );
-
-    $form['reset_button'] = array (
-      '#type' => 'checkbox',
-      '#title' => t('Include reset button'),
-      '#description' => t('If checked the exposed form will provide a button to reset all the applied exposed filters'),
-      '#default_value' => $this->options['reset_button'],
-    );
-
-    $form['reset_button_label'] = array(
-     '#type' => 'textfield',
-      '#title' => t('Reset button label'),
-      '#description' => t('Text to display in the reset button of the exposed form.'),
-      '#default_value' => $this->options['reset_button_label'],
-      '#required' => TRUE,
-      '#states' => array(
-        'invisible' => array(
-          'input[name="exposed_form_options[reset_button]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-
-    $form['exposed_sorts_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Exposed sorts label'),
-      '#description' => t('Text to display as the label of the exposed sort select box.'),
-      '#default_value' => $this->options['exposed_sorts_label'],
-      '#required' => TRUE,
-    );
-
-    $form['sort_asc_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Ascending'),
-      '#description' => t('Text to use when exposed sort is ordered ascending.'),
-      '#default_value' => $this->options['sort_asc_label'],
-      '#required' => TRUE,
-    );
-
-    $form['sort_desc_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Descending'),
-      '#description' => t('Text to use when exposed sort is ordered descending.'),
-      '#default_value' => $this->options['sort_desc_label'],
-      '#required' => TRUE,
-    );
-
-    $form['autosubmit'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Autosubmit'),
-      '#description' => t('Automatically submit the form once an element is changed.'),
-      '#default_value' => $this->options['autosubmit'],
-    );
-
-    $form['autosubmit_hide'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Hide submit button'),
-      '#description' => t('Hide submit button if javascript is enabled.'),
-      '#default_value' => $this->options['autosubmit_hide'],
-      '#states' => array(
-        'invisible' => array(
-          'input[name="exposed_form_options[autosubmit]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-  }
-
-  /**
-   * Render the exposed filter form.
-   *
-   * This actually does more than that; because it's using FAPI, the form will
-   * also assign data to the appropriate handlers for use in building the
-   * query.
-   */
-  function render_exposed_form($block = FALSE) {
-    // Deal with any exposed filters we may have, before building.
-    $form_state = array(
-      'view' => &$this->view,
-      'display' => &$this->display,
-      'method' => 'get',
-      'rerender' => TRUE,
-      'no_redirect' => TRUE,
-      'always_process' => TRUE,
-    );
-
-    // Some types of displays (eg. attachments) may wish to use the exposed
-    // filters of their parent displays instead of showing an additional
-    // exposed filter form for the attachment as well as that for the parent.
-    if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
-      unset($form_state['rerender']);
-    }
-
-    if (!empty($this->ajax)) {
-      $form_state['ajax'] = TRUE;
-    }
-
-    $form_state['exposed_form_plugin'] = $this;
-    $form = drupal_build_form('views_exposed_form', $form_state);
-    $output = drupal_render($form);
-
-    if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
-      return "";
-    }
-    else {
-      return $output;
-    }
-  }
-
-  function query() {
-    $view = $this->view;
-    $exposed_data = isset($view->exposed_data) ? $view->exposed_data : array();
-    $sort_by = isset($exposed_data['sort_by']) ? $exposed_data['sort_by'] : NULL;
-    if (!empty($sort_by)) {
-      // Make sure the original order of sorts is preserved
-      // (e.g. a sticky sort is often first)
-      if (isset($view->sort[$sort_by])) {
-        $view->query->orderby = array();
-        foreach ($view->sort as $key => $sort) {
-          if (!$sort->is_exposed()) {
-            $sort->query();
-          }
-          else if ($key == $sort_by) {
-            if (isset($exposed_data['sort_order']) && in_array($exposed_data['sort_order'], array('ASC', 'DESC'))) {
-              $sort->options['order'] = $exposed_data['sort_order'];
-            }
-            $sort->set_relationship();
-            $sort->query();
-          }
-        }
-      }
-    }
-  }
-
-  function pre_render($values) { }
-
-  function post_render(&$output) { }
-
-  function pre_execute() { }
-
-  function post_execute() { }
-
-  function exposed_form_alter(&$form, &$form_state) {
-    if (!empty($this->options['reset_button'])) {
-      $form['reset'] = array(
-        '#value' => $this->options['reset_button_label'],
-        '#type' => 'submit',
-      );
-    }
-
-    $form['submit']['#value'] = $this->options['submit_button'];
-    // Check if there is exposed sorts for this view
-    $exposed_sorts = array();
-    foreach ($this->view->sort as $id => $handler) {
-      if ($handler->can_expose() && $handler->is_exposed()) {
-        $exposed_sorts[$id] = check_plain($handler->options['expose']['label']);
-      }
-    }
-
-    if (count($exposed_sorts)) {
-      $form['sort_by'] = array(
-        '#type' => 'select',
-        '#options' => $exposed_sorts,
-        '#title' => $this->options['exposed_sorts_label'],
-      );
-      $sort_order = array(
-        'ASC' => $this->options['sort_asc_label'],
-        'DESC' => $this->options['sort_desc_label'],
-      );
-      if (isset($form_state['input']['sort_by']) && isset($this->view->sort[$form_state['input']['sort_by']])) {
-        $default_sort_order = $this->view->sort[$form_state['input']['sort_by']]->options['order'];
-      } else {
-        $first_sort = reset($this->view->sort);
-        $default_sort_order = $first_sort->options['order'];
-      }
-
-      if (!isset($form_state['input']['sort_by'])) {
-        $keys = array_keys($exposed_sorts);
-        $form_state['input']['sort_by'] = array_shift($keys);
-      }
-
-      $form['sort_order'] = array(
-        '#type' => 'select',
-        '#options' => $sort_order,
-        '#title' => t('Order'),
-        '#default_value' => $default_sort_order,
-      );
-      $form['submit']['#weight'] = 10;
-      if (isset($form['reset'])) {
-        $form['reset']['#weight'] = 10;
-      }
-    }
-
-    $pager = $this->view->display_handler->get_plugin('pager');
-    if ($pager) {
-      $pager->exposed_form_alter($form, $form_state);
-      $form_state['pager_plugin'] = $pager;
-    }
-
-
-    // Apply autosubmit values.
-    if (!empty($this->options['autosubmit'])) {
-      $form = array_merge_recursive($form, array('#attributes' => array('class' => array('ctools-auto-submit-full-form'))));
-      $form['submit']['#attributes']['class'][] = 'ctools-use-ajax';
-      $form['submit']['#attributes']['class'][] = 'ctools-auto-submit-click';
-      $form['#attached']['js'][] = drupal_get_path('module', 'ctools') . '/js/auto-submit.js';
-
-      if (!empty($this->options['autosubmit_hide'])) {
-        $form['submit']['#attributes']['class'][] = 'js-hide';
-      }
-    }
-  }
-
-  function exposed_form_validate(&$form, &$form_state) {
-    if (isset($form_state['pager_plugin'])) {
-      $form_state['pager_plugin']->exposed_form_validate($form, $form_state);
-    }
-  }
-
-  /**
-  * This function is executed when exposed form is submited.
-  *
-  * @param $form
-  *   Nested array of form elements that comprise the form.
-  * @param $form_state
-  *   A keyed array containing the current state of the form.
-  * @param $exclude
-  *   Nested array of keys to exclude of insert into
-  *   $view->exposed_raw_input
-  */
-  function exposed_form_submit(&$form, &$form_state, &$exclude) {
-    if (!empty($form_state['values']['op']) && $form_state['values']['op'] == $this->options['reset_button_label']) {
-      $this->reset_form($form, $form_state);
-    }
-    if (isset($form_state['pager_plugin'])) {
-      $form_state['pager_plugin']->exposed_form_submit($form, $form_state, $exclude);
-      $exclude[] = 'pager_plugin';
-    }
-  }
-
-  function reset_form(&$form, &$form_state) {
-    // _SESSION is not defined for users who are not logged in.
-
-    // If filters are not overridden, store the 'remember' settings on the
-    // default display. If they are, store them on this display. This way,
-    // multiple displays in the same view can share the same filters and
-    // remember settings.
-    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
-
-    if (isset($_SESSION['views'][$this->view->name][$display_id])) {
-      unset($_SESSION['views'][$this->view->name][$display_id]);
-    }
-
-    // Set the form to allow redirect.
-    if (empty($this->view->live_preview)) {
-      $form_state['no_redirect'] = FALSE;
-    }
-    else {
-      $form_state['rebuild'] = TRUE;
-      $this->view->exposed_data = array();
-    }
-
-    $form_state['values'] = array();
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_exposed_form_basic.inc b/plugins/views_plugin_exposed_form_basic.inc
deleted file mode 100644
index 73ae54a..0000000
--- a/plugins/views_plugin_exposed_form_basic.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_exposed_form_basic.
- */
-
-/**
- * Exposed form plugin that provides a basic exposed form.
- *
- * @ingroup views_exposed_form_plugins
- */
-class views_plugin_exposed_form_basic extends views_plugin_exposed_form { }
diff --git a/plugins/views_plugin_exposed_form_input_required.inc b/plugins/views_plugin_exposed_form_input_required.inc
deleted file mode 100644
index 7760cc9..0000000
--- a/plugins/views_plugin_exposed_form_input_required.inc
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_exposed_form_input_required.
- */
-
-/**
- * Exposed form plugin that provides an exposed form with required input.
- *
- * @ingroup views_exposed_form_plugins
- */
-class views_plugin_exposed_form_input_required extends views_plugin_exposed_form {
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['text_input_required'] = array('default' => t('Select any filter and click on Apply to see results'), 'translatable' => TRUE);
-    $options['text_input_required_format'] = array('default' => NULL);
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-
-    $form['text_input_required'] = array(
-      '#type' => 'text_format',
-      '#title' => t('Text on demand'),
-      '#description' => t('Text to display instead of results until the user selects and applies an exposed filter.'),
-      '#default_value' => $this->options['text_input_required'],
-      '#format' => isset($this->options['text_input_required_format']) ? $this->options['text_input_required_format'] : filter_default_format(),
-      '#wysiwyg' => FALSE,
-    );
-  }
-
-  function options_submit(&$form, &$form_state) {
-    $form_state['values']['exposed_form_options']['text_input_required_format'] = $form_state['values']['exposed_form_options']['text_input_required']['format'];
-    $form_state['values']['exposed_form_options']['text_input_required'] = $form_state['values']['exposed_form_options']['text_input_required']['value'];
-    parent::options_submit($form, $form_state);
-  }
-
-  function exposed_filter_applied() {
-    static $cache = NULL;
-    if (!isset($cache)) {
-      $view = $this->view;
-      if (is_array($view->filter) && count($view->filter)) {
-        foreach ($view->filter as $filter_id => $filter) {
-          if ($filter->is_exposed()) {
-            $identifier = $filter->options['expose']['identifier'];
-            if (isset($view->exposed_input[$identifier])) {
-              $cache = TRUE;
-              return $cache;
-            }
-          }
-        }
-      }
-      $cache = FALSE;
-    }
-
-    return $cache;
-  }
-
-  function pre_render($values) {
-    if (!$this->exposed_filter_applied()) {
-      $options = array(
-        'id' => 'area',
-        'table' => 'views',
-        'field' => 'area',
-        'label' => '',
-        'relationship' => 'none',
-        'group_type' => 'group',
-        'content' => $this->options['text_input_required'],
-        'format' => $this->options['text_input_required_format'],
-      );
-      $handler = views_get_handler('views', 'area', 'area');
-      $handler->init($this->view, $options);
-      $this->display->handler->handlers['empty'] = array(
-        'area' => $handler,
-      );
-      $this->display->handler->set_option('empty', array('text' => $options));
-    }
-  }
-
-  function query() {
-    if (!$this->exposed_filter_applied()) {
-      // We return with no query; this will force the empty text.
-      $this->view->built = TRUE;
-      $this->view->executed = TRUE;
-      $this->view->result = array();
-    }
-    else {
-      parent::query();
-    }
-  }
-
-}
diff --git a/plugins/views_plugin_localization.inc b/plugins/views_plugin_localization.inc
deleted file mode 100644
index 08caf9e..0000000
--- a/plugins/views_plugin_localization.inc
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the base class for views localization plugins.
- */
-
-/**
- * @defgroup views_localization_plugins Views localization plugins
- * @{
- * @todo.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The base plugin to handle localization of Views strings.
- */
-class views_plugin_localization extends views_plugin {
-  // Store for exported strings
-  var $export_strings = array();
-  var $translate = TRUE;
-
-  /**
-   * Initialize the plugin.
-   *
-   * @param $view
-   *   The view object.
-   */
-  function init(&$view) {
-    $this->view = &$view;
-  }
-
-  /**
-   * Translate a string / text with format
-   *
-   * The $source parameter is an array with the following elements:
-   * - value, source string
-   * - format, input format in case the text has some format to be applied
-   * - keys. An array of keys to identify the string. Generally constructed from
-   *   view name, display_id, and a property, e.g., 'header'.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   *
-   * @return string
-   *   Translated string / text
-   */
-  function translate($source) {
-    // Allow other modules to make changes to the string before and after translation
-    $source['pre_process'] = $this->invoke_translation_process($source, 'pre');
-    $source['translation'] = $this->translate_string($source['value'], $source['keys'], $source['format']);
-    $source['post_process'] = $this->invoke_translation_process($source, 'post');
-    return $source['translation'];
-  }
-
-  /**
-   * Translate a string.
-   *
-   * @param $string
-   *   The string to be translated.
-   * @param $keys
-   *   An array of keys to identify the string. Generally constructed from
-   *   view name, display_id, and a property, e.g., 'header'.
-   * @param $format
-   *   The input format of the string. This is optional.
-   */
-  function translate_string($string, $keys = array(), $format = '') {}
-
-  /**
-   * Save string source for translation.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   */
-  function save($source) {
-    // Allow other modules to make changes to the string before saving
-    $source['pre_process'] = $this->invoke_translation_process($source, 'pre');
-    $this->save_string($source['value'], $source['keys'], isset($source['format']) ? $source['format'] : '');
-  }
-
-  /**
-   * Save a string for translation
-   *
-   * @param $string
-   *   The string to be translated.
-   * @param $keys
-   *   An array of keys to identify the string. Generally constructed from
-   *   view name, display_id, and a property, e.g., 'header'.
-   * @param $format
-   *   The input format of the string. This is optional.
-   */
-  function save_string($string, $keys = array(), $format = '') {}
-
-  /**
-   * Delete a string.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   */
-  function delete($source) { }
-
-  /**
-   * Collect strings to be exported to code.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   */
-  function export($source) { }
-
-  /**
-   * Render any collected exported strings to code.
-   *
-   * @param $indent
-   *   An optional indentation for prettifying nested code.
-   */
-  function export_render($indent = '  ') { }
-
-  /**
-   * Invoke hook_translation_pre_process() or hook_translation_post_process().
-   *
-   * Like node_invoke_nodeapi(), this function is needed to enable both passing
-   * by reference and fetching return values.
-   */
-  function invoke_translation_process(&$value, $op) {
-    $return = array();
-    $hook = 'translation_' . $op . '_process';
-    foreach (module_implements($hook) as $module) {
-      $function = $module . '_' . $hook;
-      $result = $function($value);
-      if (isset($result)) {
-        $return[$module] = $result;
-      }
-    }
-    return $return;
-  }
-
-  function process_locale_strings($op) {
-    $this->view->init_display();
-
-    foreach ($this->view->display as $display_id => $display) {
-      $translatable = array();
-      // Special handling for display title.
-      if (isset($display->display_title)) {
-        $translatable[] = array('value' => $display->display_title, 'keys' => array('display_title'));
-      }
-      // Unpack handlers.
-      if (is_object($this->view->display[$display_id]->handler)) {
-        $this->view->display[$display_id]->handler->unpack_translatables($translatable);
-      }
-      foreach ($translatable as $data) {
-        $data['keys'] = array_merge(array($this->view->name, $display_id), $data['keys']);
-        switch ($op) {
-          case 'save':
-            $this->save($data);
-            break;
-          case 'delete':
-            $this->delete($data);
-            break;
-          case 'export':
-            $this->export($data);
-            break;
-        }
-      }
-    }
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_localization_core.inc b/plugins/views_plugin_localization_core.inc
deleted file mode 100644
index 3e144d7..0000000
--- a/plugins/views_plugin_localization_core.inc
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the Drupal core localization plugin.
- */
-
-/**
- * Localization plugin to pass translatable strings through t().
- *
- * @ingroup views_localization_plugins
- */
-class views_plugin_localization_core extends views_plugin_localization {
-
-  /**
-   * Translate a string.
-   *
-   * @param $string
-   *   The string to be translated.
-   * @param $keys
-   *   An array of keys to identify the string. Generally constructed from
-   *   view name, display_id, and a property, e.g., 'header'.
-   * @param $format
-   *   The input format of the string. This is optional.
-   */
-  function translate_string($string, $keys = array(), $format = '') {
-    return t($string);
-  }
-
-  /**
-   * Save a string for translation.
-   *
-   * @param $string
-   *   The string to be translated.
-   * @param $keys
-   *   An array of keys to identify the string. Generally constructed from
-   *   view name, display_id, and a property, e.g., 'header'.
-   * @param $format
-   *   The input format of the string. This is optional.
-   */
-  function save_string($string, $keys = array(), $format = '') {
-    $language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
-
-    // If the current language is 'en', we need to reset the language
-    // in order to trigger an update.
-    // TODO: add test for number of languages.
-    if ($language_interface->langcode == 'en') {
-      $changed = TRUE;
-      $languages = language_list();
-      $cached_language = $language_interface;
-      unset($languages['en']);
-      if (!empty($languages)) {
-        drupal_container()->set(LANGUAGE_TYPE_INTERFACE, current($languages));
-      }
-    }
-
-    t($string);
-
-    if (isset($cached_language)) {
-      drupal_container()->set(LANGUAGE_TYPE_INTERFACE, $cached_language);
-    }
-    return TRUE;
-  }
-
-  /**
-   * Delete a string.
-   *
-   * Deletion is not supported.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   */
-  function delete($source) {
-    return FALSE;
-  }
-
-  /**
-   * Collect strings to be exported to code.
-   *
-   * String identifiers are not supported so strings are anonymously in an array.
-   *
-   * @param $source
-   *   Full data for the string to be translated.
-   */
-  function export($source) {
-    if (!empty($source['value'])) {
-      $this->export_strings[] = $source['value'];
-    }
-  }
-
-  /**
-   * Render any collected exported strings to code.
-   *
-   * @param $indent
-   *   An optional indentation for prettifying nested code.
-   */
-  function export_render($indent = '  ') {
-    $output = '';
-    if (!empty($this->export_strings)) {
-      $this->export_strings = array_unique($this->export_strings);
-      $output = $indent . '$translatables[\'' . $this->view->name . '\'] = array(' . "\n";
-      foreach ($this->export_strings as $string) {
-        $output .= $indent . "  t('" . str_replace("'", "\'", $string) . "'),\n";
-      }
-      $output .= $indent . ");\n";
-    }
-    return $output;
-  }
-}
diff --git a/plugins/views_plugin_localization_none.inc b/plugins/views_plugin_localization_none.inc
deleted file mode 100644
index 620352a..0000000
--- a/plugins/views_plugin_localization_none.inc
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the 'none' localization plugin.
- */
-
-/**
- * Localization plugin for no localization.
- *
- * @ingroup views_localization_plugins
- */
-class views_plugin_localization_none extends views_plugin_localization {
-  var $translate = FALSE;
-
-  /**
-   * Translate a string; simply return the string.
-   */
-  function translate($source) {
-    return $source['value'];
-  }
-
-  /**
-   * Save a string for translation; not supported.
-   */
-  function save($source) {
-    return FALSE;
-  }
-
-  /**
-   * Delete a string; not supported.
-   */
-  function delete($source) {
-    return FALSE;
-  }
-}
diff --git a/plugins/views_plugin_pager.inc b/plugins/views_plugin_pager.inc
deleted file mode 100644
index 416d662..0000000
--- a/plugins/views_plugin_pager.inc
+++ /dev/null
@@ -1,236 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_pager.
- */
-
-/**
- * @defgroup views_pager_plugins Views pager plugins
- * @{
- * @todo.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * The base plugin to handle pager.
- */
-class views_plugin_pager extends views_plugin {
-  var $current_page = NULL;
-  var $total_items = 0;
-
-  /**
-   * Initialize the plugin.
-   *
-   * @param $view
-   *   The view object.
-   * @param $display
-   *   The display handler.
-   */
-  function init(&$view, &$display, $options = array()) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    $this->unpack_options($this->options, $options);
-  }
-
-  /**
-   * Get how many items per page this pager will display.
-   *
-   * All but the leanest pagers should probably return a value here, so
-   * most pagers will not need to override this method.
-   */
-  function get_items_per_page() {
-    return isset($this->options['items_per_page']) ? $this->options['items_per_page'] : 0;
-  }
-
-  /**
-   * Set how many items per page this pager will display.
-   *
-   * This is mostly used for things that will override the value.
-   */
-  function set_items_per_page($items) {
-    $this->options['items_per_page'] = $items;
-  }
-
-  /**
-   * Get the page offset, or how many items to skip.
-   *
-   * Even pagers that don't actually page can skip items at the beginning,
-   * so few pagers will need to override this method.
-   */
-  function get_offset() {
-    return isset($this->options['offset']) ? $this->options['offset'] : 0;
-  }
-
-  /**
-   * Set the page offset, or how many items to skip.
-   */
-  function set_offset($offset) {
-    $this->options['offset'] = $offset;
-  }
-
-  /**
-   * Get the current page.
-   *
-   * If NULL, we do not know what the current page is.
-   */
-  function get_current_page() {
-    return $this->current_page;
-  }
-
-  /**
-   * Set the current page.
-   *
-   * @param $number
-   *   If provided, the page number will be set to this. If NOT provided,
-   *   the page number will be set from the global page array.
-   */
-  function set_current_page($number = NULL) {
-    if (!is_numeric($number) || $number < 0) {
-      $number = 0;
-    }
-    $this->current_page = $number;
-  }
-
-  /**
-   * Get the total number of items.
-   *
-   * If NULL, we do not yet know what the total number of items are.
-   */
-  function get_total_items() {
-    return $this->total_items;
-  }
-
-  /**
-   * Get the pager id, if it exists
-   */
-  function get_pager_id() {
-    return isset($this->options['id']) ? $this->options['id'] : 0;
-  }
-
-  /**
-   * Provide the default form form for validating options
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Provide the default form form for submitting options
-   */
-  function options_submit(&$form, &$form_state) { }
-
-  /**
-   * Return a string to display as the clickable title for the
-   * pager plugin.
-   */
-  function summary_title() {
-    return t('Unknown');
-  }
-
-  /**
-   * Determine if this pager actually uses a pager.
-   *
-   * Only a couple of very specific pagers will set this to false.
-   */
-  function use_pager() {
-    return TRUE;
-  }
-
-  /**
-   * Determine if a pager needs a count query.
-   *
-   * If a pager needs a count query, a simple query
-   */
-  function use_count_query() {
-    return TRUE;
-  }
-
-  /**
-   * Execute the count query, which will be done just prior to the query
-   * itself being executed.
-   */
-  function execute_count_query(&$count_query) {
-    $this->total_items = $count_query->execute()->fetchField();
-    if (!empty($this->options['offset'])) {
-      $this->total_items -= $this->options['offset'];
-    }
-
-    $this->update_page_info();
-    return $this->total_items;
-  }
-
-  /**
-   * If there are pagers that need global values set, this method can
-   * be used to set them. It will be called when the count query is run.
-   */
-  function update_page_info() {
-
-  }
-
-  /**
-   * Modify the query for paging
-   *
-   * This is called during the build phase and can directly modify the query.
-   */
-  function query() { }
-
-  /**
-   * Perform any needed actions just prior to the query executing.
-   */
-  function pre_execute(&$query) { }
-
-  /**
-   * Perform any needed actions just after the query executing.
-   */
-  function post_execute(&$result) { }
-
-  /**
-   * Perform any needed actions just before rendering.
-   */
-  function pre_render(&$result) { }
-
-  /**
-   * Render the pager.
-   *
-   * Called during the view render process, this will render the
-   * pager.
-   *
-   * @param $input
-   *   Any extra GET parameters that should be retained, such as exposed
-   *   input.
-   */
-  function render($input) { }
-
-  /**
-   * Determine if there are more records available.
-   *
-   * This is primarily used to control the display of a more link.
-   */
-  function has_more_records() {
-    return $this->get_items_per_page()
-      && $this->total_items > (intval($this->current_page) + 1) * $this->get_items_per_page();
-  }
-
-  function exposed_form_alter(&$form, &$form_state) { }
-
-  function exposed_form_validate(&$form, &$form_state) { }
-
-  function exposed_form_submit(&$form, &$form_state, &$exclude) { }
-
-  function uses_exposed() {
-    return FALSE;
-  }
-
-  function items_per_page_exposed() {
-    return FALSE;
-  }
-
-  function offset_exposed() {
-    return FALSE;
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_pager_full.inc b/plugins/views_plugin_pager_full.inc
deleted file mode 100644
index dc3072a..0000000
--- a/plugins/views_plugin_pager_full.inc
+++ /dev/null
@@ -1,430 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_pager_full.
- */
-
-/**
- * The plugin to handle full pager.
- *
- * @ingroup views_pager_plugins
- */
-class views_plugin_pager_full extends views_plugin_pager {
-  function summary_title() {
-    if (!empty($this->options['offset'])) {
-      return format_plural($this->options['items_per_page'], '@count item, skip @skip', 'Paged, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
-    }
-      return format_plural($this->options['items_per_page'], '@count item', 'Paged, @count items', array('@count' => $this->options['items_per_page']));
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['items_per_page'] = array('default' => 10);
-    $options['offset'] = array('default' => 0);
-    $options['id'] = array('default' => 0);
-    $options['total_pages'] = array('default' => '');
-    // Use the same default quantity that core uses by default.
-    $options['quantity'] = array('default' => 9);
-    $options['expose'] = array(
-      'contains' => array(
-        'items_per_page' => array('default' => FALSE, 'bool' => TRUE),
-        'items_per_page_label' => array('default' => 'Items per page', 'translatable' => TRUE),
-        'items_per_page_options' => array('default' => '5, 10, 20, 40, 60'),
-        'items_per_page_options_all' => array('default' => FALSE, 'bool' => TRUE),
-        'items_per_page_options_all_label' => array('default' => '- All -', 'translatable' => TRUE),
-
-        'offset' => array('default' => FALSE, 'bool' => TRUE),
-        'offset_label' => array('default' => 'Offset', 'translatable' => TRUE),
-      ),
-    );
-    $options['tags'] = array(
-      'contains' => array(
-        'first' => array('default' => '« first', 'translatable' => TRUE),
-        'previous' => array('default' => '‹ previous', 'translatable' => TRUE),
-        'next' => array('default' => 'next ›', 'translatable' => TRUE),
-        'last' => array('default' => 'last »', 'translatable' => TRUE),
-      ),
-    );
-    return $options;
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $pager_text = $this->display->handler->get_pager_text();
-    $form['items_per_page'] = array(
-      '#title' => $pager_text['items per page title'],
-      '#type' => 'textfield',
-      '#description' => $pager_text['items per page description'],
-      '#default_value' => $this->options['items_per_page'],
-    );
-
-    $form['offset'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Offset'),
-      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
-      '#default_value' => $this->options['offset'],
-    );
-
-    $form['id'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Pager ID'),
-      '#description' => t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."),
-      '#default_value' => $this->options['id'],
-    );
-
-    $form['total_pages'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of pages'),
-      '#description' => t('The total number of pages. Leave empty to show all pages.'),
-      '#default_value' => $this->options['total_pages'],
-    );
-
-    $form['quantity'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of pager links visible'),
-      '#description' => t('Specify the number of links to pages to display in the pager.'),
-      '#default_value' => $this->options['quantity'],
-    );
-
-    $form['tags'] = array (
-      '#type' => 'fieldset',
-      '#collapsible' => FALSE,
-      '#collapsed' => FALSE,
-      '#tree' => TRUE,
-      '#title' => t('Tags'),
-      '#input' => TRUE,
-      '#description' => t('A lists of labels for the controls in the pager'),
-    );
-
-    $form['tags']['first'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Text for "first"-link'),
-      '#description' => t('Text for "first"-link'),
-      '#default_value' => $this->options['tags']['first'],
-    );
-
-    $form['tags']['previous'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Text for "previous"-link'),
-      '#description' => t('Text for "previous"-link'),
-      '#default_value' => $this->options['tags']['previous'],
-    );
-
-    $form['tags']['next'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Text for "next"-link'),
-      '#description' => t('Text for "next"-link'),
-      '#default_value' => $this->options['tags']['next'],
-    );
-
-    $form['tags']['last'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Text for "last"-link'),
-      '#description' => t('Text for "last"-link'),
-      '#default_value' => $this->options['tags']['last'],
-    );
-
-    $form['expose'] = array (
-      '#type' => 'fieldset',
-      '#collapsible' => FALSE,
-      '#collapsed' => FALSE,
-      '#tree' => TRUE,
-      '#title' => t('Exposed options'),
-      '#input' => TRUE,
-      '#description' => t('Exposing this options allows users to define their values in a exposed form when view is displayed'),
-    );
-
-    $form['expose']['items_per_page'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Expose items per page'),
-      '#description' => t('When checked, users can determine how many items per page show in a view'),
-      '#default_value' => $this->options['expose']['items_per_page'],
-    );
-
-    $form['expose']['items_per_page_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Items per page label'),
-      '#required' => TRUE,
-      '#description' => t('Label to use in the exposed items per page form element.'),
-      '#default_value' => $this->options['expose']['items_per_page_label'],
-      '#states' => array(
-        'invisible' => array(
-          'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-
-    $form['expose']['items_per_page_options'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Exposed items per page options'),
-      '#required' => TRUE,
-      '#description' => t('Set between which values the user can choose when determining the items per page. Separated by comma.'),
-      '#default_value' => $this->options['expose']['items_per_page_options'],
-      '#states' => array(
-        'invisible' => array(
-          'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-
-
-    $form['expose']['items_per_page_options_all'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Include all items option'),
-      '#description' => t('If checked, an extra item will be included to items per page to display all items'),
-      '#default_value' => $this->options['expose']['items_per_page_options_all'],
-    );
-
-    $form['expose']['items_per_page_options_all_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('All items label'),
-      '#description' => t('Which label will be used to display all items'),
-      '#default_value' => $this->options['expose']['items_per_page_options_all_label'],
-      '#states' => array(
-        'invisible' => array(
-          'input[name="pager_options[expose][items_per_page_options_all]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-
-    $form['expose']['offset'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Expose Offset'),
-      '#description' => t('When checked, users can determine how many items should be skipped at the beginning.'),
-      '#default_value' => $this->options['expose']['offset'],
-    );
-
-    $form['expose']['offset_label'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Offset label'),
-      '#required' => TRUE,
-      '#description' => t('Label to use in the exposed offset form element.'),
-      '#default_value' => $this->options['expose']['offset_label'],
-      '#states' => array(
-        'invisible' => array(
-          'input[name="pager_options[expose][offset]"]' => array('checked' => FALSE),
-        ),
-      ),
-    );
-  }
-
-  function options_validate(&$form, &$form_state) {
-    // Only accept integer values.
-    $error = FALSE;
-    $exposed_options = $form_state['values']['pager_options']['expose']['items_per_page_options'];
-    if (strpos($exposed_options, '.') !== FALSE) {
-      $error = TRUE;
-    }
-    $options = explode(',',$exposed_options);
-    if (!$error && is_array($options)) {
-      foreach ($options as $option) {
-        if (!is_numeric($option) || intval($option) == 0) {
-          $error = TRUE;
-        }
-      }
-    }
-    else {
-      $error = TRUE;
-    }
-    if ($error) {
-      form_set_error('pager_options][expose][items_per_page_options', t('Please insert a list of integer numeric values separated by commas: e.g: 10, 20, 50, 100'));
-    }
-
-    // Take sure that the items_per_page is part of the expose settings.
-    if (!empty($form_state['values']['pager_options']['expose']['items_per_page']) && !empty($form_state['values']['pager_options']['items_per_page'])) {
-      $items_per_page = $form_state['values']['pager_options']['items_per_page'];
-      if (array_search($items_per_page, $options) === FALSE) {
-        form_set_error('pager_options][expose][items_per_page_options', t('Please insert the items per page (@items_per_page) from above.',
-          array('@items_per_page' => $items_per_page))
-        );
-      }
-    }
-  }
-
-  function query() {
-    if ($this->items_per_page_exposed()) {
-      if (!empty($_GET['items_per_page']) && $_GET['items_per_page'] > 0) {
-        $this->options['items_per_page'] = $_GET['items_per_page'];
-      }
-      elseif (!empty($_GET['items_per_page']) && $_GET['items_per_page'] == 'All' && $this->options['expose']['items_per_page_options_all']) {
-        $this->options['items_per_page'] = 0;
-      }
-    }
-    if ($this->offset_exposed()) {
-      if (isset($_GET['offset']) && $_GET['offset'] >= 0) {
-        $this->options['offset'] = $_GET['offset'];
-      }
-    }
-
-    $limit = $this->options['items_per_page'];
-    $offset = $this->current_page * $this->options['items_per_page'] + $this->options['offset'];
-    if (!empty($this->options['total_pages'])) {
-      if ($this->current_page >= $this->options['total_pages']) {
-        $limit = $this->options['items_per_page'];
-        $offset = $this->options['total_pages'] * $this->options['items_per_page'];
-      }
-    }
-
-    $this->view->query->set_limit($limit);
-    $this->view->query->set_offset($offset);
-  }
-
-  function render($input) {
-    $pager_theme = views_theme_functions('pager', $this->view, $this->display);
-    // The 0, 1, 3, 4 index are correct. See theme_pager documentation.
-    $tags = array(
-      0 => $this->options['tags']['first'],
-      1 => $this->options['tags']['previous'],
-      3 => $this->options['tags']['next'],
-      4 => $this->options['tags']['last'],
-    );
-    $output = theme($pager_theme, array(
-      'tags' => $tags,
-      'element' => $this->options['id'],
-      'parameters' => $input,
-      'quantity' => $this->options['quantity'],
-    ));
-    return $output;
-  }
-
-  /**
-   * Set the current page.
-   *
-   * @param $number
-   *   If provided, the page number will be set to this. If NOT provided,
-   *   the page number will be set from the global page array.
-   */
-  function set_current_page($number = NULL) {
-    if (isset($number)) {
-      $this->current_page = $number;
-      return;
-    }
-
-    // If the current page number was not specified, extract it from the global
-    // page array.
-    global $pager_page_array;
-
-    if (empty($pager_page_array)) {
-      $pager_page_array = array();
-    }
-
-    // Fill in missing values in the global page array, in case the global page
-    // array hasn't been initialized before.
-    $page = isset($_GET['page']) ? explode(',', $_GET['page']) : array();
-
-    for ($i = 0; $i <= $this->options['id'] || $i < count($pager_page_array); $i++) {
-      $pager_page_array[$i] = empty($page[$i]) ? 0 : $page[$i];
-    }
-
-    $this->current_page = intval($pager_page_array[$this->options['id']]);
-
-    if ($this->current_page < 0) {
-      $this->current_page = 0;
-    }
-  }
-
-  function get_pager_total() {
-    if ($items_per_page = intval($this->get_items_per_page())) {
-      return ceil($this->total_items / $items_per_page);
-    }
-    else {
-      return 1;
-    }
-  }
-
-  /**
-   * Update global paging info.
-   *
-   * This is called after the count query has been run to set the total
-   * items available and to update the current page if the requested
-   * page is out of range.
-   */
-  function update_page_info() {
-    if (!empty($this->options['total_pages'])) {
-      if (($this->options['total_pages'] * $this->options['items_per_page']) < $this->total_items) {
-        $this->total_items = $this->options['total_pages'] * $this->options['items_per_page'];
-      }
-    }
-
-    // Don't set pager settings for items per page = 0.
-    $items_per_page = $this->get_items_per_page();
-    if (!empty($items_per_page)) {
-      // Dump information about what we already know into the globals.
-      global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
-      // Set the limit.
-      $pager_limits[$this->options['id']] = $this->options['items_per_page'];
-      // Set the item count for the pager.
-      $pager_total_items[$this->options['id']] = $this->total_items;
-      // Calculate and set the count of available pages.
-      $pager_total[$this->options['id']] = $this->get_pager_total();
-
-      // See if the requested page was within range:
-      if ($this->current_page < 0) {
-        $this->current_page = 0;
-      }
-      else if ($this->current_page >= $pager_total[$this->options['id']]) {
-        // Pages are numbered from 0 so if there are 10 pages, the last page is 9.
-        $this->current_page = $pager_total[$this->options['id']] - 1;
-      }
-
-      // Put this number in to guarantee that we do not generate notices when the pager
-      // goes to look for it later.
-      $pager_page_array[$this->options['id']] = $this->current_page;
-    }
-  }
-
-  function uses_exposed() {
-    return $this->items_per_page_exposed() || $this->offset_exposed();
-  }
-
-  function items_per_page_exposed() {
-    return !empty($this->options['expose']['items_per_page']);
-  }
-
-  function offset_exposed() {
-    return !empty($this->options['expose']['offset']);
-  }
-
-  function exposed_form_alter(&$form, &$form_state) {
-    if ($this->items_per_page_exposed()) {
-      $options = explode(',', $this->options['expose']['items_per_page_options']);
-      $sanitized_options = array();
-      if (is_array($options)) {
-        foreach ($options as $option) {
-          $sanitized_options[intval($option)] = intval($option);
-        }
-        if (!empty($this->options['expose']['items_per_page_options_all']) && !empty($this->options['expose']['items_per_page_options_all_label'])) {
-          $sanitized_options['All'] = $this->options['expose']['items_per_page_options_all_label'];
-        }
-        $form['items_per_page'] = array(
-          '#type' => 'select',
-          '#title' => $this->options['expose']['items_per_page_label'],
-          '#options' => $sanitized_options,
-          '#default_value' => $this->get_items_per_page(),
-        );
-      }
-    }
-
-    if ($this->offset_exposed()) {
-      $form['offset'] = array(
-        '#type' => 'textfield',
-        '#size' => 10,
-        '#maxlength' => 10,
-        '#title' => $this->options['expose']['offset_label'],
-        '#default_value' => $this->get_offset(),
-      );
-    }
-  }
-
-  function exposed_form_validate(&$form, &$form_state) {
-    if (!empty($form_state['values']['offset']) && trim($form_state['values']['offset'])) {
-      if (!is_numeric($form_state['values']['offset']) || $form_state['values']['offset'] < 0) {
-        form_set_error('offset', t('Offset must be an number greather or equal than 0.'));
-      }
-    }
-  }
-}
diff --git a/plugins/views_plugin_pager_mini.inc b/plugins/views_plugin_pager_mini.inc
deleted file mode 100644
index 2daea99..0000000
--- a/plugins/views_plugin_pager_mini.inc
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_pager_mini.
- */
-
-/**
- * The plugin to handle full pager.
- *
- * @ingroup views_pager_plugins
- */
-class views_plugin_pager_mini extends views_plugin_pager_full {
-  function summary_title() {
-    if (!empty($this->options['offset'])) {
-      return format_plural($this->options['items_per_page'], 'Mini pager, @count item, skip @skip', 'Mini pager, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
-    }
-      return format_plural($this->options['items_per_page'], 'Mini pager, @count item', 'Mini pager, @count items', array('@count' => $this->options['items_per_page']));
-  }
-
-  function render($input) {
-    $pager_theme = views_theme_functions('views_mini_pager', $this->view, $this->display);
-    return theme($pager_theme, array(
-      'parameters' => $input, 'element' => $this->options['id']));
-  }
-}
diff --git a/plugins/views_plugin_pager_none.inc b/plugins/views_plugin_pager_none.inc
deleted file mode 100644
index 12b96d0..0000000
--- a/plugins/views_plugin_pager_none.inc
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_pager_none.
- */
-
-/**
- * Plugin for views without pagers.
- *
- * @ingroup views_pager_plugins
- */
-class views_plugin_pager_none extends views_plugin_pager {
-
-  function init(&$view, &$display, $options = array()) {
-    parent::init($view, $display, $options);
-
-    // If the pager is set to none, then it should show all items.
-    $this->set_items_per_page(0);
-  }
-
-  function summary_title() {
-    if (!empty($this->options['offset'])) {
-      return t('All items, skip @skip', array('@skip' => $this->options['offset']));
-    }
-    return t('All items');
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['offset'] = array('default' => 0);
-
-    return $options;
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['offset'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Offset'),
-      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
-      '#default_value' => $this->options['offset'],
-    );
-  }
-
-  function use_pager() {
-    return FALSE;
-  }
-
-  function use_count_query() {
-    return FALSE;
-  }
-
-  function get_items_per_page() {
-    return 0;
-  }
-
-  function execute_count_query(&$count_query) {
-    // If we are displaying all items, never count. But we can update the count in post_execute.
-  }
-
-  function post_execute(&$result) {
-    $this->total_items = count($result);
-  }
-
-  function query() {
-    // The only query modifications we might do are offsets.
-    if (!empty($this->options['offset'])) {
-      $this->view->query->set_offset($this->options['offset']);
-    }
-  }
-}
diff --git a/plugins/views_plugin_pager_some.inc b/plugins/views_plugin_pager_some.inc
deleted file mode 100644
index 09452ce..0000000
--- a/plugins/views_plugin_pager_some.inc
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_pager_some.
- */
-
-/**
- * Plugin for views without pagers.
- *
- * @ingroup views_pager_plugins
- */
-class views_plugin_pager_some extends views_plugin_pager {
-  function summary_title() {
-    if (!empty($this->options['offset'])) {
-      return format_plural($this->options['items_per_page'], '@count item, skip @skip', '@count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']));
-    }
-      return format_plural($this->options['items_per_page'], '@count item', '@count items', array('@count' => $this->options['items_per_page']));
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['items_per_page'] = array('default' => 10);
-    $options['offset'] = array('default' => 0);
-
-    return $options;
-  }
-
-  /**
-   * Provide the default form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $pager_text = $this->display->handler->get_pager_text();
-    $form['items_per_page'] = array(
-      '#title' => $pager_text['items per page title'],
-      '#type' => 'textfield',
-      '#description' => $pager_text['items per page description'],
-      '#default_value' => $this->options['items_per_page'],
-    );
-
-    $form['offset'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Offset'),
-      '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'),
-      '#default_value' => $this->options['offset'],
-    );
-  }
-
-  function use_pager() {
-    return FALSE;
-  }
-
-  function use_count_query() {
-    return FALSE;
-  }
-
-  function query() {
-    $this->view->query->set_limit($this->options['items_per_page']);
-    $this->view->query->set_offset($this->options['offset']);
-  }
-}
diff --git a/plugins/views_plugin_query.inc b/plugins/views_plugin_query.inc
deleted file mode 100644
index 59982cd..0000000
--- a/plugins/views_plugin_query.inc
+++ /dev/null
@@ -1,184 +0,0 @@
-<?php
-
-/**
- * @file
- * Defines the base query class, which is the underlying layer in a View.
- */
-
-/**
- * @defgroup views_query_plugins Views query plugins
- * @{
- * A Views query plugin builds SQL to execute using the Drupal database API.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * Object used to create a SELECT query.
- */
-class views_plugin_query extends views_plugin {
-  /**
-   * A pager plugin that should be provided by the display.
-   *
-   * @var views_plugin_pager
-   */
-  var $pager = NULL;
-
-  /**
-   * Constructor; Create the basic query object and fill with default values.
-   */
-  function init($base_table, $base_field, $options) {
-    $this->base_table = $base_table;
-    $this->base_field = $base_field;
-    $this->unpack_options($this->options, $options);
-  }
-
-  /**
-   * Generate a query and a countquery from all of the information supplied
-   * to the object.
-   *
-   * @param $get_count
-   *   Provide a countquery if this is true, otherwise provide a normal query.
-   */
-  function query($get_count = FALSE) { }
-
-  /**
-   * Let modules modify the query just prior to finalizing it.
-   *
-   * @param view $view
-   *   The view which is executed.
-   */
-  function alter(&$view) {  }
-
-  /**
-   * Builds the necessary info to execute the query.
-   *
-   * @param view $view
-   *   The view which is executed.
-   */
-  function build(&$view) { }
-
-  /**
-   * Executes the query and fills the associated view object with according
-   * values.
-   *
-   * Values to set: $view->result, $view->total_rows, $view->execute_time,
-   * $view->pager['current_page'].
-   *
-   * $view->result should contain an array of objects.
-   *
-   * @param view $view
-   *   The view which is executed.
-   */
-  function execute(&$view) {  }
-
-  /**
-   * Add a signature to the query, if such a thing is feasible.
-   *
-   * This signature is something that can be used when perusing query logs to
-   * discern where particular queries might be coming from.
-   *
-   * @param view $view
-   *   The view which is executed.
-   */
-  function add_signature(&$view) { }
-
-  /**
-   * Get aggregation info for group by queries.
-   *
-   * If NULL, aggregation is not allowed.
-   */
-  function get_aggregation_info() { }
-
-  /**
-   * Add settings for the ui.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-  }
-
-  function options_validate(&$form, &$form_state) { }
-
-  function options_submit(&$form, &$form_state) { }
-
-  function summary_title() {
-    return t('Settings');
-  }
-
-  /**
-   * Set a LIMIT on the query, specifying a maximum number of results.
-   */
-  function set_limit($limit) {
-    $this->limit = $limit;
-  }
-
-  /**
-   * Set an OFFSET on the query, specifying a number of results to skip
-   */
-  function set_offset($offset) {
-    $this->offset = $offset;
-  }
-
-  /**
-   * Render the pager, if necessary.
-   */
-  function render_pager($exposed_input) {
-    if (!empty($this->pager) && $this->pager->use_pager()) {
-      return $this->pager->render($exposed_input);
-    }
-
-    return '';
-  }
-
-  /**
-   * Create a new grouping for the WHERE or HAVING clause.
-   *
-   * @param $type
-   *   Either 'AND' or 'OR'. All items within this group will be added
-   *   to the WHERE clause with this logical operator.
-   * @param $group
-   *   An ID to use for this group. If unspecified, an ID will be generated.
-   * @param $where
-   *   'where' or 'having'.
-   *
-   * @return $group
-   *   The group ID generated.
-   */
-  function set_where_group($type = 'AND', $group = NULL, $where = 'where') {
-    // Set an alias.
-    $groups = &$this->$where;
-
-    if (!isset($group)) {
-      $group = empty($groups) ? 1 : max(array_keys($groups)) + 1;
-    }
-
-    // Create an empty group
-    if (empty($groups[$group])) {
-      $groups[$group] = array('conditions' => array(), 'args' => array());
-    }
-
-    $groups[$group]['type'] = strtoupper($type);
-    return $group;
-  }
-
-  /**
-   * Control how all WHERE and HAVING groups are put together.
-   *
-   * @param $type
-   *   Either 'AND' or 'OR'
-   */
-  function set_group_operator($type = 'AND') {
-    $this->group_operator = strtoupper($type);
-  }
-
-  /**
-   * Returns the according entity objects for the given query results.
-   */
-  function get_result_entities($results, $relationship = NULL) {
-    return FALSE;
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_query_default.inc b/plugins/views_plugin_query_default.inc
deleted file mode 100644
index 6a12bef..0000000
--- a/plugins/views_plugin_query_default.inc
+++ /dev/null
@@ -1,1643 +0,0 @@
-<?php
-
-/**
- * @file
- * Defines the default query object.
- */
-
-use Drupal\Core\Database\Database;
-use Drupal\views\Join;
-
-/**
- * Object used to create a SELECT query.
- *
- * @ingroup views_query_plugins
- */
-class views_plugin_query_default extends views_plugin_query {
-
-  /**
-   * A list of tables in the order they should be added, keyed by alias.
-   */
-  var $table_queue = array();
-
-  /**
-   * Holds an array of tables and counts added so that we can create aliases
-   */
-  var $tables = array();
-
-  /**
-   * Holds an array of relationships, which are aliases of the primary
-   * table that represent different ways to join the same table in.
-   */
-  var $relationships = array();
-
-  /**
-   * An array of sections of the WHERE query. Each section is in itself
-   * an array of pieces and a flag as to whether or not it should be AND
-   * or OR.
-   */
-  var $where = array();
-  /**
-   * An array of sections of the HAVING query. Each section is in itself
-   * an array of pieces and a flag as to whether or not it should be AND
-   * or OR.
-   */
-  var $having = array();
-  /**
-   * The default operator to use when connecting the WHERE groups. May be
-   * AND or OR.
-   */
-  var $group_operator = 'AND';
-
-  /**
-   * A simple array of order by clauses.
-   */
-  var $orderby = array();
-
-  /**
-   * A simple array of group by clauses.
-   */
-  var $groupby = array();
-
-
-  /**
-   * An array of fields.
-   */
-  var $fields = array();
-
-
-  /**
-   * The table header to use for tablesort. This matters because tablesort
-   * needs to modify the query and needs the header.
-   */
-  var $header = array();
-
-  /**
-   * A flag as to whether or not to make the primary field distinct.
-   */
-  var $distinct = FALSE;
-
-  var $has_aggregate = FALSE;
-
-  /**
-   * Should this query be optimized for counts, for example no sorts.
-   */
-  var $get_count_optimized = NULL;
-
-  /**
-   * The current used pager plugin.
-   *
-   * @var views_plugin_pager
-   */
-   var $pager = NULL;
-
-   /**
-    * 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();
-
-  /**
-   * Is the view marked as not distinct.
-   *
-   * @var bool
-   */
-  var $no_distinct;
-
-  /**
-   * Defines the distinct type.
-   * - FALSE if it's distinct by base field.
-   * - TRUE if it just adds the sql distinct keyword.
-   *
-   * @var bool
-   */
-  public $pure_distinct = FALSE;
-
-  /**
-   * Constructor; Create the basic query object and fill with default values.
-   */
-  function init($base_table = 'node', $base_field = 'nid', $options) {
-    parent::init($base_table, $base_field, $options);
-    $this->base_table = $base_table;  // Predefine these above, for clarity.
-    $this->base_field = $base_field;
-    $this->relationships[$base_table] = array(
-      'link' => NULL,
-      'table' => $base_table,
-      'alias' => $base_table,
-      'base' => $base_table
-    );
-
-    // init the table queue with our primary table.
-    $this->table_queue[$base_table] = array(
-      'alias' => $base_table,
-      'table' => $base_table,
-      'relationship' => $base_table,
-      'join' => NULL,
-    );
-
-    // init the tables with our primary table
-    $this->tables[$base_table][$base_table] = array(
-      'count' => 1,
-      'alias' => $base_table,
-    );
-
-/**
- * -- 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->count_field = array(
-      'table' => $base_table,
-      'field' => $base_field,
-      'alias' => $base_field,
-      'count' => TRUE,
-    );
-  }
-
-  // ----------------------------------------------------------------
-  // Utility methods to set flags and data.
-
-  /**
-   * Set the view to be distinct.
-   *
-   * There are either distinct per base field or distinct in the pure sql way,
-   * based on $pure_distinct.
-   *
-   * @param bool $value
-   *   Should the view by distincted.
-   * @param bool $pure_distinct
-   *   Should only the sql keyword be added.
-   */
-  function set_distinct($value = TRUE, $pure_distinct = FALSE) {
-    if (!(isset($this->no_distinct) && $value)) {
-      $this->distinct = $value;
-      $this->pure_distinct = $pure_distinct;
-    }
-  }
-
-  /**
-   * Set what field the query will count() on for paging.
-   */
-  function set_count_field($table, $field, $alias = NULL) {
-    if (empty($alias)) {
-      $alias = $table . '_' . $field;
-    }
-    $this->count_field = array(
-      'table' => $table,
-      'field' => $field,
-      'alias' => $alias,
-      'count' => TRUE,
-    );
-  }
-
-  /**
-   * Set the table header; used for click-sorting because it's needed
-   * info to modify the ORDER BY clause.
-   */
-  function set_header($header) {
-    $this->header = $header;
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['disable_sql_rewrite'] = array(
-      'default' => FALSE,
-      'translatable' => FALSE,
-      'bool' => TRUE,
-    );
-    $options['distinct'] = array(
-      'default' => FALSE,
-      'bool' => TRUE,
-    );
-    $options['pure_distinct'] = array(
-      'default' => FALSE,
-      'bool' => TRUE,
-    );
-    $options['slave'] = array(
-      'default' => FALSE,
-      'bool' => TRUE,
-    );
-    $options['query_comment'] = array(
-      'default' => '',
-    );
-    $options['query_tags'] = array(
-      'default' => array(),
-    );
-
-    return $options;
-  }
-
-  /**
-   * Add settings for the ui.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-
-    $form['disable_sql_rewrite'] = array(
-      '#title' => t('Disable SQL rewriting'),
-      '#description' => t('Disabling SQL rewriting will disable node_access checks as well as other modules that implement hook_query_alter().'),
-      '#type' => 'checkbox',
-      '#default_value' => !empty($this->options['disable_sql_rewrite']),
-      '#suffix' => '<div class="messages warning sql-rewrite-warning js-hide">' . t('WARNING: Disabling SQL rewriting means that node access security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Please use this option only if you understand and accept this security risk.') . '</div>',
-    );
-    $form['distinct'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Distinct'),
-      '#description' => t('This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.'),
-      '#default_value' => !empty($this->options['distinct']),
-    );
-    $form['pure_distinct'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Pure Distinct'),
-      '#description' => t('This will prevent views from adding the base column to the distinct field. If this is not selected and the base column is a primary key, then a non-pure distinct will not function properly because the primary key is always unique.'),
-      '#default_value' => !empty($this->options['pure_distinct']),
-      '#states' => array(
-        'visible' => array(
-          ':input[name="query[options][distinct]"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
-    $form['slave'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use Slave Server'),
-      '#description' => t('This will make the query attempt to connect to a slave server if available.  If no slave server is defined or available, it will fall back to the default server.'),
-      '#default_value' => !empty($this->options['slave']),
-    );
-    $form['query_comment'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Query Comment'),
-      '#description' => t('If set, this comment will be embedded in the query and passed to the SQL server. This can be helpful for logging or debugging.'),
-      '#default_value' => $this->options['query_comment'],
-    );
-    $form['query_tags'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Query Tags'),
-      '#description' => t('If set, these tags will be appended to the query and can be used to identify the query in a module. This can be helpful for altering queries.'),
-      '#default_value' => implode(', ', $this->options['query_tags']),
-      '#element_validate' => array('views_element_validate_tags'),
-    );
-  }
-
-  /**
-   * Special submit handling.
-   */
-  function options_submit(&$form, &$form_state) {
-    $element = array('#parents' => array('query', 'options', 'query_tags'));
-    $value = explode(',', drupal_array_get_nested_value($form_state['values'], $element['#parents']));
-    $value = array_filter(array_map('trim', $value));
-    form_set_value($element, $value, $form_state);
-  }
-
-  // ----------------------------------------------------------------
-  // Table/join adding
-
-  /**
-   * A relationship is an alternative endpoint to a series of table
-   * joins. Relationships must be aliases of the primary table and
-   * they must join either to the primary table or to a pre-existing
-   * relationship.
-   *
-   * An example of a relationship would be a nodereference table.
-   * If you have a nodereference named 'book_parent' which links to a
-   * parent node, you could set up a relationship 'node_book_parent'
-   * to 'node'. Then, anything that links to 'node' can link to
-   * 'node_book_parent' instead, thus allowing all properties of
-   * both nodes to be available in the query.
-   *
-   * @param $alias
-   *   What this relationship will be called, and is also the alias
-   *   for the table.
-   * @param Drupal\views\Join $join
-   *   A Join object (or derived object) to join the alias in.
-   * @param $base
-   *   The name of the 'base' table this relationship represents; this
-   *   tells the join search which path to attempt to use when finding
-   *   the path to this relationship.
-   * @param $link_point
-   *   If this relationship links to something other than the primary
-   *   table, specify that table here. For example, a 'track' node
-   *   might have a relationship to an 'album' node, which might
-   *   have a relationship to an 'artist' node.
-   */
-  function add_relationship($alias, Join $join, $base, $link_point = NULL) {
-    if (empty($link_point)) {
-      $link_point = $this->base_table;
-    }
-    elseif (!array_key_exists($link_point, $this->relationships)) {
-      return FALSE;
-    }
-
-    // Make sure $alias isn't already used; if it, start adding stuff.
-    $alias_base = $alias;
-    $count = 1;
-    while (!empty($this->relationships[$alias])) {
-      $alias = $alias_base . '_' . $count++;
-    }
-
-    // Make sure this join is adjusted for our relationship.
-    if ($link_point && isset($this->relationships[$link_point])) {
-      $join = $this->adjust_join($join, $link_point);
-    }
-
-    // Add the table directly to the queue to avoid accidentally marking
-    // it.
-    $this->table_queue[$alias] = array(
-      'table' => $join->table,
-      'num' => 1,
-      'alias' => $alias,
-      'join' => $join,
-      'relationship' => $link_point,
-    );
-
-    $this->relationships[$alias] = array(
-      'link' => $link_point,
-      'table' => $join->table,
-      'base' => $base,
-    );
-
-    $this->tables[$this->base_table][$alias] = array(
-      'count' => 1,
-      'alias' => $alias,
-    );
-
-    return $alias;
-  }
-
-  /**
-   * Add a table to the query, ensuring the path exists.
-   *
-   * This function will test to ensure that the path back to the primary
-   * table is valid and exists; if you do not wish for this testing to
-   * occur, use $query->queue_table() instead.
-   *
-   * @param $table
-   *   The name of the table to add. It needs to exist in the global table
-   *   array.
-   * @param $relationship
-   *   An alias of a table; if this is set, the path back to this table will
-   *   be tested prior to adding the table, making sure that all intermediary
-   *   tables exist and are properly aliased. If set to NULL the path to
-   *   the primary table will be ensured. If the path cannot be made, the
-   *   table will NOT be added.
-   * @param Drupal\views\Join $join
-   *   In some join configurations this table may actually join back through
-   *   a different method; this is most likely to be used when tracing
-   *   a hierarchy path. (node->parent->parent2->parent3). This parameter
-   *   will specify how this table joins if it is not the default.
-   * @param $alias
-   *   A specific alias to use, rather than the default alias.
-   *
-   * @return $alias
-   *   The alias of the table; this alias can be used to access information
-   *   about the table and should always be used to refer to the table when
-   *   adding parts to the query. Or FALSE if the table was not able to be
-   *   added.
-   */
-  function add_table($table, $relationship = NULL, Join $join = NULL, $alias = NULL) {
-    if (!$this->ensure_path($table, $relationship, $join)) {
-      return FALSE;
-    }
-
-    if ($join && $relationship) {
-      $join = $this->adjust_join($join, $relationship);
-    }
-
-    return $this->queue_table($table, $relationship, $join, $alias);
-  }
-
-  /**
-   * Add a table to the query without ensuring the path.
-   *
-   * This is a pretty internal function to Views and add_table() or
-   * ensure_table() should be used instead of this one, unless you are
-   * absolutely sure this is what you want.
-   *
-   * @param $table
-   *   The name of the table to add. It needs to exist in the global table
-   *   array.
-   * @param $relationship
-   *   The primary table alias this table is related to. If not set, the
-   *   primary table will be used.
-   * @param Drupal\views\Join $join
-   *   In some join configurations this table may actually join back through
-   *   a different method; this is most likely to be used when tracing
-   *   a hierarchy path. (node->parent->parent2->parent3). This parameter
-   *   will specify how this table joins if it is not the default.
-   * @param $alias
-   *   A specific alias to use, rather than the default alias.
-   *
-   * @return $alias
-   *   The alias of the table; this alias can be used to access information
-   *   about the table and should always be used to refer to the table when
-   *   adding parts to the query. Or FALSE if the table was not able to be
-   *   added.
-   */
-  function queue_table($table, $relationship = NULL, Join $join = NULL, $alias = NULL) {
-    // If the alias is set, make sure it doesn't already exist.
-    if (isset($this->table_queue[$alias])) {
-      return $alias;
-    }
-
-    if (empty($relationship)) {
-      $relationship = $this->base_table;
-    }
-
-    if (!array_key_exists($relationship, $this->relationships)) {
-      return FALSE;
-    }
-
-    if (!$alias && $join && $relationship && !empty($join->adjusted) && $table != $join->table) {
-      if ($relationship == $this->base_table) {
-        $alias = $table;
-      }
-      else {
-        $alias = $relationship . '_' . $table;
-      }
-    }
-
-    // Check this again to make sure we don't blow up existing aliases for already
-    // adjusted joins.
-    if (isset($this->table_queue[$alias])) {
-      return $alias;
-    }
-
-    $alias = $this->mark_table($table, $relationship, $alias);
-
-    // If no alias is specified, give it the default.
-    if (!isset($alias)) {
-      $alias = $this->tables[$relationship][$table]['alias'] . $this->tables[$relationship][$table]['count'];
-    }
-
-    // If this is a relationship based table, add a marker with
-    // the relationship as a primary table for the alias.
-    if ($table != $alias) {
-      $this->mark_table($alias, $this->base_table, $alias);
-    }
-
-    // If no join is specified, pull it from the table data.
-    if (!isset($join)) {
-      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
-      if (empty($join)) {
-        return FALSE;
-      }
-
-      $join = $this->adjust_join($join, $relationship);
-    }
-
-    $this->table_queue[$alias] = array(
-      'table' => $table,
-      'num' => $this->tables[$relationship][$table]['count'],
-      'alias' => $alias,
-      'join' => $join,
-      'relationship' => $relationship,
-    );
-
-    return $alias;
-  }
-
-  function mark_table($table, $relationship, $alias) {
-    // Mark that this table has been added.
-    if (empty($this->tables[$relationship][$table])) {
-      if (!isset($alias)) {
-        $alias = '';
-        if ($relationship != $this->base_table) {
-          // double underscore will help prevent accidental name
-          // space collisions.
-          $alias = $relationship . '__';
-        }
-        $alias .= $table;
-      }
-      $this->tables[$relationship][$table] = array(
-        'count' => 1,
-        'alias' => $alias,
-      );
-    }
-    else {
-      $this->tables[$relationship][$table]['count']++;
-    }
-
-    return $alias;
-  }
-
-  /**
-   * Ensure a table exists in the queue; if it already exists it won't
-   * do anything, but if it doesn't it will add the table queue. It will ensure
-   * a path leads back to the relationship table.
-   *
-   * @param $table
-   *   The unaliased name of the table to ensure.
-   * @param $relationship
-   *   The relationship to ensure the table links to. Each relationship will
-   *   get a unique instance of the table being added. If not specified,
-   *   will be the primary table.
-   * @param Drupal\views\Join $join
-   *   A Join object (or derived object) to join the alias in.
-   *
-   * @return
-   *   The alias used to refer to this specific table, or NULL if the table
-   *   cannot be ensured.
-   */
-  function ensure_table($table, $relationship = NULL, Join $join = NULL) {
-    // ensure a relationship
-    if (empty($relationship)) {
-      $relationship = $this->base_table;
-    }
-
-    // If the relationship is the primary table, this actually be a relationship
-    // link back from an alias. We store all aliases along with the primary table
-    // to detect this state, because eventually it'll hit a table we already
-    // have and that's when we want to stop.
-    if ($relationship == $this->base_table && !empty($this->tables[$relationship][$table])) {
-      return $this->tables[$relationship][$table]['alias'];
-    }
-
-    if (!array_key_exists($relationship, $this->relationships)) {
-      return FALSE;
-    }
-
-    if ($table == $this->relationships[$relationship]['base']) {
-      return $relationship;
-    }
-
-    // If we do not have join info, fetch it.
-    if (!isset($join)) {
-      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
-    }
-
-    // If it can't be fetched, this won't work.
-    if (empty($join)) {
-      return;
-    }
-
-    // Adjust this join for the relationship, which will ensure that the 'base'
-    // table it links to is correct. Tables adjoined to a relationship
-    // join to a link point, not the base table.
-    $join = $this->adjust_join($join, $relationship);
-
-    if ($this->ensure_path($table, $relationship, $join)) {
-      // Attempt to eliminate redundant joins.  If this table's
-      // relationship and join exactly matches an existing table's
-      // relationship and join, we do not have to join to it again;
-      // just return the existing table's alias.  See
-      // http://groups.drupal.org/node/11288 for details.
-      //
-      // This can be done safely here but not lower down in
-      // queue_table(), because queue_table() is also used by
-      // add_table() which requires the ability to intentionally add
-      // the same table with the same join multiple times.  For
-      // example, a view that filters on 3 taxonomy terms using AND
-      // needs to join taxonomy_term_data 3 times with the same join.
-
-      // scan through the table queue to see if a matching join and
-      // relationship exists.  If so, use it instead of this join.
-
-      // TODO: Scanning through $this->table_queue results in an
-      // O(N^2) algorithm, and this code runs every time the view is
-      // instantiated (Views 2 does not currently cache queries).
-      // There are a couple possible "improvements" but we should do
-      // some performance testing before picking one.
-      foreach ($this->table_queue as $queued_table) {
-        // In PHP 4 and 5, the == operation returns TRUE for two objects
-        // if they are instances of the same class and have the same
-        // attributes and values.
-        if ($queued_table['relationship'] == $relationship && $queued_table['join'] == $join) {
-          return $queued_table['alias'];
-        }
-      }
-
-      return $this->queue_table($table, $relationship, $join);
-    }
-  }
-
-  /**
-   * Make sure that the specified table can be properly linked to the primary
-   * table in the JOINs. This function uses recursion. If the tables
-   * needed to complete the path back to the primary table are not in the
-   * query they will be added, but additional copies will NOT be added
-   * if the table is already there.
-   */
-  function ensure_path($table, $relationship = NULL, $join = NULL, $traced = array(), $add = array()) {
-    if (!isset($relationship)) {
-      $relationship = $this->base_table;
-    }
-
-    if (!array_key_exists($relationship, $this->relationships)) {
-      return FALSE;
-    }
-
-    // If we do not have join info, fetch it.
-    if (!isset($join)) {
-      $join = $this->get_join_data($table, $this->relationships[$relationship]['base']);
-    }
-
-    // If it can't be fetched, this won't work.
-    if (empty($join)) {
-      return FALSE;
-    }
-
-    // Does a table along this path exist?
-    if (isset($this->tables[$relationship][$table]) ||
-      ($join && $join->left_table == $relationship) ||
-      ($join && $join->left_table == $this->relationships[$relationship]['table'])) {
-
-      // Make sure that we're linking to the correct table for our relationship.
-      foreach (array_reverse($add) as $table => $path_join) {
-        $this->queue_table($table, $relationship, $this->adjust_join($path_join, $relationship));
-      }
-      return TRUE;
-    }
-
-    // Have we been this way?
-    if (isset($traced[$join->left_table])) {
-      // we looped. Broked.
-      return FALSE;
-    }
-
-    // Do we have to add this table?
-    $left_join = $this->get_join_data($join->left_table, $this->relationships[$relationship]['base']);
-    if (!isset($this->tables[$relationship][$join->left_table])) {
-      $add[$join->left_table] = $left_join;
-    }
-
-    // Keep looking.
-    $traced[$join->left_table] = TRUE;
-    return $this->ensure_path($join->left_table, $relationship, $left_join, $traced, $add);
-  }
-
-  /**
-   * Fix a join to adhere to the proper relationship; the left table can vary
-   * based upon what relationship items are joined in on.
-   */
-  function adjust_join($join, $relationship) {
-    if (!empty($join->adjusted)) {
-      return $join;
-    }
-
-    if (empty($relationship) || empty($this->relationships[$relationship])) {
-      return $join;
-    }
-
-    // Adjusts the left table for our relationship.
-    if ($relationship != $this->base_table) {
-      // If we're linking to the primary table, the relationship to use will
-      // be the prior relationship. Unless it's a direct link.
-
-      // Safety! Don't modify an original here.
-      $join = clone $join;
-
-      // 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'])) {
-        $this->ensure_table($join->left_table, $relationship);
-      }
-
-      // First, if this is our link point/anchor table, just use the relationship
-      if ($join->left_table == $this->relationships[$relationship]['table']) {
-        $join->left_table = $relationship;
-      }
-      // then, try the base alias.
-      elseif (isset($this->tables[$relationship][$join->left_table]['alias'])) {
-        $join->left_table = $this->tables[$relationship][$join->left_table]['alias'];
-      }
-      // But if we're already looking at an alias, use that instead.
-      elseif (isset($this->table_queue[$relationship]['alias'])) {
-        $join->left_table = $this->table_queue[$relationship]['alias'];
-      }
-    }
-
-    $join->adjusted = TRUE;
-    return $join;
-  }
-
-  /**
-   * Retrieve join data from the larger join data cache.
-   *
-   * @param $table
-   *   The table to get the join information for.
-   * @param $base_table
-   *   The path we're following to get this join.
-   *
-   * @return Drupal\views\Join
-   *   A Join object or child object, if one exists.
-   */
-  function get_join_data($table, $base_table) {
-    // Check to see if we're linking to a known alias. If so, get the real
-    // table's data instead.
-    if (!empty($this->table_queue[$table])) {
-      $table = $this->table_queue[$table]['table'];
-    }
-    return views_get_table_join($table, $base_table);
-  }
-
-  /**
-   * Get the information associated with a table.
-   *
-   * If you need the alias of a table with a particular relationship, use
-   * ensure_table().
-   */
-  function get_table_info($table) {
-    if (!empty($this->table_queue[$table])) {
-      return $this->table_queue[$table];
-    }
-
-    // In rare cases we might *only* have aliased versions of the table.
-    if (!empty($this->tables[$this->base_table][$table])) {
-      $alias = $this->tables[$this->base_table][$table]['alias'];
-      if (!empty($this->table_queue[$alias])) {
-        return $this->table_queue[$alias];
-      }
-    }
-  }
-
-  /**
-   * Add a field to the query table, possibly with an alias. This will
-   * automatically call ensure_table to make sure the required table
-   * exists, *unless* $table is unset.
-   *
-   * @param $table
-   *   The table this field is attached to. If NULL, it is assumed this will
-   *   be a formula; otherwise, ensure_table is used to make sure the
-   *   table exists.
-   * @param $field
-   *   The name of the field to add. This may be a real field or a formula.
-   * @param $alias
-   *   The alias to create. If not specified, the alias will be $table_$field
-   *   unless $table is NULL. When adding formulae, it is recommended that an
-   *   alias be used.
-   * @param $params
-   *   An array of parameters additional to the field that will control items
-   *   such as aggregation functions and DISTINCT.
-   *
-   * @return $name
-   *   The name that this field can be referred to as. Usually this is the alias.
-   */
-  function add_field($table, $field, $alias = '', $params = array()) {
-    // We check for this specifically because it gets a special alias.
-    if ($table == $this->base_table && $field == $this->base_field && empty($alias)) {
-      $alias = $this->base_field;
-    }
-
-    if ($table && empty($this->table_queue[$table])) {
-      $this->ensure_table($table);
-    }
-
-    if (!$alias && $table) {
-      $alias = $table . '_' . $field;
-    }
-
-    // Make sure an alias is assigned
-    $alias = $alias ? $alias : $field;
-
-    // PostgreSQL truncates aliases to 63 characters: http://drupal.org/node/571548
-
-    // We limit the length of the original alias up to 60 characters
-    // to get a unique alias later if its have duplicates
-    $alias = strtolower(substr($alias, 0, 60));
-
-    // Create a field info array.
-    $field_info = array(
-      'field' => $field,
-      'table' => $table,
-      'alias' => $alias,
-    ) + $params;
-
-    // Test to see if the field is actually the same or not. Due to
-    // differing parameters changing the aggregation function, we need
-    // to do some automatic alias collision detection:
-    $base = $alias;
-    $counter = 0;
-    while (!empty($this->fields[$alias]) && $this->fields[$alias] != $field_info) {
-      $field_info['alias'] = $alias = $base . '_' . ++$counter;
-    }
-
-    if (empty($this->fields[$alias])) {
-      $this->fields[$alias] = $field_info;
-    }
-
-    // Keep track of all aliases used.
-    $this->field_aliases[$table][$field] = $alias;
-
-    return $alias;
-  }
-
-  /**
-   * Remove all fields that may've been added; primarily used for summary
-   * mode where we're changing the query because we didn't get data we needed.
-   */
-  function clear_fields() {
-    $this->fields = array();
-  }
-
-  /**
-   * Add a simple WHERE clause to the query. The caller is responsible for
-   * ensuring that all fields are fully qualified (TABLE.FIELD) and that
-   * the table already exists in the query.
-   *
-   * @param $group
-   *   The WHERE group to add these to; groups are used to create AND/OR
-   *   sections. Groups cannot be nested. Use 0 as the default group.
-   *   If the group does not yet exist it will be created as an AND group.
-   * @param $field
-   *   The name of the field to check.
-   * @param $value
-   *   The value to test the field against. In most cases, this is a scalar. For more
-   *   complex options, it is an array. The meaning of each element in the array is
-   *   dependent on the $operator.
-   * @param $operator
-   *   The comparison operator, such as =, <, or >=. It also accepts more complex
-   *   options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array
-   *   = otherwise. If $field is a string you have to use 'formula' here.
-   *
-   * @see QueryConditionInterface::condition()
-   */
-  function add_where($group, $field, $value = NULL, $operator = NULL) {
-    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
-    // the default group.
-    if (empty($group)) {
-      $group = 0;
-    }
-
-    // Check for a group.
-    if (!isset($this->where[$group])) {
-      $this->set_where_group('AND', $group);
-    }
-
-    $this->where[$group]['conditions'][] = array(
-      'field' => $field,
-      'value' => $value,
-      'operator' => $operator,
-    );
-  }
-
-  /**
-   * Add a complex WHERE clause to the query.
-   *
-   * The caller is reponsible for ensuring that all fields are fully qualified
-   * (TABLE.FIELD) and that the table already exists in the query.
-   * Internally the dbtng method "where" is used.
-   *
-   * @param $group
-   *   The WHERE group to add these to; groups are used to create AND/OR
-   *   sections. Groups cannot be nested. Use 0 as the default group.
-   *   If the group does not yet exist it will be created as an AND group.
-   * @param $snippet
-   *   The snippet to check. This can be either a column or
-   *   a complex expression like "UPPER(table.field) = 'value'"
-   * @param $args
-   *   An associative array of arguments.
-   *
-   * @see QueryConditionInterface::where()
-   */
-  function add_where_expression($group, $snippet, $args = array()) {
-    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
-    // the default group.
-    if (empty($group)) {
-      $group = 0;
-    }
-
-    // Check for a group.
-    if (!isset($this->where[$group])) {
-      $this->set_where_group('AND', $group);
-    }
-
-    $this->where[$group]['conditions'][] = array(
-      'field' => $snippet,
-      'value' => $args,
-      'operator' => 'formula',
-    );
-  }
-
-  /**
-   * Add a simple HAVING clause to the query.
-   *
-   * The caller is responsible for ensuring that all fields are fully qualified
-   * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query.
-   * Internally the dbtng method "havingCondition" is used.
-   *
-   * @param $group
-   *   The HAVING group to add these to; groups are used to create AND/OR
-   *   sections. Groups cannot be nested. Use 0 as the default group.
-   *   If the group does not yet exist it will be created as an AND group.
-   * @param $field
-   *   The name of the field to check.
-   * @param $value
-   *   The value to test the field against. In most cases, this is a scalar. For more
-   *   complex options, it is an array. The meaning of each element in the array is
-   *   dependent on the $operator.
-   * @param $operator
-   *   The comparison operator, such as =, <, or >=. It also accepts more complex
-   *   options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array
-   *   = otherwise.  If $field is a string you have to use 'formula' here.
-   *
-   * @see SelectQueryInterface::havingCondition()
-   */
-  function add_having($group, $field, $value = NULL, $operator = NULL) {
-    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
-    // the default group.
-    if (empty($group)) {
-      $group = 0;
-    }
-
-    // Check for a group.
-    if (!isset($this->having[$group])) {
-      $this->set_where_group('AND', $group, 'having');
-    }
-
-    // Add the clause and the args.
-    $this->having[$group]['conditions'][] = array(
-      'field' => $field,
-      'value' => $value,
-      'operator' => $operator,
-    );
-  }
-
-  /**
-   * Add a complex HAVING clause to the query.
-   * The caller is responsible for ensuring that all fields are fully qualified
-   * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query.
-   * Internally the dbtng method "having" is used.
-   *
-   * @param $group
-   *   The HAVING group to add these to; groups are used to create AND/OR
-   *   sections. Groups cannot be nested. Use 0 as the default group.
-   *   If the group does not yet exist it will be created as an AND group.
-   * @param $snippet
-   *   The snippet to check. This can be either a column or
-   *   a complex expression like "COUNT(table.field) > 3"
-   * @param $args
-   *   An associative array of arguments.
-   *
-   * @see QueryConditionInterface::having()
-   */
-  function add_having_expression($group, $snippet, $args = array()) {
-    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
-    // the default group.
-    if (empty($group)) {
-      $group = 0;
-    }
-
-    // Check for a group.
-    if (!isset($this->having[$group])) {
-      $this->set_where_group('AND', $group, 'having');
-    }
-
-    // Add the clause and the args.
-    $this->having[$group]['conditions'][] = array(
-      'field' => $snippet,
-      'value' => $args,
-      'operator' => 'formula',
-    );
-  }
-
-  /**
-   * Add an ORDER BY clause to the query.
-   *
-   * @param $table
-   *   The table this field is part of. If a formula, enter NULL.
-   *   If you want to orderby random use "rand" as table and nothing else.
-   * @param $field
-   *   The field or formula to sort on. If already a field, enter NULL
-   *   and put in the alias.
-   * @param $order
-   *   Either ASC or DESC.
-   * @param $alias
-   *   The alias to add the field as. In SQL, all fields in the order by
-   *   must also be in the SELECT portion. If an $alias isn't specified
-   *   one will be generated for from the $field; however, if the
-   *   $field is a formula, this alias will likely fail.
-   * @param $params
-   *   Any params that should be passed through to the add_field.
-   */
-  function add_orderby($table, $field = NULL, $order = 'ASC', $alias = '', $params = array()) {
-    // Only ensure the table if it's not the special random key.
-    // @todo: Maybe it would make sense to just add a add_orderby_rand or something similar.
-    if ($table && $table != 'rand') {
-      $this->ensure_table($table);
-    }
-
-    // Only fill out this aliasing if there is a table;
-    // otherwise we assume it is a formula.
-    if (!$alias && $table) {
-      $as = $table . '_' . $field;
-    }
-    else {
-      $as = $alias;
-    }
-
-    if ($field) {
-      $as = $this->add_field($table, $field, $as, $params);
-    }
-
-    $this->orderby[] = array(
-      'field' => $as,
-      'direction' => strtoupper($order)
-    );
-
-	/**
- 	 * -- 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);
-      }
-    */
-  }
-
-  /**
-   * Add a simple GROUP BY clause to the query. The caller is responsible
-   * for ensuring that the fields are fully qualified and the table is properly
-   * added.
-   */
-  function add_groupby($clause) {
-    // Only add it if it's not already in there.
-    if (!in_array($clause, $this->groupby)) {
-      $this->groupby[] = $clause;
-    }
-  }
-
-  /**
-   * Returns the alias for the given field added to $table.
-   *
-   * @see views_plugin_query_default::add_field()
-   */
-  function get_field_alias($table_alias, $field) {
-    return isset($this->field_aliases[$table_alias][$field]) ? $this->field_aliases[$table_alias][$field] : FALSE;
-  }
-
-  /**
-   * Adds a query tag to the sql object.
-   *
-   * @see SelectQuery::addTag()
-   */
-  function add_tag($tag) {
-    $this->tags[] = $tag;
-  }
-
-  /**
-   * Generates a unique placeholder used in the db query.
-   */
-  function placeholder($base = 'views') {
-    static $placeholders = array();
-    if (!isset($placeholders[$base])) {
-      $placeholders[$base] = 0;
-      return ':' . $base;
-    }
-    else {
-      return ':' . $base . ++$placeholders[$base];
-    }
-  }
-
-  /**
-   * Construct the "WHERE" or "HAVING" part of the query.
-   *
-   * As views has to wrap the conditions from arguments with AND, a special
-   * group is wrapped around all conditions. This special group has the ID 0.
-   * There is other code in filters which makes sure that the group IDs are
-   * higher than zero.
-   *
-   * @param $where
-   *   'where' or 'having'.
-   */
-  function build_condition($where = 'where') {
-    $has_condition = FALSE;
-    $has_arguments = FALSE;
-    $has_filter = FALSE;
-
-    $main_group = db_and();
-    $filter_group = $this->group_operator == 'OR' ? db_or() : db_and();
-
-    foreach ($this->$where as $group => $info) {
-
-      if (!empty($info['conditions'])) {
-        $sub_group = $info['type'] == 'OR' ? db_or() : db_and();
-        foreach ($info['conditions'] as $key => $clause) {
-          // DBTNG doesn't support to add the same subquery twice to the main
-          // query and the count query, so clone the subquery to have two instances
-          // of the same object. - http://drupal.org/node/1112854
-          if (is_object($clause['value']) && $clause['value'] instanceof SelectQuery) {
-            $clause['value'] = clone $clause['value'];
-          }
-          if ($clause['operator'] == 'formula') {
-            $has_condition = TRUE;
-            $sub_group->where($clause['field'], $clause['value']);
-          }
-          else {
-            $has_condition = TRUE;
-            $sub_group->condition($clause['field'], $clause['value'], $clause['operator']);
-          }
-        }
-
-        // Add the item to the filter group.
-        if ($group != 0) {
-          $has_filter = TRUE;
-          $filter_group->condition($sub_group);
-        }
-        else {
-          $has_arguments = TRUE;
-          $main_group->condition($sub_group);
-        }
-      }
-    }
-
-    if ($has_filter) {
-      $main_group->condition($filter_group);
-    }
-
-    if (!$has_arguments && $has_condition) {
-      return $filter_group;
-    }
-    if ($has_arguments && $has_condition) {
-      return $main_group;
-    }
-  }
-
-  /**
-   * Build fields array.
-   */
-  function compile_fields($fields_array, $query) {
-    $non_aggregates = array();
-    foreach ($fields_array as $field) {
-      $string = '';
-      if (!empty($field['table'])) {
-        $string .= $field['table'] . '.';
-      }
-      $string .= $field['field'];
-      $fieldname = (!empty($field['alias']) ? $field['alias'] : $string);
-
-      if (!empty($field['distinct'])) {
-        throw new Exception("Column-level distinct is not supported anymore.");
-      }
-
-      if (!empty($field['count'])) {
-        // Retained for compatibility
-        $field['function'] = 'count';
-        // It seems there's no way to abstract the table+column reference
-        // without adding a field, aliasing, and then using the alias.
-      }
-
-      if (!empty($field['function'])) {
-        $info = $this->get_aggregation_info();
-        if (!empty($info[$field['function']]['method']) && function_exists($info[$field['function']]['method'])) {
-          $string = $info[$field['function']]['method']($field['function'], $string);
-          $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
-          $query->addExpression($string, $fieldname, $placeholders);
-        }
-
-        $this->has_aggregate = TRUE;
-      }
-      // This is a formula, using no tables.
-      elseif (empty($field['table'])) {
-        $non_aggregates[] = $fieldname;
-        $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
-        $query->addExpression($string, $fieldname, $placeholders);
-      }
-
-      elseif ($this->distinct && !in_array($fieldname, $this->groupby)) {
-        // d7cx: This code was there, apparently needed for PostgreSQL
-        // $string = db_driver() == 'pgsql' ? "FIRST($string)" : $string;
-        $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname);
-      }
-      elseif (empty($field['aggregate'])) {
-        $non_aggregates[] = $fieldname;
-        $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname);
-      }
-
-      // @TODO Remove this old code.
-      if (!empty($field['distinct']) && empty($field['function'])) {
-        $distinct[] = $string;
-      }
-      else {
-        $fields[] = $string;
-      }
-
-      if ($this->get_count_optimized) {
-        // We only want the first field in this case.
-        break;
-      }
-    }
-    return array(
-      $non_aggregates,
-    );
-  }
-
-  /**
-   * Generate a query and a countquery from all of the information supplied
-   * to the object.
-   *
-   * @param $get_count
-   *   Provide a countquery if this is true, otherwise provide a normal query.
-   */
-  function query($get_count = FALSE) {
-    // Check query distinct value.
-    if (empty($this->no_distinct) && $this->distinct && !empty($this->fields)) {
-      if ($this->pure_distinct === FALSE){
-        $base_field_alias = $this->add_field($this->base_table, $this->base_field);
-        $this->add_groupby($base_field_alias);
-      }
-      $distinct = TRUE;
-    }
-
-    /**
-     * An optimized count query includes just the base field instead of all the fields.
-     * Determine of this query qualifies by checking for a groupby or distinct.
-     */
-    $fields_array = $this->fields;
-    if ($get_count && !$this->groupby) {
-      foreach ($fields_array as $field) {
-        if (!empty($field['distinct']) || !empty($field['function'])) {
-          $this->get_count_optimized = FALSE;
-          break;
-        }
-      }
-    }
-    else {
-      $this->get_count_optimized = FALSE;
-    }
-    if (!isset($this->get_count_optimized)) {
-      $this->get_count_optimized = TRUE;
-    }
-
-    $options = array();
-    $target = 'default';
-    $key = 'default';
-    // Detect an external database and set the
-    if (isset($this->view->base_database)) {
-      $key = $this->view->base_database;
-    }
-
-    // Set the slave target if the slave option is set
-    if (!empty($this->options['slave'])) {
-      $target = 'slave';
-    }
-
-    // Go ahead and build the query.
-    // db_select doesn't support to specify the key, so use getConnection directly.
-    $query = Database::getConnection($target, $key)
-      ->select($this->base_table, $this->base_table, $options)
-      ->addTag('views')
-      ->addTag('views_' . $this->view->name);
-
-    // Add the tags added to the view itself.
-    foreach ($this->tags as $tag) {
-      $query->addTag($tag);
-    }
-
-    if (!empty($distinct)) {
-      $query->distinct();
-    }
-
-    $joins = $where = $having = $orderby = $groupby = '';
-    $fields = $distinct = array();
-
-    // Add all the tables to the query via joins. We assume all LEFT joins.
-    foreach ($this->table_queue as $table) {
-      if (is_object($table['join'])) {
-        $table['join']->build_join($query, $table, $this);
-      }
-    }
-
-    $this->has_aggregate = FALSE;
-    $non_aggregates = array();
-
-    list($non_aggregates) = $this->compile_fields($fields_array, $query);
-
-    if (count($this->having)) {
-      $this->has_aggregate = TRUE;
-    }
-    if ($this->has_aggregate && (!empty($this->groupby) || !empty($non_aggregates))) {
-      $groupby = array_unique(array_merge($this->groupby, $non_aggregates));
-      foreach ($groupby as $field) {
-        $query->groupBy($field);
-      }
-      if (!empty($this->having) && $condition = $this->build_condition('having')) {
-        $query->havingCondition($condition);
-      }
-    }
-
-    if (!$this->get_count_optimized) {
-      // we only add the orderby if we're not counting.
-      if ($this->orderby) {
-        foreach ($this->orderby as $order) {
-          if ($order['field'] == 'rand_') {
-            $query->orderRandom();
-          }
-          else {
-            $query->orderBy($order['field'], $order['direction']);
-          }
-        }
-      }
-    }
-
-    if (!empty($this->where) && $condition = $this->build_condition('where')) {
-      $query->condition($condition);
-    }
-
-    // Add a query comment.
-    if (!empty($this->options['query_comment'])) {
-      $query->comment($this->options['query_comment']);
-    }
-
-    // Add the query tags.
-    if (!empty($this->options['query_tags'])) {
-      foreach ($this->options['query_tags'] as $tag) {
-        $query->addTag($tag);
-      }
-    }
-
-    // Add all query substitutions as metadata.
-    $query->addMetaData('views_substitutions', module_invoke_all('views_query_substitutions', $this));
-
-    return $query;
-  }
-
-  /**
-   * Get the arguments attached to the WHERE and HAVING clauses of this query.
-   */
-  function get_where_args() {
-    $args = array();
-    foreach ($this->where as $group => $where) {
-      $args = array_merge($args, $where['args']);
-    }
-    foreach ($this->having as $group => $having) {
-      $args = array_merge($args, $having['args']);
-    }
-    return $args;
-  }
-
-  /**
-   * Let modules modify the query just prior to finalizing it.
-   */
-  function alter(&$view) {
-    foreach (module_implements('views_query_alter') as $module) {
-      $function = $module . '_views_query_alter';
-      $function($view, $this);
-    }
-  }
-
-  /**
-   * Builds the necessary info to execute the query.
-   */
-  function build(&$view) {
-    // Make the query distinct if the option was set.
-    if (!empty($this->options['distinct'])) {
-      $this->set_distinct(TRUE, !empty($this->options['pure_distinct']));
-    }
-
-    // Store the view in the object to be able to use it later.
-    $this->view = $view;
-
-    $view->init_pager();
-
-    // Let the pager modify the query to add limits.
-    $this->pager->query();
-
-    $view->build_info['query'] = $this->query();
-    $view->build_info['count_query'] = $this->query(TRUE);
-  }
-
-  /**
-   * Executes the query and fills the associated view object with according
-   * values.
-   *
-   * Values to set: $view->result, $view->total_rows, $view->execute_time,
-   * $view->current_page.
-   */
-  function execute(&$view) {
-    $external = FALSE; // Whether this query will run against an external database.
-    $query = $view->build_info['query'];
-    $count_query = $view->build_info['count_query'];
-
-    $query->addMetaData('view', $view);
-    $count_query->addMetaData('view', $view);
-
-    if (empty($this->options['disable_sql_rewrite'])) {
-      $base_table_data = views_fetch_data($this->base_table);
-      if (isset($base_table_data['table']['base']['access query tag'])) {
-        $access_tag = $base_table_data['table']['base']['access query tag'];
-        $query->addTag($access_tag);
-        $count_query->addTag($access_tag);
-      }
-    }
-
-    $items = array();
-    if ($query) {
-      $additional_arguments = module_invoke_all('views_query_substitutions', $view);
-
-      // Count queries must be run through the preExecute() method.
-      // If not, then hook_query_node_access_alter() may munge the count by
-      // adding a distinct against an empty query string
-      // (e.g. COUNT DISTINCT(1) ...) and no pager will return.
-      // See pager.inc > PagerDefault::execute()
-      // http://api.drupal.org/api/drupal/includes--pager.inc/function/PagerDefault::execute/7
-      // See http://drupal.org/node/1046170.
-      $count_query->preExecute();
-
-      // Build the count query.
-      $count_query = $count_query->countQuery();
-
-      // Add additional arguments as a fake condition.
-      // XXX: this doesn't work... because PDO mandates that all bound arguments
-      // are used on the query. TODO: Find a better way to do this.
-      if (!empty($additional_arguments)) {
-        // $query->where('1 = 1', $additional_arguments);
-        // $count_query->where('1 = 1', $additional_arguments);
-      }
-
-      $start = microtime(TRUE);
-
-
-      try {
-        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
-          $this->pager->execute_count_query($count_query);
-        }
-
-        // Let the pager modify the query to add limits.
-        $this->pager->pre_execute($query);
-
-        if (!empty($this->limit) || !empty($this->offset)) {
-          // We can't have an offset without a limit, so provide a very large limit instead.
-          $limit  = intval(!empty($this->limit) ? $this->limit : 999999);
-          $offset = intval(!empty($this->offset) ? $this->offset : 0);
-          $query->range($offset, $limit);
-        }
-
-        $result = $query->execute();
-
-        $view->result = array();
-        foreach ($result as $item) {
-          $view->result[] = $item;
-        }
-
-        $this->pager->post_execute($view->result);
-
-        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
-          $view->total_rows = $this->pager->get_total_items();
-        }
-      }
-      catch (Exception $e) {
-        $view->result = array();
-        if (!empty($view->live_preview)) {
-          drupal_set_message($e->getMessage(), 'error');
-        }
-        else {
-          vpr('Exception in @human_name[@view_name]: @message', array('@human_name' => $view->human_name, '@view_name' => $view->name, '@message' => $e->getMessage()));
-        }
-      }
-
-    }
-    else {
-      $start = microtime(TRUE);
-    }
-    $view->execute_time = microtime(TRUE) - $start;
-  }
-
-  function add_signature(&$view) {
-    $view->query->add_field(NULL, "'" . $view->name . ':' . $view->current_display . "'", 'view_name');
-  }
-
-  function get_aggregation_info() {
-    // @todo -- need a way to get database specific and customized aggregation
-    // functions into here.
-    return array(
-      'group' => array(
-        'title' => t('Group results together'),
-        'is aggregate' => FALSE,
-      ),
-      'count' => array(
-        'title' => t('Count'),
-        'method' => 'views_query_default_aggregation_method_simple',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'field' => 'views_handler_field_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-      'count_distinct' => array(
-        'title' => t('Count DISTINCT'),
-        'method' => 'views_query_default_aggregation_method_distinct',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'field' => 'views_handler_field_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-      'sum' => array(
-        'title' => t('Sum'),
-        'method' => 'views_query_default_aggregation_method_simple',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-      'avg' => array(
-        'title' => t('Average'),
-        'method' => 'views_query_default_aggregation_method_simple',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-      'min' => array(
-        'title' => t('Minimum'),
-        'method' => 'views_query_default_aggregation_method_simple',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-      'max' => array(
-        'title' => t('Maximum'),
-        'method' => 'views_query_default_aggregation_method_simple',
-        'handler' => array(
-          'argument' => 'views_handler_argument_group_by_numeric',
-          'filter' => 'views_handler_filter_group_by_numeric',
-          'sort' => 'views_handler_sort_group_by_numeric',
-        ),
-      ),
-    );
-  }
-
-  /**
-   * Returns the according entity objects for the given query results.
-   *
-   */
-  function get_result_entities($results, $relationship = NULL) {
-    $base_table = $this->base_table;
-    $base_table_alias = $base_table;
-
-    if (!empty($relationship)) {
-      foreach ($this->view->relationship as $current) {
-        if ($current->alias == $relationship) {
-          $base_table = $current->definition['base'];
-          $base_table_alias = $relationship;
-          break;
-        }
-      }
-    }
-    $table_data = views_fetch_data($base_table);
-
-    // Bail out if the table has not specified the according entity-type.
-    if (!isset($table_data['table']['entity type'])) {
-      return FALSE;
-    }
-    $entity_type = $table_data['table']['entity type'];
-    $info = entity_get_info($entity_type);
-    $id_alias = $this->get_field_alias($base_table_alias, $info['entity keys']['id']);
-
-    // Assemble the ids of the entities to load.
-    $ids = array();
-    foreach ($results as $key => $result) {
-      if (isset($result->$id_alias)) {
-        $ids[$key] = $result->$id_alias;
-      }
-    }
-
-    $entities = entity_load_multiple($entity_type, $ids);
-    // Re-key the array by row-index.
-    $result = array();
-    foreach ($ids as $key => $id) {
-      $result[$key] = isset($entities[$id]) ? $entities[$id] : FALSE;
-    }
-    return array($entity_type, $result);
-  }
-}
-
-function views_query_default_aggregation_method_simple($group_type, $field) {
-  return strtoupper($group_type) . '(' . $field . ')';
-}
-
-function views_query_default_aggregation_method_distinct($group_type, $field) {
-  $group_type = str_replace('_distinct', '', $group_type);
-  return strtoupper($group_type) . '(DISTINCT ' . $field . ')';
-}
-
-/**
- * Validation callback for query tags.
- */
-function views_element_validate_tags($element, &$form_state) {
-  $values = array_map('trim', explode(',', $element['#value']));
-  foreach ($values as $value) {
-    if (preg_match("/[^a-z_]/", $value)) {
-      form_error($element, t('The query tags may only contain lower-case alphabetical characters and underscores.'));
-      return;
-    }
-  }
-}
diff --git a/plugins/views_plugin_row.inc b/plugins/views_plugin_row.inc
deleted file mode 100644
index 157cc26..0000000
--- a/plugins/views_plugin_row.inc
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the base row style plugin.
- */
-
-/**
- * @defgroup views_row_plugins Views row plugins
- * @{
- * Row plugins control how Views outputs an individual record.
- *
- * They are tightly coupled to style plugins, in that a style plugin is what
- * calls the row plugin.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * Default plugin to view a single row of a table. This is really just a wrapper around
- * a theme function.
- */
-class views_plugin_row extends views_plugin {
-  /**
-   * Initialize the row plugin.
-   */
-  function init(&$view, &$display, $options = NULL) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    // Overlay incoming options on top of defaults
-    $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('row_options'));
-  }
-
-  function uses_fields() {
-    return !empty($this->definition['uses fields']);
-  }
-
-
-  function option_definition() {
-    $options = parent::option_definition();
-    if (isset($this->base_table)) {
-      $options['relationship'] = array('default' => 'none');
-    }
-
-    return $options;
-  }
-
-  /**
-   * Provide a form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    if (isset($this->base_table)) {
-      $view = &$form_state['view'];
-
-      // A whole bunch of code to figure out what relationships are valid for
-      // this item.
-      $relationships = $view->display_handler->get_option('relationships');
-      $relationship_options = array();
-
-      foreach ($relationships as $relationship) {
-        $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
-
-        // If this relationship is valid for this type, add it to the list.
-        $data = views_fetch_data($relationship['table']);
-        $base = $data[$relationship['field']]['relationship']['base'];
-        if ($base == $this->base_table) {
-          $relationship_handler->init($view, $relationship);
-          $relationship_options[$relationship['id']] = $relationship_handler->label();
-        }
-      }
-
-      if (!empty($relationship_options)) {
-        $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
-        $rel = empty($this->options['relationship']) ? 'none' : $this->options['relationship'];
-        if (empty($relationship_options[$rel])) {
-          // Pick the first relationship.
-          $rel = key($relationship_options);
-        }
-
-        $form['relationship'] = array(
-          '#type' => 'select',
-          '#title' => t('Relationship'),
-          '#options' => $relationship_options,
-          '#default_value' => $rel,
-        );
-      }
-      else {
-        $form['relationship'] = array(
-          '#type' => 'value',
-          '#value' => 'none',
-        );
-      }
-    }
-  }
-
-  /**
-   * Validate the options form.
-   */
-  function options_validate(&$form, &$form_state) { }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) { }
-
-  function query() {
-    if (isset($this->base_table)) {
-      if (isset($this->options['relationship']) && isset($this->view->relationship[$this->options['relationship']])) {
-        $relationship = $this->view->relationship[$this->options['relationship']];
-        $this->field_alias = $this->view->query->add_field($relationship->alias, $this->base_field);
-      }
-      else {
-        $this->field_alias = $this->view->query->add_field($this->base_table, $this->base_field);
-      }
-    }
-  }
-
-  /**
-   * Allow the style to do stuff before each row is rendered.
-   *
-   * @param $result
-   *   The full array of results from the query.
-   */
-  function pre_render($result) { }
-
-  /**
-   * Render a row object. This usually passes through to a theme template
-   * of some form, but not always.
-   *
-   * @param stdClass $row
-   *   A single row of the query result, so an element of $view->result.
-   *
-   * @return string
-   *   The rendered output of a single row, used by the style plugin.
-   */
-  function render($row) {
-    return theme($this->theme_functions(),
-      array(
-        'view' => $this->view,
-        'options' => $this->options,
-        'row' => $row,
-        'field_alias' => isset($this->field_alias) ? $this->field_alias : '',
-      ));
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_row_fields.inc b/plugins/views_plugin_row_fields.inc
deleted file mode 100644
index c39b40b..0000000
--- a/plugins/views_plugin_row_fields.inc
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the base row style plugin.
- */
-
-/**
- * The basic 'fields' row plugin
- *
- * This displays fields one after another, giving options for inline
- * or not.
- *
- * @ingroup views_row_plugins
- */
-class views_plugin_row_fields extends views_plugin_row {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['inline'] = array('default' => array());
-    $options['separator'] = array('default' => '');
-    $options['hide_empty'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['default_field_elements'] = array('default' => TRUE, 'bool' => TRUE);
-    return $options;
-  }
-
-  /**
-   * Provide a form for setting options.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $options = $this->display->handler->get_field_labels();
-
-    if (empty($this->options['inline'])) {
-      $this->options['inline'] = array();
-    }
-
-    $form['default_field_elements'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Provide default field wrapper elements'),
-      '#default_value' => $this->options['default_field_elements'],
-      '#description' => t('If not checked, fields that are not configured to customize their HTML elements will get no wrappers at all for their field, label and field + label wrappers. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'),
-    );
-
-    $form['inline'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Inline fields'),
-      '#options' => $options,
-      '#default_value' => $this->options['inline'],
-      '#description' => t('Inline fields will be displayed next to each other rather than one after another. Note that some fields will ignore this if they are block elements, particularly body fields and other formatted HTML.'),
-      '#states' => array(
-        'visible' => array(
-          ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
-
-    $form['separator'] = array(
-      '#title' => t('Separator'),
-      '#type' => 'textfield',
-      '#size' => 10,
-      '#default_value' => isset($this->options['separator']) ? $this->options['separator'] : '',
-      '#description' => t('The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field.'),
-      '#states' => array(
-        'visible' => array(
-          ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
-
-    $form['hide_empty'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Hide empty fields'),
-      '#default_value' => $this->options['hide_empty'],
-      '#description' => t('Do not display fields, labels or markup for fields that are empty.'),
-    );
-
-  }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function options_submit(&$form, &$form_state) {
-    $form_state['values']['row_options']['inline'] = array_filter($form_state['values']['row_options']['inline']);
-  }
-}
diff --git a/plugins/views_plugin_row_rss_fields.inc b/plugins/views_plugin_row_rss_fields.inc
deleted file mode 100644
index 9355e83..0000000
--- a/plugins/views_plugin_row_rss_fields.inc
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-/**
- * @file
- * Contains an implementation of RSS items based on fields on a row plugin.
- */
-
-/**
- * Renders an RSS item based on fields.
- */
-class views_plugin_row_rss_fields extends views_plugin_row {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['title_field'] = array('default' => '');
-    $options['link_field'] = array('default' => '');
-    $options['description_field'] = array('default' => '');
-    $options['creator_field'] = array('default' => '');
-    $options['date_field'] = array('default' => '');
-    $options['guid_field_options']['guid_field'] = array('default' => '');
-    $options['guid_field_options']['guid_field_is_permalink'] = array('default' => TRUE, 'bool' => TRUE);
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-
-    $initial_labels = array('' => t('- None -'));
-    $view_fields_labels = $this->display->handler->get_field_labels();
-    $view_fields_labels = array_merge($initial_labels, $view_fields_labels);
-
-    $form['title_field'] = array(
-      '#type' => 'select',
-      '#title' => t('Title field'),
-      '#description' => t('The field that is going to be used as the RSS item title for each row.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['title_field'],
-      '#required' => TRUE,
-    );
-    $form['link_field'] = array(
-      '#type' => 'select',
-      '#title' => t('Link field'),
-      '#description' => t('The field that is going to be used as the RSS item link for each row. This must be a drupal relative path.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['link_field'],
-      '#required' => TRUE,
-    );
-    $form['description_field'] = array(
-      '#type' => 'select',
-      '#title' => t('Description field'),
-      '#description' => t('The field that is going to be used as the RSS item description for each row.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['description_field'],
-      '#required' => TRUE,
-    );
-    $form['creator_field'] = array(
-      '#type' => 'select',
-      '#title' => t('Creator field'),
-      '#description' => t('The field that is going to be used as the RSS item creator for each row.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['creator_field'],
-      '#required' => TRUE,
-    );
-    $form['date_field'] = array(
-      '#type' => 'select',
-      '#title' => t('Publication date field'),
-      '#description' => t('The field that is going to be used as the RSS item pubDate for each row. It needs to be in RFC 2822 format.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['date_field'],
-      '#required' => TRUE,
-    );
-    $form['guid_field_options'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('GUID settings'),
-      '#collapsible' => FALSE,
-      '#collapsed' => FALSE,
-    );
-    $form['guid_field_options']['guid_field'] = array(
-      '#type' => 'select',
-      '#title' => t('GUID field'),
-      '#description' => t('The globally unique identifier of the RSS item.'),
-      '#options' => $view_fields_labels,
-      '#default_value' => $this->options['guid_field_options']['guid_field'],
-      '#required' => TRUE,
-    );
-    $form['guid_field_options']['guid_field_is_permalink'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('GUID is permalink'),
-      '#description' => t('The RSS item GUID is a permalink.'),
-      '#default_value' => $this->options['guid_field_options']['guid_field_is_permalink'],
-    );
-  }
-
-  function validate() {
-    $errors = parent::validate();
-    $required_options = array('title_field', 'link_field', 'description_field', 'creator_field', 'date_field');
-    foreach ($required_options as $required_option) {
-      if (empty($this->options[$required_option])) {
-        $errors[] = t('Row style plugin requires specifying which views fields to use for RSS item.');
-        break;
-      }
-    }
-    // Once more for guid.
-    if (empty($this->options['guid_field_options']['guid_field'])) {
-      $errors[] = t('Row style plugin requires specifying which views fields to use for RSS item.');
-    }
-    return $errors;
-  }
-
-  function render($row) {
-    static $row_index;
-    if (!isset($row_index)) {
-      $row_index = 0;
-    }
-    if (function_exists('rdf_get_namespaces')) {
-      // Merge RDF namespaces in the XML namespaces in case they are used
-      // further in the RSS content.
-      $xml_rdf_namespaces = array();
-      foreach (rdf_get_namespaces() as $prefix => $uri) {
-        $xml_rdf_namespaces['xmlns:' . $prefix] = $uri;
-      }
-      $this->view->style_plugin->namespaces += $xml_rdf_namespaces;
-    }
-
-    // Create the RSS item object.
-    $item = new stdClass();
-    $item->title = $this->get_field($row_index, $this->options['title_field']);
-    $item->link = url($this->get_field($row_index, $this->options['link_field']), array('absolute' => TRUE));
-    $item->description = $this->get_field($row_index, $this->options['description_field']);
-    $item->elements = array(
-      array('key' => 'pubDate', 'value' => $this->get_field($row_index, $this->options['date_field'])),
-      array(
-        'key' => 'dc:creator',
-        'value' => $this->get_field($row_index, $this->options['creator_field']),
-        'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'),
-      ),
-    );
-    $guid_is_permalink_string = 'false';
-    $item_guid = $this->get_field($row_index, $this->options['guid_field_options']['guid_field']);
-    if ($this->options['guid_field_options']['guid_field_is_permalink']) {
-      $guid_is_permalink_string = 'true';
-      $item_guid = url($item_guid, array('absolute' => TRUE));
-    }
-    $item->elements[] = array(
-      'key' => 'guid',
-      'value' => $item_guid,
-      'attributes' => array('isPermaLink' => $guid_is_permalink_string),
-    );
-
-    $row_index++;
-
-    foreach ($item->elements as $element) {
-      if (isset($element['namespace'])) {
-        $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']);
-      }
-    }
-
-    return theme($this->theme_functions(),
-      array(
-        'view' => $this->view,
-        'options' => $this->options,
-        'row' => $item,
-        'field_alias' => isset($this->field_alias) ? $this->field_alias : '',
-      ));
-  }
-
-  /**
-   * Retrieves a views field value from the style plugin.
-   *
-   * @param $index
-   *   The index count of the row as expected by views_plugin_style::get_field().
-   * @param $field_id
-   *   The ID assigned to the required field in the display.
-   */
-  function get_field($index, $field_id) {
-    if (empty($this->view->style_plugin) || !is_object($this->view->style_plugin) || empty($field_id)) {
-      return '';
-    }
-    return $this->view->style_plugin->get_field($index, $field_id);
-  }
-
-}
diff --git a/plugins/views_plugin_style.inc b/plugins/views_plugin_style.inc
deleted file mode 100644
index 831ba36..0000000
--- a/plugins/views_plugin_style.inc
+++ /dev/null
@@ -1,603 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_plugin_style.
- */
-
-/**
- * @defgroup views_style_plugins Views style plugins
- * @{
- * Style plugins control how a view is rendered. For example, they
- * can choose to display a collection of fields, node_view() output,
- * table output, or any kind of crazy output they want.
- *
- * Many style plugins can have an optional 'row' plugin, that displays
- * a single record. Not all style plugins can utilize this, so it is
- * up to the plugin to set this up and call through to the row plugin.
- *
- * @see hook_views_plugins()
- */
-
-/**
- * Base class to define a style plugin handler.
- */
-class views_plugin_style extends views_plugin {
-  /**
-   * Store all available tokens row rows.
-   */
-  var $row_tokens = array();
-
-  /**
-   * Contains the row plugin, if it's initialized
-   * and the style itself supports it.
-   *
-   * @var views_plugin_row
-   */
-  var $row_plugin;
-
-  /**
-   * Initialize a style plugin.
-   *
-   * @param $view
-   * @param $display
-   * @param $options
-   *   The style options might come externally as the style can be sourced
-   *   from at least two locations. If it's not included, look on the display.
-   */
-  function init(&$view, &$display, $options = NULL) {
-    $this->view = &$view;
-    $this->display = &$display;
-
-    // Overlay incoming options on top of defaults
-    $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
-
-    if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
-      $this->row_plugin = $display->handler->get_plugin('row');
-    }
-
-    $this->options += array(
-      'grouping' => array(),
-    );
-
-    $this->definition += array(
-      'uses grouping' => TRUE,
-    );
-  }
-
-  function destroy() {
-    parent::destroy();
-
-    if (isset($this->row_plugin)) {
-      $this->row_plugin->destroy();
-    }
-  }
-
-  /**
-   * Return TRUE if this style also uses a row plugin.
-   */
-  function uses_row_plugin() {
-    return !empty($this->definition['uses row plugin']);
-  }
-
-  /**
-   * Return TRUE if this style also uses a row plugin.
-   */
-  function uses_row_class() {
-    return !empty($this->definition['uses row class']);
-  }
-
-  /**
-   * Return TRUE if this style also uses fields.
-   *
-   * @return bool
-   */
-  function uses_fields() {
-    // If we use a row plugin, ask the row plugin. Chances are, we don't
-    // care, it does.
-    $row_uses_fields = FALSE;
-    if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
-      $row_uses_fields = $this->row_plugin->uses_fields();
-    }
-    // Otherwise, check the definition or the option.
-    return $row_uses_fields || !empty($this->definition['uses fields']) || !empty($this->options['uses_fields']);
-  }
-
-  /**
-   * Return TRUE if this style uses tokens.
-   *
-   * Used to ensure we don't fetch tokens when not needed for performance.
-   */
-  function uses_tokens() {
-    if ($this->uses_row_class()) {
-      $class = $this->options['row_class'];
-      if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
-        return TRUE;
-      }
-    }
-  }
-
-  /**
-   * Return the token replaced row class for the specified row.
-   */
-  function get_row_class($row_index) {
-    if ($this->uses_row_class()) {
-      $class = $this->options['row_class'];
-      if ($this->uses_fields() && $this->view->field) {
-        $class = strip_tags($this->tokenize_value($class, $row_index));
-      }
-
-      $classes = explode(' ', $class);
-      foreach ($classes as &$class) {
-        $class = drupal_clean_css_identifier($class);
-      }
-      return implode(' ', $classes);
-    }
-  }
-
-  /**
-   * Take a value and apply token replacement logic to it.
-   */
-  function tokenize_value($value, $row_index) {
-    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
-      $fake_item = array(
-        'alter_text' => TRUE,
-        'text' => $value,
-      );
-
-      // Row tokens might be empty, for example for node row style.
-      $tokens = isset($this->row_tokens[$row_index]) ? $this->row_tokens[$row_index] : array();
-      if (!empty($this->view->build_info['substitutions'])) {
-        $tokens += $this->view->build_info['substitutions'];
-      }
-
-      if ($tokens) {
-        $value = strtr($value, $tokens);
-      }
-    }
-
-    return $value;
-  }
-
-  /**
-   * Should the output of the style plugin be rendered even if it's a empty view.
-   */
-  function even_empty() {
-    return !empty($this->definition['even empty']);
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['grouping'] = array('default' => array());
-    if ($this->uses_row_class()) {
-      $options['row_class'] = array('default' => '');
-      $options['default_row_class'] = array('default' => TRUE, 'bool' => TRUE);
-      $options['row_class_special'] = array('default' => TRUE, 'bool' => TRUE);
-    }
-    $options['uses_fields'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    // Only fields-based views can handle grouping.  Style plugins can also exclude
-    // themselves from being groupable by setting their "use grouping" definiton
-    // key to FALSE.
-    // @TODO: Document "uses grouping" in docs.php when docs.php is written.
-    if ($this->uses_fields() && $this->definition['uses grouping']) {
-      $options = array('' => t('- None -'));
-      $field_labels = $this->display->handler->get_field_labels();
-      $options += $field_labels;
-
-      // If there are no fields, we can't group on them.
-      if (count($options) > 1) {
-        // This is for backward compability, when there was just a single select form.
-        if (is_string($this->options['grouping'])) {
-          $grouping = $this->options['grouping'];
-          $this->options['grouping'] = array();
-          $this->options['grouping'][0]['field'] = $grouping;
-        }
-        if (isset($this->options['group_rendered']) && is_string($this->options['group_rendered'])) {
-          $this->options['grouping'][0]['rendered'] = $this->options['group_rendered'];
-          unset($this->options['group_rendered']);
-        }
-
-        $c = count($this->options['grouping']);
-        // Add a form for every grouping, plus one.
-        for ($i = 0; $i <= $c; $i++) {
-          $grouping = !empty($this->options['grouping'][$i]) ? $this->options['grouping'][$i] : array();
-          $grouping += array('field' => '', 'rendered' => TRUE, 'rendered_strip' => FALSE);
-          $form['grouping'][$i]['field'] = array(
-            '#type' => 'select',
-            '#title' => t('Grouping field Nr.@number', array('@number' => $i + 1)),
-            '#options' => $options,
-            '#default_value' => $grouping['field'],
-            '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
-          );
-          $form['grouping'][$i]['rendered'] = array(
-            '#type' => 'checkbox',
-            '#title' => t('Use rendered output to group rows'),
-            '#default_value' => $grouping['rendered'],
-            '#description' => t('If enabled the rendered output of the grouping field is used to group the rows.'),
-            '#states' => array(
-              'invisible' => array(
-                ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
-              ),
-            ),
-          );
-          $form['grouping'][$i]['rendered_strip'] = array(
-            '#type' => 'checkbox',
-            '#title' => t('Remove tags from rendered output'),
-            '#default_value' => $grouping['rendered_strip'],
-            '#states' => array(
-              'invisible' => array(
-                ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
-              ),
-            ),
-          );
-        }
-      }
-    }
-
-    if ($this->uses_row_class()) {
-      $form['row_class'] = array(
-        '#title' => t('Row class'),
-        '#description' => t('The class to provide on each row.'),
-        '#type' => 'textfield',
-        '#default_value' => $this->options['row_class'],
-      );
-
-      if ($this->uses_fields()) {
-        $form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.');
-      }
-
-      $form['default_row_class'] = array(
-        '#title' => t('Add views row classes'),
-        '#description' => t('Add the default row classes like views-row-1 to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'),
-        '#type' => 'checkbox',
-        '#default_value' => $this->options['default_row_class'],
-      );
-      $form['row_class_special'] = array(
-        '#title' => t('Add striping (odd/even), first/last row classes'),
-        '#description' => t('Add css classes to the first and last line, as well as odd/even classes for striping.'),
-        '#type' => 'checkbox',
-        '#default_value' => $this->options['row_class_special'],
-      );
-    }
-
-    if (!$this->uses_fields() || !empty($this->options['uses_fields'])) {
-      $form['uses_fields'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Force using fields'),
-        '#description' => t('If neither the row nor the style plugin supports fields, this field allows to enable them, so you can for example use groupby.'),
-        '#default_value' => $this->options['uses_fields'],
-      );
-    }
-  }
-
-  function options_validate(&$form, &$form_state) {
-    // Don't run validation on style plugins without the grouping setting.
-    if (isset($form_state['values']['style_options']['grouping'])) {
-      // Don't save grouping if no field is specified.
-      foreach ($form_state['values']['style_options']['grouping'] as $index => $grouping) {
-        if (empty($grouping['field'])) {
-          unset($form_state['values']['style_options']['grouping'][$index]);
-        }
-      }
-    }
-  }
-
-  /**
-   * Called by the view builder to see if this style handler wants to
-   * interfere with the sorts. If so it should build; if it returns
-   * any non-TRUE value, normal sorting will NOT be added to the query.
-   */
-  function build_sort() { return TRUE; }
-
-  /**
-   * Called by the view builder to let the style build a second set of
-   * sorts that will come after any other sorts in the view.
-   */
-  function build_sort_post() { }
-
-  /**
-   * Allow the style to do stuff before each row is rendered.
-   *
-   * @param $result
-   *   The full array of results from the query.
-   */
-  function pre_render($result) {
-    if (!empty($this->row_plugin)) {
-      $this->row_plugin->pre_render($result);
-    }
-  }
-
-  /**
-   * Render the display in this style.
-   */
-  function render() {
-    if ($this->uses_row_plugin() && empty($this->row_plugin)) {
-      debug('views_plugin_style_default: Missing row plugin');
-      return;
-    }
-
-    // Group the rows according to the grouping instructions, if specified.
-    $sets = $this->render_grouping(
-      $this->view->result,
-      $this->options['grouping'],
-      TRUE
-    );
-
-    return $this->render_grouping_sets($sets);
-  }
-
-  /**
-   * Render the grouping sets.
-   *
-   * Plugins may override this method if they wish some other way of handling
-   * grouping.
-   *
-   * @param $sets
-   *   Array containing the grouping sets to render.
-   * @param $level
-   *   Integer indicating the hierarchical level of the grouping.
-   *
-   * @return string
-   *   Rendered output of given grouping sets.
-   */
-  function render_grouping_sets($sets, $level = 0) {
-    $output = '';
-    foreach ($sets as $set) {
-      $row = reset($set['rows']);
-      // Render as a grouping set.
-      if (is_array($row) && isset($row['group'])) {
-        $output .= theme(views_theme_functions('views_view_grouping', $this->view, $this->display),
-          array(
-            'view' => $this->view,
-            'grouping' => $this->options['grouping'][$level],
-            'grouping_level' => $level,
-            'rows' => $set['rows'],
-            'title' => $set['group'])
-        );
-      }
-      // Render as a record set.
-      else {
-        if ($this->uses_row_plugin()) {
-          foreach ($set['rows'] as $index => $row) {
-            $this->view->row_index = $index;
-            $set['rows'][$index] = $this->row_plugin->render($row);
-          }
-        }
-
-        $output .= theme($this->theme_functions(),
-          array(
-            'view' => $this->view,
-            'options' => $this->options,
-            'grouping_level' => $level,
-            'rows' => $set['rows'],
-            'title' => $set['group'])
-        );
-      }
-    }
-    unset($this->view->row_index);
-    return $output;
-  }
-
-  /**
-   * Group records as needed for rendering.
-   *
-   * @param $records
-   *   An array of records from the view to group.
-   * @param $groupings
-   *   An array of grouping instructions on which fields to group. If empty, the
-   *   result set will be given a single group with an empty string as a label.
-   * @param $group_rendered
-   *   Boolean value whether to use the rendered or the raw field value for
-   *   grouping. If set to NULL the return is structured as before
-   *   Views 7.x-3.0-rc2. After Views 7.x-3.0 this boolean is only used if
-   *   $groupings is an old-style string or if the rendered option is missing
-   *   for a grouping instruction.
-   * @return
-   *   The grouped record set.
-   *   A nested set structure is generated if multiple grouping fields are used.
-   *
-   *   @code
-   *   array(
-   *     'grouping_field_1:grouping_1' => array(
-   *       'group' => 'grouping_field_1:content_1',
-   *       'rows' => array(
-   *         'grouping_field_2:grouping_a' => array(
-   *           'group' => 'grouping_field_2:content_a',
-   *           'rows' => array(
-   *             $row_index_1 => $row_1,
-   *             $row_index_2 => $row_2,
-   *             // ...
-   *           )
-   *         ),
-   *       ),
-   *     ),
-   *     'grouping_field_1:grouping_2' => array(
-   *       // ...
-   *     ),
-   *   )
-   *   @endcode
-   */
-  function render_grouping($records, $groupings = array(), $group_rendered = NULL) {
-    // This is for backward compability, when $groupings was a string containing
-    // the ID of a single field.
-    if (is_string($groupings)) {
-      $rendered = $group_rendered === NULL ? TRUE : $group_rendered;
-      $groupings = array(array('field' => $groupings, 'rendered' => $rendered));
-    }
-
-    // Make sure fields are rendered
-    $this->render_fields($this->view->result);
-    $sets = array();
-    if ($groupings) {
-      foreach ($records as $index => $row) {
-        // Iterate through configured grouping fields to determine the
-        // hierarchically positioned set where the current row belongs to.
-        // While iterating, parent groups, that do not exist yet, are added.
-        $set = &$sets;
-        foreach ($groupings as $info) {
-          $field = $info['field'];
-          $rendered = isset($info['rendered']) ? $info['rendered'] : $group_rendered;
-          $rendered_strip = isset($info['rendered_strip']) ? $info['rendered_strip'] : FALSE;
-          $grouping = '';
-          $group_content = '';
-          // Group on the rendered version of the field, not the raw.  That way,
-          // we can control any special formatting of the grouping field through
-          // the admin or theme layer or anywhere else we'd like.
-          if (isset($this->view->field[$field])) {
-            $group_content = $this->get_field($index, $field);
-            if ($this->view->field[$field]->options['label']) {
-              $group_content = $this->view->field[$field]->options['label'] . ': ' . $group_content;
-            }
-            if ($rendered) {
-              $grouping = $group_content;
-              if ($rendered_strip) {
-                $group_content = $grouping = strip_tags(htmlspecialchars_decode($group_content));
-              }
-            }
-            else {
-              $grouping = $this->get_field_value($index, $field);
-              // Not all field handlers return a scalar value,
-              // e.g. views_handler_field_field.
-              if (!is_scalar($grouping)) {
-                $grouping = md5(serialize($grouping));
-              }
-            }
-          }
-
-          // Create the group if it does not exist yet.
-          if (empty($set[$grouping])) {
-            $set[$grouping]['group'] = $group_content;
-            $set[$grouping]['rows'] = array();
-          }
-
-          // Move the set reference into the row set of the group we just determined.
-          $set = &$set[$grouping]['rows'];
-        }
-        // Add the row to the hierarchically positioned row set we just determined.
-        $set[$index] = $row;
-      }
-    }
-    else {
-      // Create a single group with an empty grouping field.
-      $sets[''] = array(
-        'group' => '',
-        'rows' => $records,
-      );
-    }
-
-    // If this parameter isn't explicitely set modify the output to be fully
-    // backward compatible to code before Views 7.x-3.0-rc2.
-    // @TODO Remove this as soon as possible e.g. October 2020
-    if ($group_rendered === NULL) {
-      $old_style_sets = array();
-      foreach ($sets as $group) {
-        $old_style_sets[$group['group']] = $group['rows'];
-      }
-      $sets = $old_style_sets;
-    }
-
-    return $sets;
-  }
-
-  /**
-   * Render all of the fields for a given style and store them on the object.
-   *
-   * @param $result
-   *   The result array from $view->result
-   */
-  function render_fields($result) {
-    if (!$this->uses_fields()) {
-      return;
-    }
-
-    if (!isset($this->rendered_fields)) {
-      $this->rendered_fields = array();
-      $this->view->row_index = 0;
-      $keys = array_keys($this->view->field);
-
-      // If all fields have a field::access FALSE there might be no fields, so
-      // there is no reason to execute this code.
-      if (!empty($keys)) {
-        foreach ($result as $count => $row) {
-          $this->view->row_index = $count;
-          foreach ($keys as $id) {
-            $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
-          }
-
-          $this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array());
-        }
-      }
-      unset($this->view->row_index);
-    }
-
-    return $this->rendered_fields;
-  }
-
-  /**
-   * Get a rendered field.
-   *
-   * @param $index
-   *   The index count of the row.
-   * @param $field
-   *    The id of the field.
-   */
-  function get_field($index, $field) {
-    if (!isset($this->rendered_fields)) {
-      $this->render_fields($this->view->result);
-    }
-
-    if (isset($this->rendered_fields[$index][$field])) {
-      return $this->rendered_fields[$index][$field];
-    }
-  }
-
-  /**
-  * Get the raw field value.
-  *
-  * @param $index
-  *   The index count of the row.
-  * @param $field
-  *    The id of the field.
-  */
-  function get_field_value($index, $field) {
-    $this->view->row_index = $index;
-    $value = $this->view->field[$field]->get_value($this->view->result[$index]);
-    unset($this->view->row_index);
-    return $value;
-  }
-
-  function validate() {
-    $errors = parent::validate();
-
-    if ($this->uses_row_plugin()) {
-      $plugin = $this->display->handler->get_plugin('row');
-      if (empty($plugin)) {
-        $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
-      }
-      else {
-        $result = $plugin->validate();
-        if (!empty($result) && is_array($result)) {
-          $errors = array_merge($errors, $result);
-        }
-      }
-    }
-    return $errors;
-  }
-
-  function query() {
-    parent::query();
-    if (isset($this->row_plugin)) {
-      $this->row_plugin->query();
-    }
-  }
-}
-
-/**
- * @}
- */
diff --git a/plugins/views_plugin_style_default.inc b/plugins/views_plugin_style_default.inc
deleted file mode 100644
index a18f6cc..0000000
--- a/plugins/views_plugin_style_default.inc
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the default style plugin.
- */
-
-/**
- * Default style plugin to render rows one after another with no
- * decorations.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_default extends views_plugin_style {
-  /**
-   * Set default options
-   */
-  function options(&$options) {
-    parent::options($options);
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-  }
-}
diff --git a/plugins/views_plugin_style_grid.inc b/plugins/views_plugin_style_grid.inc
deleted file mode 100644
index 9be7ee1..0000000
--- a/plugins/views_plugin_style_grid.inc
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the grid style plugin.
- */
-
-/**
- * Style plugin to render each item in a grid cell.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_grid extends views_plugin_style {
-  /**
-   * Set default options
-   */
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['columns'] = array('default' => '4');
-    $options['alignment'] = array('default' => 'horizontal');
-    $options['fill_single_line'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['summary'] = array('default' => '');
-
-    return $options;
-  }
-
-  /**
-   * Render the given style.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['columns'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of columns'),
-      '#default_value' => $this->options['columns'],
-      '#required' => TRUE,
-      '#element_validate' => array('views_element_validate_integer'),
-    );
-    $form['alignment'] = array(
-      '#type' => 'radios',
-      '#title' => t('Alignment'),
-      '#options' => array('horizontal' => t('Horizontal'), 'vertical' => t('Vertical')),
-      '#default_value' => $this->options['alignment'],
-      '#description' => t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'),
-    );
-
-    $form['fill_single_line'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Fill up single line'),
-      '#description' => t('If you disable this option, a grid with only one row will have the same number of table cells (<TD>) as items. Disabling it can cause problems with your CSS.'),
-      '#default_value' => !empty($this->options['fill_single_line']),
-    );
-
-    $form['summary'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Table summary'),
-      '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'),
-      '#default_value' => $this->options['summary'],
-    );
-  }
-}
diff --git a/plugins/views_plugin_style_jump_menu.inc b/plugins/views_plugin_style_jump_menu.inc
deleted file mode 100644
index 94612aa..0000000
--- a/plugins/views_plugin_style_jump_menu.inc
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the table style plugin.
- */
-
-/**
- * Style plugin to render each item as a row in a table.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_jump_menu extends views_plugin_style {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['hide'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['path'] = array('default' => '');
-    $options['text'] = array('default' => 'Go', 'translatable' => TRUE);
-    $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE);
-    $options['default_value'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  /**
-   * Render the given style.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $handlers = $this->display->handler->get_handlers('field');
-    if (empty($handlers)) {
-      $form['error_markup'] = array(
-        '#markup' => t('You need at least one field before you can configure your jump menu settings'),
-        '#prefix' => '<div class="error messages">',
-        '#suffix' => '</div>',
-      );
-      return;
-    }
-
-    $form['markup'] = array(
-      '#markup' => t('To properly configure a jump menu, you must select one field that will represent the path to utilize. You should then set that field to exclude. All other displayed fields will be part of the menu. Please note that all HTML will be stripped from this output as select boxes cannot show HTML.'),
-      '#prefix' => '<div class="form-item description">',
-      '#suffix' => '</div>',
-    );
-
-    foreach ($handlers as $id => $handler) {
-      $options[$id] = $handler->ui_name();
-    }
-
-    $form['path'] = array(
-      '#type' => 'select',
-      '#title' => t('Path field'),
-      '#options' => $options,
-      '#default_value' => $this->options['path'],
-    );
-
-    $form['hide'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Hide the "Go" button'),
-      '#default_value' => !empty($this->options['hide']),
-      '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'),
-    );
-
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Button text'),
-      '#default_value' => $this->options['text'],
-    );
-
-    $form['choose'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Choose text'),
-      '#default_value' => $this->options['choose'],
-      '#description' => t('The text that will appear as the selected option in the jump menu.'),
-    );
-
-    $form['default_value'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Select the current contextual filter value'),
-      '#default_value' => !empty($this->options['default_value']),
-      '#description' => t('If checked, the current path will be displayed as the default option in the jump menu, if applicable.'),
-    );
-  }
-
-  /**
-   * Render the display in this style.
-   *
-   * This is overridden so that we can render our grouping specially.
-   */
-  function render() {
-    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
-
-    // Turn this all into an $options array for the jump menu.
-    $this->view->row_index = 0;
-    $options = array();
-    $paths = array();
-
-    foreach ($sets as $title => $records) {
-      foreach ($records as $row_index => $row) {
-        $this->view->row_index = $row_index;
-        $path = strip_tags(decode_entities($this->get_field($this->view->row_index, $this->options['path'])));
-        // Putting a '/' in front messes up url() so let's take that out
-        // so users don't shoot themselves in the foot.
-        $base_path = base_path();
-        if (strpos($path, $base_path) === 0) {
-          $path = drupal_substr($path, drupal_strlen($base_path));
-        }
-
-        // use drupal_parse_url() to preserve query and fragment in case the user
-        // wants to do fun tricks.
-        $url_options = drupal_parse_url($path);
-
-        $path = url($url_options['path'], $url_options);
-        $field = strip_tags(decode_entities($this->row_plugin->render($row)));
-        $key = md5($path . $field) . "::" . $path;
-        if ($title) {
-          $options[$title][$key] = $field;
-        }
-        else {
-          $options[$key] = $field;
-        }
-        $paths[$path] = $key;
-        $this->view->row_index++;
-      }
-    }
-    unset($this->view->row_index);
-
-    $default_value = '';
-    if ($this->options['default_value'] && !empty($paths[url(current_path())])) {
-      $default_value = $paths[url(current_path())];
-    }
-
-    ctools_include('jump-menu');
-    $settings = array(
-      'hide' => $this->options['hide'],
-      'button' => $this->options['text'],
-      'choose' => $this->options['choose'],
-      'default_value' => $default_value,
-    );
-
-    $form = drupal_get_form('ctools_jump_menu', $options, $settings);
-    return $form;
-  }
-
-  function render_set($title, $records) {
-    $options = array();
-    $fields = $this->rendered_fields;
-  }
-}
diff --git a/plugins/views_plugin_style_list.inc b/plugins/views_plugin_style_list.inc
deleted file mode 100644
index 2a1dadb..0000000
--- a/plugins/views_plugin_style_list.inc
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the list style plugin.
- */
-
-/**
- * Style plugin to render each item in an ordered or unordered list.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_list extends views_plugin_style {
-  /**
-   * Set default options
-   */
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['type'] = array('default' => 'ul');
-    $options['class'] = array('default' => '');
-    $options['wrapper_class'] = array('default' => 'item-list');
-
-    return $options;
-  }
-
-  /**
-   * Render the given style.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['type'] = array(
-      '#type' => 'radios',
-      '#title' => t('List type'),
-      '#options' => array('ul' => t('Unordered list'), 'ol' => t('Ordered list')),
-      '#default_value' => $this->options['type'],
-    );
-    $form['wrapper_class'] = array(
-      '#title' => t('Wrapper class'),
-      '#description' => t('The class to provide on the wrapper, outside the list.'),
-      '#type' => 'textfield',
-      '#size' => '30',
-      '#default_value' => $this->options['wrapper_class'],
-    );
-    $form['class'] = array(
-      '#title' => t('List class'),
-      '#description' => t('The class to provide on the list element itself.'),
-      '#type' => 'textfield',
-      '#size' => '30',
-      '#default_value' => $this->options['class'],
-    );
-  }
-}
diff --git a/plugins/views_plugin_style_rss.inc b/plugins/views_plugin_style_rss.inc
deleted file mode 100644
index 27106a8..0000000
--- a/plugins/views_plugin_style_rss.inc
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the RSS style plugin.
- */
-
-/**
- * Default style plugin to render an RSS feed.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_rss extends views_plugin_style {
-  function attach_to($display_id, $path, $title) {
-    $display = $this->view->display[$display_id]->handler;
-    $url_options = array();
-    $input = $this->view->get_exposed_input();
-    if ($input) {
-      $url_options['query'] = $input;
-    }
-    $url_options['absolute'] = TRUE;
-
-    $url = url($this->view->get_url(NULL, $path), $url_options);
-    if ($display->has_path()) {
-      if (empty($this->preview)) {
-        drupal_add_feed($url, $title);
-      }
-    }
-    else {
-      if (empty($this->view->feed_icon)) {
-        $this->view->feed_icon = '';
-      }
-
-      $this->view->feed_icon .= theme('feed_icon', array('url' => $url, 'title' => $title));
-      drupal_add_html_head_link(array(
-        'rel' => 'alternate',
-        'type' => 'application/rss+xml',
-        'title' => $title,
-        'href' => $url
-      ));
-    }
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['description'] = array('default' => '', 'translatable' => TRUE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-
-    $form['description'] = array(
-      '#type' => 'textfield',
-      '#title' => t('RSS description'),
-      '#default_value' => $this->options['description'],
-      '#description' => t('This will appear in the RSS feed itself.'),
-      '#maxlength' => 1024,
-    );
-  }
-
-  /**
-   * Return an array of additional XHTML elements to add to the channel.
-   *
-   * @return
-   *   An array that can be passed to format_xml_elements().
-   */
-  function get_channel_elements() {
-    return array();
-  }
-
-  /**
-   * Get RSS feed description.
-   *
-   * @return string
-   *   The string containing the description with the tokens replaced.
-   */
-  function get_description() {
-    $description = $this->options['description'];
-
-    // Allow substitutions from the first row.
-    $description = $this->tokenize_value($description, 0);
-
-    return $description;
-  }
-
-  function render() {
-    if (empty($this->row_plugin)) {
-      vpr('views_plugin_style_default: Missing row plugin');
-      return;
-    }
-    $rows = '';
-
-    // This will be filled in by the row plugin and is used later on in the
-    // theming output.
-    $this->namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
-
-    // Fetch any additional elements for the channel and merge in their
-    // namespaces.
-    $this->channel_elements = $this->get_channel_elements();
-    foreach ($this->channel_elements as $element) {
-      if (isset($element['namespace'])) {
-        $this->namespaces = array_merge($this->namespaces, $element['namespace']);
-      }
-    }
-
-    foreach ($this->view->result as $row_index => $row) {
-      $this->view->row_index = $row_index;
-      $rows .= $this->row_plugin->render($row);
-    }
-
-    $output = theme($this->theme_functions(),
-      array(
-        'view' => $this->view,
-        'options' => $this->options,
-        'rows' => $rows
-      ));
-    unset($this->view->row_index);
-    return $output;
-  }
-}
diff --git a/plugins/views_plugin_style_summary.inc b/plugins/views_plugin_style_summary.inc
deleted file mode 100644
index 256c0e3..0000000
--- a/plugins/views_plugin_style_summary.inc
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the default summary style plugin, which displays items in an HTML list.
- */
-
-/**
- * The default style plugin for summaries.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_summary extends views_plugin_style {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['base_path'] = array('default' => '');
-    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['override'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['items_per_page'] = array('default' => 25);
-
-    return $options;
-  }
-
-  function query() {
-    if (!empty($this->options['override'])) {
-      $this->view->set_items_per_page(intval($this->options['items_per_page']));
-    }
-  }
-
-  function options_form(&$form, &$form_state) {
-    $form['base_path'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Base path'),
-      '#default_value' => $this->options['base_path'],
-      '#description' => t('Define the base path for links in this summary
-        view, i.e. http://example.com/<strong>your_view_path/archive</strong>.
-        Do not include beginning and ending forward slash. If this value
-        is empty, views will use the first path found as the base path,
-        in page displays, or / if no path could be found.'),
-    );
-    $form['count'] = array(
-      '#type' => 'checkbox',
-      '#default_value' => !empty($this->options['count']),
-      '#title' => t('Display record count with link'),
-    );
-    $form['override'] = array(
-      '#type' => 'checkbox',
-      '#default_value' => !empty($this->options['override']),
-      '#title' => t('Override number of items to display'),
-    );
-
-    $form['items_per_page'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Items to display'),
-      '#default_value' => $this->options['items_per_page'],
-      '#states' => array(
-        'visible' => array(
-          ':input[name="options[summary][options][' . $this->definition['name'] . '][override]"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
-  }
-
-  function render() {
-    $rows = array();
-    foreach ($this->view->result as $row) {
-      // @todo: Include separator as an option.
-      $rows[] = $row;
-    }
-
-    return theme($this->theme_functions(), array(
-      'view' => $this->view,
-      'options' => $this->options,
-      'rows' => $rows
-    ));
-  }
-}
diff --git a/plugins/views_plugin_style_summary_jump_menu.inc b/plugins/views_plugin_style_summary_jump_menu.inc
deleted file mode 100644
index be46db7..0000000
--- a/plugins/views_plugin_style_summary_jump_menu.inc
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the default summary style plugin, which displays items in an HTML list.
- */
-
-/**
- * The default style plugin for summaries.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_summary_jump_menu extends views_plugin_style {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['base_path'] = array('default' => '');
-    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['hide'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['text'] = array('default' => 'Go', 'translatable' => TRUE);
-    $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE);
-    $options['default_value'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  function query() {
-    // Copy the offset option.
-    $pager = array(
-      'type' => 'none',
-      'options' => $this->display->handler->options['pager']['options'],
-    );
-    $this->display->handler->set_option('pager', $pager);
-  }
-
-  function options_form(&$form, &$form_state) {
-    $form['base_path'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Base path'),
-      '#default_value' => $this->options['base_path'],
-      '#description' => t('Define the base path for links in this summary
-        view, i.e. http://example.com/<strong>your_view_path/archive</strong>.
-        Do not include beginning and ending forward slash. If this value
-        is empty, views will use the first path found as the base path,
-        in page displays, or / if no path could be found.'),
-    );
-    $form['count'] = array(
-      '#type' => 'checkbox',
-      '#default_value' => !empty($this->options['count']),
-      '#title' => t('Display record count with link'),
-    );
-
-    $form['hide'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Hide the "Go" button'),
-      '#default_value' => !empty($this->options['hide']),
-      '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'),
-    );
-
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Button text'),
-      '#default_value' => $this->options['text'],
-    );
-
-    $form['choose'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Choose text'),
-      '#default_value' => $this->options['choose'],
-      '#description' => t('The text that will appear as the selected option in the jump menu.'),
-    );
-
-    $form['default_value'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Select the current contextual filter value'),
-      '#default_value' => !empty($this->options['default_value']),
-      '#description' => t('If checked, the current contextual filter value will be displayed as the default option in the jump menu, if applicable.'),
-    );
-  }
-
-  function render() {
-    $argument = $this->view->argument[$this->view->build_info['summary_level']];
-
-    $url_options = array();
-
-    if (!empty($this->view->exposed_raw_input)) {
-      $url_options['query'] = $this->view->exposed_raw_input;
-    }
-
-    $options = array();
-    $default_value = '';
-    $row_args = array();
-    foreach ($this->view->result as $id => $row) {
-      $row_args[$id] = $argument->summary_argument($row);
-    }
-    $argument->process_summary_arguments($row_args);
-
-    foreach ($this->view->result as $id => $row) {
-      $args = $this->view->args;
-      $args[$argument->position] = $row_args[$id];
-      $base_path = NULL;
-      if (!empty($argument->options['summary_options']['base_path'])) {
-        $base_path = $argument->options['summary_options']['base_path'];
-      }
-      $path = url($this->view->get_url($args, $base_path), $url_options);
-      $summary_value = strip_tags($argument->summary_name($row));
-      $key = md5($path . $summary_value) . "::" . $path;
-
-      $options[$key] = $summary_value;
-      if (!empty($this->options['count'])) {
-        $options[$key] .= ' (' . intval($row->{$argument->count_alias}) . ')';
-      }
-      if ($this->options['default_value'] && current_path() == $this->view->get_url($args)) {
-        $default_value = $key;
-      }
-    }
-
-    ctools_include('jump-menu');
-    $settings = array(
-      'hide' => $this->options['hide'],
-      'button' => $this->options['text'],
-      'choose' => $this->options['choose'],
-      'default_value' => $default_value,
-    );
-
-    $form = drupal_get_form('ctools_jump_menu', $options, $settings);
-    return drupal_render($form);
-  }
-}
diff --git a/plugins/views_plugin_style_summary_unformatted.inc b/plugins/views_plugin_style_summary_unformatted.inc
deleted file mode 100644
index fc46624..0000000
--- a/plugins/views_plugin_style_summary_unformatted.inc
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the unformatted summary style plugin.
- */
-
-/**
- * The default style plugin for summaries.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_summary_unformatted extends views_plugin_style_summary {
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['inline'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['separator'] = array('default' => '');
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['inline'] = array(
-      '#type' => 'checkbox',
-      '#default_value' => !empty($this->options['inline']),
-      '#title' => t('Display items inline'),
-    );
-    $form['separator'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Separator'),
-      '#default_value' => $this->options['separator'],
-    );
-  }
-}
diff --git a/plugins/views_plugin_style_table.inc b/plugins/views_plugin_style_table.inc
deleted file mode 100644
index b4aa6a9..0000000
--- a/plugins/views_plugin_style_table.inc
+++ /dev/null
@@ -1,320 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains the table style plugin.
- */
-
-/**
- * Style plugin to render each item as a row in a table.
- *
- * @ingroup views_style_plugins
- */
-class views_plugin_style_table extends views_plugin_style {
-
-  /**
-   * Contains the current active sort column.
-   * @var string
-   */
-  public $active;
-
-  /**
-   * Contains the current active sort order, either desc or asc.
-   * @var string
-   */
-  public $order;
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['columns'] = array('default' => array());
-    $options['default'] = array('default' => '');
-    $options['info'] = array('default' => array());
-    $options['override'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['sticky'] = array('default' => FALSE, 'bool' => TRUE);
-    $options['order'] = array('default' => 'asc');
-    $options['summary'] = array('default' => '', 'translatable' => TRUE);
-    $options['empty_table'] = array('default' => FALSE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  /**
-   * Determine if we should provide sorting based upon $_GET inputs
-   *
-   * @return bool
-   */
-  function build_sort() {
-    if (!isset($_GET['order']) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) {
-      return TRUE;
-    }
-
-    // If a sort we don't know anything about gets through, exit gracefully.
-    if (isset($_GET['order']) && empty($this->view->field[$_GET['order']])) {
-      return TRUE;
-    }
-
-    // Let the builder know whether or not we're overriding the default sorts.
-    return empty($this->options['override']);
-  }
-
-  /**
-   * Add our actual sort criteria
-   */
-  function build_sort_post() {
-    if (!isset($_GET['order'])) {
-      // check for a 'default' clicksort. If there isn't one, exit gracefully.
-      if (empty($this->options['default'])) {
-        return;
-      }
-      $sort = $this->options['default'];
-      if (!empty($this->options['info'][$sort]['default_sort_order'])) {
-        $this->order = $this->options['info'][$sort]['default_sort_order'];
-      }
-      else {
-        $this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc';
-      }
-    }
-    else {
-      $sort = $_GET['order'];
-      // Store the $order for later use.
-      $this->order = !empty($_GET['sort']) ? strtolower($_GET['sort']) : 'asc';
-    }
-
-    // If a sort we don't know anything about gets through, exit gracefully.
-    if (empty($this->view->field[$sort])) {
-      return;
-    }
-
-    // Ensure $this->order is valid.
-    if ($this->order != 'asc' && $this->order != 'desc') {
-      $this->order = 'asc';
-    }
-
-    // Store the $sort for later use.
-    $this->active = $sort;
-
-    // Tell the field to click sort.
-    $this->view->field[$sort]->click_sort($this->order);
-  }
-
-  /**
-   * Normalize a list of columns based upon the fields that are
-   * available. This compares the fields stored in the style handler
-   * to the list of fields actually in the view, removing fields that
-   * have been removed and adding new fields in their own column.
-   *
-   * - Each field must be in a column.
-   * - Each column must be based upon a field, and that field
-   *   is somewhere in the column.
-   * - Any fields not currently represented must be added.
-   * - Columns must be re-ordered to match the fields.
-   *
-   * @param $columns
-   *   An array of all fields; the key is the id of the field and the
-   *   value is the id of the column the field should be in.
-   * @param $fields
-   *   The fields to use for the columns. If not provided, they will
-   *   be requested from the current display. The running render should
-   *   send the fields through, as they may be different than what the
-   *   display has listed due to access control or other changes.
-   *
-   * @return array
-   *    An array of all the sanitized columns.
-   */
-  function sanitize_columns($columns, $fields = NULL) {
-    $sanitized = array();
-    if ($fields === NULL) {
-      $fields = $this->display->handler->get_option('fields');
-    }
-    // Preconfigure the sanitized array so that the order is retained.
-    foreach ($fields as $field => $info) {
-      // Set to itself so that if it isn't touched, it gets column
-      // status automatically.
-      $sanitized[$field] = $field;
-    }
-
-    foreach ($columns as $field => $column) {
-      // first, make sure the field still exists.
-      if (!isset($sanitized[$field])) {
-        continue;
-      }
-
-      // If the field is the column, mark it so, or the column
-      // it's set to is a column, that's ok
-      if ($field == $column || $columns[$column] == $column && !empty($sanitized[$column])) {
-        $sanitized[$field] = $column;
-      }
-      // Since we set the field to itself initially, ignoring
-      // the condition is ok; the field will get its column
-      // status back.
-    }
-
-    return $sanitized;
-  }
-
-  /**
-   * Render the given style.
-   */
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $handlers = $this->display->handler->get_handlers('field');
-    if (empty($handlers)) {
-      $form['error_markup'] = array(
-        '#markup' => '<div class="error messages">' . t('You need at least one field before you can configure your table settings') . '</div>',
-      );
-      return;
-    }
-
-    $form['override'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Override normal sorting if click sorting is used'),
-      '#default_value' => !empty($this->options['override']),
-    );
-
-    $form['sticky'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable Drupal style "sticky" table headers (Javascript)'),
-      '#default_value' => !empty($this->options['sticky']),
-      '#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'),
-    );
-
-    $form['summary'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Table summary'),
-      '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'),
-      '#default_value' => $this->options['summary'],
-      '#maxlength' => 255,
-    );
-
-    // Note: views UI registers this theme handler on our behalf. Your module
-    // will have to register your theme handlers if you do stuff like this.
-    $form['#theme'] = 'views_ui_style_plugin_table';
-
-    $columns = $this->sanitize_columns($this->options['columns']);
-
-    // Create an array of allowed columns from the data we know:
-    $field_names = $this->display->handler->get_field_labels();
-
-    if (isset($this->options['default'])) {
-      $default = $this->options['default'];
-      if (!isset($columns[$default])) {
-        $default = -1;
-      }
-    }
-    else {
-      $default = -1;
-    }
-
-    foreach ($columns as $field => $column) {
-      $column_selector = ':input[name="style_options[columns][' . $field . ']"]';
-
-      $form['columns'][$field] = array(
-        '#type' => 'select',
-        '#options' => $field_names,
-        '#default_value' => $column,
-      );
-      if ($handlers[$field]->click_sortable()) {
-        $form['info'][$field]['sortable'] = array(
-          '#type' => 'checkbox',
-          '#default_value' => !empty($this->options['info'][$field]['sortable']),
-          '#states' => array(
-            'visible' => array(
-              $column_selector => array('value' => $field),
-            ),
-          ),
-        );
-        $form['info'][$field]['default_sort_order'] = array(
-          '#type' => 'select',
-          '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')),
-          '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc',
-          '#states' => array(
-            'visible' => array(
-              $column_selector => array('value' => $field),
-              ':input[name="style_options[info][' . $field . '][sortable]"]' => array('checked' => TRUE),
-            ),
-          ),
-        );
-        // Provide an ID so we can have such things.
-        $radio_id = drupal_html_id('edit-default-' . $field);
-        $form['default'][$field] = array(
-          '#type' => 'radio',
-          '#return_value' => $field,
-          '#parents' => array('style_options', 'default'),
-          '#id' => $radio_id,
-          // because 'radio' doesn't fully support '#id' =(
-          '#attributes' => array('id' => $radio_id),
-          '#default_value' => $default,
-          '#states' => array(
-            'visible' => array(
-              $column_selector => array('value' => $field),
-            ),
-          ),
-        );
-      }
-      $form['info'][$field]['align'] = array(
-        '#type' => 'select',
-        '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '',
-        '#options' => array(
-          '' => t('None'),
-          'views-align-left' => t('Left'),
-          'views-align-center' => t('Center'),
-          'views-align-right' => t('Right'),
-          ),
-        '#states' => array(
-          'visible' => array(
-            $column_selector => array('value' => $field),
-          ),
-        ),
-      );
-      $form['info'][$field]['separator'] = array(
-        '#type' => 'textfield',
-        '#size' => 10,
-        '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '',
-        '#states' => array(
-          'visible' => array(
-            $column_selector => array('value' => $field),
-          ),
-        ),
-      );
-      $form['info'][$field]['empty_column'] = array(
-        '#type' => 'checkbox',
-        '#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE,
-        '#states' => array(
-          'visible' => array(
-            $column_selector => array('value' => $field),
-          ),
-        ),
-      );
-
-      // markup for the field name
-      $form['info'][$field]['name'] = array(
-        '#markup' => $field_names[$field],
-      );
-    }
-
-    // Provide a radio for no default sort
-    $form['default'][-1] = array(
-      '#type' => 'radio',
-      '#return_value' => -1,
-      '#parents' => array('style_options', 'default'),
-      '#id' => 'edit-default-0',
-      '#default_value' => $default,
-    );
-
-    $form['empty_table'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Show the empty text in the table'),
-      '#default_value' => $this->options['empty_table'],
-      '#description' => t('Per default the table is hidden for an empty view. With this option it is posible to show an empty table with the text in it.'),
-    );
-
-    $form['description_markup'] = array(
-      '#markup' => '<div class="description form-item">' . t('Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section.') . '</div>',
-    );
-  }
-
-  function even_empty() {
-    return parent::even_empty() || !empty($this->options['empty_table']);
-  }
-}
diff --git a/plugins/views_wizard/comment.inc b/plugins/views_wizard/comment.inc
deleted file mode 100644
index a910788..0000000
--- a/plugins/views_wizard/comment.inc
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for comment views.
- */
-
-// Parent plugin.
-if (module_exists('comment')) {
-  $plugin = array(
-    'name' => 'comment',
-    'base_table' => 'comment',
-    'created_column' => 'created',
-    'form_wizard_class' => array(
-      'file' => 'views_ui_comment_views_wizard.class.php',
-      'class' => 'ViewsUiCommentViewsWizard',
-    ),
-    'title' => t('Comments'),
-    'filters' => array(
-      'status' => array(
-        'value' => COMMENT_PUBLISHED,
-        'table' => 'comment',
-        'field' => 'status',
-      ),
-      'status_node' => array(
-        'value' => NODE_PUBLISHED,
-        'table' => 'node',
-        'field' => 'status',
-        'relationship' => 'nid',
-      ),
-    ),
-    'path_field' => array(
-      'id' => 'cid',
-      'table' => 'comment',
-      'field' => 'cid',
-      'exclude' => TRUE,
-      'link_to_comment' => FALSE,
-      'alter' => array(
-        'alter_text' => 1,
-        'text' => 'comment/[cid]#comment-[cid]',
-      ),
-    ),
-  );
-}
diff --git a/plugins/views_wizard/file_managed.inc b/plugins/views_wizard/file_managed.inc
deleted file mode 100644
index 049ce1b..0000000
--- a/plugins/views_wizard/file_managed.inc
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for managed file views.
- */
-
-$plugin = array(
-  'name' => 'file_managed',
-  'base_table' => 'file_managed',
-  'created_column' => 'timestamp',
-  'form_wizard_class' => array(
-    'file' => 'views_ui_file_managed_views_wizard.class.php',
-    'class' => 'ViewsUiFileManagedViewsWizard',
-  ),
-  'title' => t('Files'),
-  'filters' => array(
-  ),
-  'path_field' => array(
-    'id' => 'uri',
-    'table' => 'file_managed',
-    'field' => 'uri',
-    'exclude' => TRUE,
-    'file_download_path' => TRUE,
-  ),
-);
diff --git a/plugins/views_wizard/node.inc b/plugins/views_wizard/node.inc
deleted file mode 100644
index ccca48d..0000000
--- a/plugins/views_wizard/node.inc
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for node views.
- */
-
-$plugin = array(
-  'name' => 'node',
-  'base_table' => 'node',
-  'created_column' => 'created',
-  'available_sorts' => array(
-    'title:DESC' => t('Title')
-  ),
-  'form_wizard_class' => array(
-    'file' => 'views_ui_node_views_wizard.class.php',
-    'class' => 'ViewsUiNodeViewsWizard',
-  ),
-  'title' => t('Content'),
-  'filters' => array(
-    'status' => array(
-      'value' => NODE_PUBLISHED,
-      'table' => 'node',
-      'field' => 'status',
-    ),
-  ),
-  'path_field' => array(
-    'id' => 'nid',
-    'table' => 'node',
-    'field' => 'nid',
-    'exclude' => TRUE,
-    'link_to_node' => FALSE,
-    'alter' => array(
-      'alter_text' => 1,
-      'text' => 'node/[nid]',
-    ),
-  ),
-);
-
-if (module_exists('statistics')) {
-  $plugin['available_sorts']['node_counter-totalcount:DESC'] = t('Number of hits');
-}
diff --git a/plugins/views_wizard/node_revision.inc b/plugins/views_wizard/node_revision.inc
deleted file mode 100644
index ddf1d61..0000000
--- a/plugins/views_wizard/node_revision.inc
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for node revision views.
- */
-
-$plugin = array(
-  'name' => 'node_revision',
-  'base_table' => 'node_revision',
-  'created_column' => 'timestamp',
-  'form_wizard_class' => array(
-    'file' => 'views_ui_node_revision_views_wizard.class.php',
-    'class' => 'ViewsUiNodeRevisionViewsWizard',
-  ),
-  'title' => t('Content revisions'),
-  'filters' => array(
-    'status' => array(
-      'value' => '1',
-      'table' => 'node', // @todo - unclear if this should be node or node_revision
-      'field' => 'status',
-    ),
-  ),
-  'path_field' => array(
-    'id' => 'vid',
-    'table' => 'node_revision',
-    'field' => 'vid',
-    'exclude' => TRUE,
-    'alter' => array(
-      'alter_text' => 1,
-      'text' => 'node/[nid]/revisions/[vid]/view',
-    ),
-  ),
-  'path_fields_supplemental' => array(
-    array(
-      'id' => 'nid',
-      'table' => 'node',
-      'field' => 'nid',
-      'exclude' => TRUE,
-      'link_to_node' => FALSE,
-    ),
-  ),
-);
diff --git a/plugins/views_wizard/taxonomy_term.inc b/plugins/views_wizard/taxonomy_term.inc
deleted file mode 100644
index 599e354..0000000
--- a/plugins/views_wizard/taxonomy_term.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for taxonomy term views.
- */
-
-if (module_exists('taxonomy')) {
-  $plugin = array(
-    'name' => 'taxonomy_term',
-    'base_table' => 'taxonomy_term_data',
-    'form_wizard_class' => array(
-      'file' => 'views_ui_taxonomy_term_views_wizard.class.php',
-      'class' => 'ViewsUiTaxonomyTermViewsWizard',
-    ),
-    'title' => t('Taxonomy terms'),
-    'filters' => array(
-    ),
-    'path_field' => array(
-      'id' => 'tid',
-      'table' => 'taxonomy_term_data',
-      'field' => 'tid',
-      'exclude' => TRUE,
-      'alter' => array(
-        'alter_text' => 1,
-        'text' => 'taxonomy/term/[tid]',
-      ),
-    ),
-  );
-}
diff --git a/plugins/views_wizard/users.inc b/plugins/views_wizard/users.inc
deleted file mode 100644
index 176a9e1..0000000
--- a/plugins/views_wizard/users.inc
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Views wizard for user views.
- */
-
-$plugin = array(
-  'name' => 'users',
-  'base_table' => 'users',
-  'created_column' => 'created',
-  'form_wizard_class' => array(
-    'file' => 'views_ui_users_views_wizard.class.php',
-    'class' => 'ViewsUiUsersViewsWizard',
-  ),
-  'title' => t('Users'),
-  'filters' => array(
-    'status' => array(
-      'value' => '1',
-      'table' => 'users',
-      'field' => 'status',
-    ),
-  ),
-  'path_field' => array(
-    'id' => 'uid',
-    'table' => 'users',
-    'field' => 'uid',
-    'exclude' => TRUE,
-    'link_to_user' => FALSE,
-    'alter' => array(
-      'alter_text' => 1,
-      'text' => 'user/[uid]',
-    ),
-  ),
-);
diff --git a/plugins/views_wizard/views_ui_base_views_wizard.class.php b/plugins/views_wizard/views_ui_base_views_wizard.class.php
deleted file mode 100644
index 4f89be9..0000000
--- a/plugins/views_wizard/views_ui_base_views_wizard.class.php
+++ /dev/null
@@ -1,939 +0,0 @@
-<?php
-
-/**
- * @file
- * Provides the interface and base class for Views Wizard plugins.
- */
-
-use Drupal\views\View;
-
-/**
- * Defines a common interface for Views Wizard plugins.
- */
-interface ViewsWizardInterface {
-  function __construct($plugin);
-
-  /**
-   * For AJAX callbacks to build other elements in the "show" form.
-   */
-  function build_form($form, &$form_state);
-
-  /**
-   * Validate form and values.
-   *
-   * @return an array of form errors.
-   */
-  function validate($form, &$form_state);
-
-  /**
-   * Create a new View from form values.
-   *
-   * @return a view object.
-   *
-   * @throws ViewsWizardException in the event of a problem.
-   */
-  function create_view($form, &$form_state);
-}
-
-/**
- * A custom exception class for our errors.
- */
-class ViewsWizardException extends Exception {
-}
-
-/**
- * A very generic Views Wizard class - can be constructed for any base table.
- */
-class ViewsUiBaseViewsWizard implements ViewsWizardInterface {
-  protected $base_table;
-  protected $entity_type;
-  protected $entity_info = array();
-  protected $validated_views = array();
-  protected $plugin = array();
-  protected $filter_defaults = array(
-    'id' => NULL,
-    'expose' => array('operator' => FALSE),
-    'group' => 1,
-  );
-
-  function __construct($plugin) {
-    $this->base_table = $plugin['base_table'];
-    $default = $this->filter_defaults;
-
-    if (isset($plugin['filters'])) {
-      foreach ($plugin['filters'] as $name => $info) {
-        $default['id'] = $name;
-        $plugin['filters'][$name] = $info + $default;
-      }
-    }
-
-    $this->plugin = $plugin;
-
-    $entities = entity_get_info();
-    foreach ($entities as $entity_type => $entity_info) {
-      if (isset($entity_info['base table']) && $this->base_table == $entity_info['base table']) {
-        $this->entity_info = $entity_info;
-        $this->entity_type = $entity_type;
-      }
-    }
-  }
-
-  function build_form($form, &$form_state) {
-    $style_options = views_fetch_plugin_names('style', 'normal', array($this->base_table));
-    $feed_row_options = views_fetch_plugin_names('row', 'feed', array($this->base_table));
-    $path_prefix = url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=');
-
-    // Add filters and sorts which apply to the view as a whole.
-    $this->build_filters($form, $form_state);
-    $this->build_sorts($form, $form_state);
-
-    $form['displays']['page'] = array(
-      '#type' => 'fieldset',
-      '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend'),),
-      '#tree' => TRUE,
-    );
-    $form['displays']['page']['create'] = array(
-      '#title' => t('Create a page'),
-      '#type' => 'checkbox',
-      '#attributes' => array('class' => array('strong')),
-      '#default_value' => TRUE,
-      '#id' => 'edit-page-create',
-    );
-
-    // All options for the page display are included in this container so they
-    // can be hidden en masse when the "Create a page" checkbox is unchecked.
-    $form['displays']['page']['options'] = array(
-      '#type' => 'container',
-      '#attributes' => array('class' => array('options-set'),),
-      '#states' => array(
-        'visible' => array(
-          ':input[name="page[create]"]' => array('checked' => TRUE),
-        ),
-      ),
-      '#pre_render' => array('ctools_dependent_pre_render'),
-      '#prefix' => '<div><div id="edit-page-wrapper">',
-      '#suffix' => '</div></div>',
-      '#parents' => array('page'),
-    );
-
-    $form['displays']['page']['options']['title'] = array(
-      '#title' => t('Page title'),
-      '#type' => 'textfield',
-    );
-    $form['displays']['page']['options']['path'] = array(
-      '#title' => t('Path'),
-      '#type' => 'textfield',
-      '#field_prefix' => $path_prefix,
-    );
-    $form['displays']['page']['options']['style'] = array(
-      '#type' => 'fieldset',
-      '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')),
-    );
-
-    // Create the dropdown for choosing the display format.
-    $form['displays']['page']['options']['style']['style_plugin'] = array(
-      '#title' => t('Display format'),
-      '#help_topic' => 'style',
-      '#type' => 'select',
-      '#options' => $style_options,
-    );
-    $style_form = &$form['displays']['page']['options']['style'];
-    $style_form['style_plugin']['#default_value'] = views_ui_get_selected($form_state, array('page', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
-    // Changing this dropdown updates $form['displays']['page']['options'] via
-    // AJAX.
-    views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'page', 'options'));
-
-    $this->build_form_style($form, $form_state, 'page');
-    $form['displays']['page']['options']['items_per_page'] = array(
-      '#title' => t('Items to display'),
-      '#type' => 'textfield',
-      '#default_value' => '10',
-      '#size' => 5,
-      '#element_validate' => array('views_element_validate_integer'),
-    );
-    $form['displays']['page']['options']['pagerz'] = array(
-      '#title' => t('Use a pager'),
-      '#type' => 'checkbox',
-      '#default_value' => TRUE,
-    );
-    $form['displays']['page']['options']['link'] = array(
-      '#title' => t('Create a menu link'),
-      '#type' => 'checkbox',
-      '#id' => 'edit-page-link',
-    );
-    $form['displays']['page']['options']['link_properties'] = array(
-      '#type' => 'container',
-      '#states' => array(
-        'visible' => array(
-          ':input[name="page[link]"]' => array('checked' => TRUE),
-        ),
-      ),
-      '#prefix' => '<div id="edit-page-link-properties-wrapper">',
-      '#suffix' => '</div>',
-    );
-    if (module_exists('menu')) {
-      $menu_options = menu_get_menus();
-    }
-    else {
-      // These are not yet translated.
-      $menu_options = menu_list_system_menus();
-      foreach ($menu_options as $name => $title) {
-        $menu_options[$name] = t($title);
-      }
-    }
-    $form['displays']['page']['options']['link_properties']['menu_name'] = array(
-      '#title' => t('Menu'),
-      '#type' => 'select',
-      '#options' => $menu_options,
-    );
-    $form['displays']['page']['options']['link_properties']['title'] = array(
-      '#title' => t('Link text'),
-      '#type' => 'textfield',
-    );
-    // Only offer a feed if we have at least one available feed row style.
-    if ($feed_row_options) {
-      $form['displays']['page']['options']['feed'] = array(
-        '#title' => t('Include an RSS feed'),
-        '#type' => 'checkbox',
-        '#id' => 'edit-page-feed',
-      );
-      $form['displays']['page']['options']['feed_properties'] = array(
-        '#type' => 'container',
-        '#states' => array(
-          'visible' => array(
-            ':input[name="page[feed]"]' => array('checked' => TRUE),
-          ),
-        ),
-        '#prefix' => '<div id="edit-page-feed-properties-wrapper">',
-        '#suffix' => '</div>',
-      );
-      $form['displays']['page']['options']['feed_properties']['path'] = array(
-        '#title' => t('Feed path'),
-        '#type' => 'textfield',
-        '#field_prefix' => $path_prefix,
-      );
-      // This will almost never be visible.
-      $form['displays']['page']['options']['feed_properties']['row_plugin'] = array(
-        '#title' => t('Feed row style'),
-        '#type' => 'select',
-        '#options' => $feed_row_options,
-        '#default_value' => key($feed_row_options),
-        '#access' => (count($feed_row_options) > 1),
-        '#states' => array(
-          'visible' => array(
-            ':input[name="page[feed]"]' => array('checked' => TRUE),
-          ),
-        ),
-        '#pre_render' => array('ctools_dependent_pre_render'),
-        '#prefix' => '<div id="edit-page-feed-properties-row-plugin-wrapper">',
-        '#suffix' => '</div>',
-      );
-    }
-
-    $form['displays']['block'] = array(
-      '#type' => 'fieldset',
-      '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend'),),
-      '#tree' => TRUE,
-    );
-    $form['displays']['block']['create'] = array(
-      '#title' => t('Create a block'),
-      '#type' => 'checkbox',
-      '#attributes' => array('class' => array('strong')),
-      '#id' => 'edit-block-create',
-    );
-
-    // All options for the block display are included in this container so they
-    // can be hidden en masse when the "Create a block" checkbox is unchecked.
-    $form['displays']['block']['options'] = array(
-      '#type' => 'container',
-      '#attributes' => array('class' => array('options-set'),),
-      '#states' => array(
-        'visible' => array(
-          ':input[name="block[create]"]' => array('checked' => TRUE),
-        ),
-      ),
-      '#pre_render' => array('ctools_dependent_pre_render'),
-      '#prefix' => '<div id="edit-block-wrapper">',
-      '#suffix' => '</div>',
-      '#parents' => array('block'),
-    );
-
-    $form['displays']['block']['options']['title'] = array(
-      '#title' => t('Block title'),
-      '#type' => 'textfield',
-    );
-    $form['displays']['block']['options']['style'] = array(
-      '#type' => 'fieldset',
-      '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')),
-    );
-
-    // Create the dropdown for choosing the display format.
-    $form['displays']['block']['options']['style']['style_plugin'] = array(
-      '#title' => t('Display format'),
-      '#help_topic' => 'style',
-      '#type' => 'select',
-      '#options' => $style_options,
-    );
-    $style_form = &$form['displays']['block']['options']['style'];
-    $style_form['style_plugin']['#default_value'] = views_ui_get_selected($form_state, array('block', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
-    // Changing this dropdown updates $form['displays']['block']['options'] via
-    // AJAX.
-    views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'block', 'options'));
-
-    $this->build_form_style($form, $form_state, 'block');
-    $form['displays']['block']['options']['items_per_page'] = array(
-      '#title' => t('Items per page'),
-      '#type' => 'textfield',
-      '#default_value' => '5',
-      '#size' => 5,
-      '#element_validate' => array('views_element_validate_integer'),
-    );
-    $form['displays']['block']['options']['pager'] = array(
-      '#title' => t('Use a pager'),
-      '#type' => 'checkbox',
-      '#default_value' => FALSE,
-    );
-
-    return $form;
-  }
-
-  /**
-   * Build the part of the form that builds the display format options.
-   */
-  protected function build_form_style(&$form, &$form_state, $type) {
-    $style_form =& $form['displays'][$type]['options']['style'];
-    $style = $style_form['style_plugin']['#default_value'];
-    $style_plugin = views_get_plugin('style', $style);
-    if (isset($style_plugin) && $style_plugin->uses_row_plugin()) {
-      $options = $this->row_style_options($type);
-      $style_form['row_plugin'] = array(
-        '#type' => 'select',
-        '#title' => t('of'),
-        '#options' => $options,
-        '#access' => count($options) > 1,
-      );
-      // For the block display, the default value should be "titles (linked)",
-      // if it's available (since that's the most common use case).
-      $block_with_linked_titles_available = ($type == 'block' && isset($options['titles_linked']));
-      $default_value = $block_with_linked_titles_available ? 'titles_linked' : key($options);
-      $style_form['row_plugin']['#default_value'] = views_ui_get_selected($form_state, array($type, 'style', 'row_plugin'), $default_value, $style_form['row_plugin']);
-      // Changing this dropdown updates the individual row options via AJAX.
-      views_ui_add_ajax_trigger($style_form, 'row_plugin', array('displays', $type, 'options', 'style', 'row_options'));
-
-      // This is the region that can be updated by AJAX. The base class doesn't
-      // add anything here, but child classes can.
-      $style_form['row_options'] = array(
-        '#theme_wrappers' => array('container'),
-      );
-    }
-    elseif ($style_plugin->uses_fields()) {
-      $style_form['row_plugin'] = array('#markup' => '<span>' . t('of fields') . '</span>');
-    }
-  }
-
-  /**
-   * Add possible row style options.
-   *
-   * Per default use fields with base field.
-   */
-  protected function row_style_options($type) {
-    $data = views_fetch_data($this->base_table);
-    // Get all available row plugins by default.
-    $options = views_fetch_plugin_names('row', 'normal', array($this->base_table));
-    return $options;
-  }
-
-  /**
-   * Build the part of the form that allows the user to select the view's filters.
-   *
-   * By default, this adds "of type" and "tagged with" filters (when they are
-   * available).
-   */
-  protected function build_filters(&$form, &$form_state) {
-    // Find all the fields we are allowed to filter by.
-    $fields = views_fetch_fields($this->base_table, 'filter');
-
-    $entity_info = $this->entity_info;
-    // If the current base table support bundles and has more than one (like user).
-    if (isset($entity_info['bundle keys']) && isset($entity_info['bundles'])) {
-      // Get all bundles and their human readable names.
-      $options = array('all' => t('All'));
-      foreach ($entity_info['bundles'] as $type => $bundle) {
-        $options[$type] = $bundle['label'];
-      }
-      $form['displays']['show']['type'] = array(
-        '#type' => 'select',
-        '#title' => t('of type'),
-        '#options' => $options,
-      );
-      $selected_bundle = views_ui_get_selected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
-      $form['displays']['show']['type']['#default_value'] = $selected_bundle;
-      // Changing this dropdown updates the entire content of $form['displays']
-      // via AJAX, since each bundle might have entirely different fields
-      // attached to it, etc.
-      views_ui_add_ajax_trigger($form['displays']['show'], 'type', array('displays'));
-    }
-
-    // Check if we are allowed to filter by taxonomy, and if so, add the
-    // "tagged with" filter to the view.
-    //
-    // We construct this filter using taxonomy_index.tid (which limits the
-    // filtering to a specific vocabulary) rather than taxonomy_term_data.name
-    // (which matches terms in any vocabulary). This is because it is a more
-    // commonly-used filter that works better with the autocomplete UI, and
-    // also to avoid confusion with other vocabularies on the site that may
-    // have terms with the same name but are not used for free tagging.
-    //
-    // The downside is that if there *is* more than one vocabulary on the site
-    // that is used for free tagging, the wizard will only be able to make the
-    // "tagged with" filter apply to one of them (see below for the method it
-    // uses to choose).
-    if (isset($fields['taxonomy_index.tid'])) {
-      // Check if this view will be displaying fieldable entities.
-      if (!empty($entity_info['fieldable'])) {
-        // Find all "tag-like" taxonomy fields associated with the view's
-        // entities. If a particular entity type (i.e., bundle) has been
-        // selected above, then we only search for taxonomy fields associated
-        // with that bundle. Otherwise, we use all bundles.
-        $bundles = array_keys($entity_info['bundles']);
-        // Double check that this is a real bundle before using it (since above
-        // we added a dummy option 'all' to the bundle list on the form).
-        if (isset($selected_bundle) && in_array($selected_bundle, $bundles)) {
-          $bundles = array($selected_bundle);
-        }
-        $tag_fields = array();
-        foreach ($bundles as $bundle) {
-          foreach (field_info_instances($this->entity_type, $bundle) as $instance) {
-            // We define "tag-like" taxonomy fields as ones that use the
-            // "Autocomplete term widget (tagging)" widget.
-            if ($instance['widget']['type'] == 'taxonomy_autocomplete') {
-              $tag_fields[] = $instance['field_name'];
-            }
-          }
-        }
-        $tag_fields = array_unique($tag_fields);
-        if (!empty($tag_fields)) {
-          // If there is more than one "tag-like" taxonomy field available to
-          // the view, we can only make our filter apply to one of them (as
-          // described above). We choose 'field_tags' if it is available, since
-          // that is created by the Standard install profile in core and also
-          // commonly used by contrib modules; thus, it is most likely to be
-          // associated with the "main" free-tagging vocabulary on the site.
-          if (in_array('field_tags', $tag_fields)) {
-            $tag_field_name = 'field_tags';
-          }
-          else {
-            $tag_field_name = reset($tag_fields);
-          }
-          // Add the autocomplete textfield to the wizard.
-          $form['displays']['show']['tagged_with'] = array(
-            '#type' => 'textfield',
-            '#title' => t('tagged with'),
-            '#autocomplete_path' => 'taxonomy/autocomplete/' . $tag_field_name,
-            '#size' => 30,
-            '#maxlength' => 1024,
-            '#field_name' => $tag_field_name,
-            '#element_validate' => array('views_ui_taxonomy_autocomplete_validate'),
-          );
-        }
-      }
-    }
-  }
-
-  /**
-   * Build the part of the form that allows the user to select the view's sort order.
-   *
-   * By default, this adds a "sorted by [date]" filter (when it is available).
-   */
-  protected function build_sorts(&$form, &$form_state) {
-    $sorts = array(
-      'none' => t('Unsorted'),
-    );
-    // Check if we are allowed to sort by creation date.
-    if (!empty($this->plugin['created_column'])) {
-      $sorts += array(
-        $this->plugin['created_column'] . ':DESC' => t('Newest first'),
-        $this->plugin['created_column'] . ':ASC' => t('Oldest first'),
-      );
-    }
-    if (isset($this->plugin['available_sorts'])) {
-      $sorts += $this->plugin['available_sorts'];
-    }
-
-    // If there is no sorts option available continue.
-    if (!empty($sorts)) {
-      $form['displays']['show']['sort'] = array(
-        '#type' => 'select',
-        '#title' => t('sorted by'),
-        '#options' => $sorts,
-        '#default_value' => isset($this->plugin['created_column']) ? $this->plugin['created_column'] . ':DESC' : 'none',
-      );
-    }
-  }
-
-  protected function instantiate_view($form, &$form_state) {
-    // Build the basic view properties.
-    $view = views_new_view();
-    $view->name = $form_state['values']['name'];
-    $view->human_name = $form_state['values']['human_name'];
-    $view->description = $form_state['values']['description'];
-    $view->tag = 'default';
-    $view->core = VERSION;
-    $view->base_table = $this->base_table;
-
-    // Build all display options for this view.
-    $display_options = $this->build_display_options($form, $form_state);
-
-    // Allow the fully built options to be altered. This happens before adding
-    // the options to the view, so that once they are eventually added we will
-    // be able to get all the overrides correct.
-    $this->alter_display_options($display_options, $form, $form_state);
-
-    $this->add_displays($view, $display_options, $form, $form_state);
-
-    return $view;
-  }
-
-  /**
-   * Build an array of display options for the view.
-   *
-   * @return
-   *   An array whose keys are the names of each display and whose values are
-   *   arrays of options for that display.
-   */
-  protected function build_display_options($form, $form_state) {
-    // Display: Master
-    $display_options['default'] = $this->default_display_options($form, $form_state);
-    $display_options['default'] += array(
-      'filters' => array(),
-      'sorts' => array(),
-    );
-    $display_options['default']['filters'] += $this->default_display_filters($form, $form_state);
-    $display_options['default']['sorts'] += $this->default_display_sorts($form, $form_state);
-
-    // Display: Page
-    if (!empty($form_state['values']['page']['create'])) {
-      $display_options['page'] = $this->page_display_options($form, $form_state);
-
-      // Display: Feed (attached to the page)
-      if (!empty($form_state['values']['page']['feed'])) {
-        $display_options['feed'] = $this->page_feed_display_options($form, $form_state);
-      }
-    }
-
-    // Display: Block
-    if (!empty($form_state['values']['block']['create'])) {
-      $display_options['block'] = $this->block_display_options($form, $form_state);
-    }
-
-    return $display_options;
-  }
-
-  /**
-   * Alter the full array of display options before they are added to the view.
-   */
-  protected function alter_display_options(&$display_options, $form, $form_state) {
-    // If any of the displays use jump menus, we want to add fields to the view
-    // that store the path that will be used in the jump menu. The fields to
-    // use for this are defined by the plugin.
-    if (isset($this->plugin['path_field'])) {
-      $path_field = $this->plugin['path_field'];
-      $path_fields_added = FALSE;
-      foreach ($display_options as $display_type => $options) {
-        if (!empty($options['style_plugin']) && $options['style_plugin'] == 'jump_menu') {
-          // Regardless of how many displays have jump menus, we only need to
-          // add a single set of path fields to the view.
-          if (!$path_fields_added) {
-            // The plugin might provide supplemental fields that it needs to
-            // generate the path (for example, node revisions need the node ID
-            // as well as the revision ID). We need to add these first so they
-            // are available as replacement patterns in the main path field.
-            $path_fields = !empty($this->plugin['path_fields_supplemental']) ? $this->plugin['path_fields_supplemental'] : array();
-            $path_fields[] = &$path_field;
-
-            // Generate a unique ID for each field so we don't overwrite
-            // existing ones.
-            foreach ($path_fields as &$field) {
-              $field['id'] = View::generate_item_id($field['id'], $display_options['default']['fields']);
-              $display_options['default']['fields'][$field['id']] = $field;
-            }
-
-            $path_fields_added = TRUE;
-          }
-
-          // Configure the style plugin to use the path field to generate the
-          // jump menu path.
-          $display_options[$display_type]['style_options']['path'] = $path_field['id'];
-        }
-      }
-    }
-
-    // If any of the displays use the table style, take sure that the fields
-    // always have a labels by unsetting the override.
-    foreach ($display_options as &$options) {
-      if ($options['style_plugin'] == 'table') {
-        foreach ($display_options['default']['fields'] as &$field) {
-          unset($field['label']);
-        }
-      }
-    }
-  }
-
-  /**
-   * Add the array of display options to the view, with appropriate overrides.
-   */
-  protected function add_displays($view, $display_options, $form, $form_state) {
-    // Display: Master
-    $default_display = $view->new_display('default', 'Master', 'default');
-    foreach ($display_options['default'] as $option => $value) {
-      $default_display->set_option($option, $value);
-    }
-
-    // Display: Page
-    if (isset($display_options['page'])) {
-      $display = $view->new_display('page', 'Page', 'page');
-      // The page display is usually the main one (from the user's point of
-      // view). Its options should therefore become the overall view defaults,
-      // so that new displays which are added later automatically inherit them.
-      $this->set_default_options($display_options['page'], $display, $default_display);
-
-      // Display: Feed (attached to the page)
-      if (isset($display_options['feed'])) {
-        $display = $view->new_display('feed', 'Feed', 'feed');
-        $this->set_override_options($display_options['feed'], $display, $default_display);
-      }
-    }
-
-    // Display: Block
-    if (isset($display_options['block'])) {
-      $display = $view->new_display('block', 'Block', 'block');
-      // When there is no page, the block display options should become the
-      // overall view defaults.
-      if (!isset($display_options['page'])) {
-        $this->set_default_options($display_options['block'], $display, $default_display);
-      }
-      else {
-        $this->set_override_options($display_options['block'], $display, $default_display);
-      }
-    }
-  }
-
-  /**
-   * Most subclasses will need to override this method to provide some fields
-   * or a different row plugin.
-   */
-  protected function default_display_options($form, $form_state) {
-    $display_options = array();
-    $display_options['access']['type'] = 'none';
-    $display_options['cache']['type'] = 'none';
-    $display_options['query']['type'] = 'views_query';
-    $display_options['exposed_form']['type'] = 'basic';
-    $display_options['pager']['type'] = 'full';
-    $display_options['style_plugin'] = 'default';
-    $display_options['row_plugin'] = 'fields';
-
-    // Add a least one field so the view validates and the user has already a preview.
-    // Therefore the basefield could provide 'defaults][field]' in it's base settings.
-    // If there is nothing like this choose the first field with a field handler.
-    $data = views_fetch_data($this->base_table);
-    if (isset($data['table']['base']['defaults']['field'])) {
-      $field = $data['table']['base']['defaults']['field'];
-    }
-    else {
-      foreach ($data as $field => $field_data) {
-        if (isset($field_data['field']['handler'])) {
-          break;
-        }
-      }
-    }
-    $display_options['fields'][$field] = array(
-      'table' => $this->base_table,
-      'field' => $field,
-      'id' => $field,
-    );
-
-    return $display_options;
-  }
-
-  protected function default_display_filters($form, $form_state) {
-    $filters = array();
-
-    // Add any filters provided by the plugin.
-    if (isset($this->plugin['filters'])) {
-      foreach ($this->plugin['filters'] as $name => $info) {
-        $filters[$name] = $info;
-      }
-    }
-
-    // Add any filters specified by the user when filling out the wizard.
-    $filters = array_merge($filters, $this->default_display_filters_user($form, $form_state));
-
-    return $filters;
-  }
-
-  protected function default_display_filters_user($form, $form_state) {
-    $filters = array();
-
-    if (!empty($form_state['values']['show']['type']) && $form_state['values']['show']['type'] != 'all') {
-      $bundle_key = $this->entity_info['bundle keys']['bundle'];
-      // Figure out the table where $bundle_key lives. It may not be the same as
-      // the base table for the view; the taxonomy vocabulary machine_name, for
-      // example, is stored in taxonomy_vocabulary, not taxonomy_term_data.
-      $fields = views_fetch_fields($this->base_table, 'filter');
-      if (isset($fields[$this->base_table . '.' . $bundle_key])) {
-        $table = $this->base_table;
-      }
-      else {
-        foreach ($fields as $field_name => $value) {
-          if ($pos = strpos($field_name, '.' . $bundle_key)) {
-            $table = substr($field_name, 0, $pos);
-            break;
-          }
-        }
-      }
-      $table_data = views_fetch_data($table);
-      // Check whether the bundle key filter handler is or an child of it views_handler_filter_in_operator
-      // If it's not just use a single value instead of an array.
-      $handler = $table_data[$bundle_key]['filter']['handler'];
-      if ($handler == 'views_handler_filter_in_operator' || is_subclass_of($handler, 'views_handler_filter_in_operator')) {
-        $value = drupal_map_assoc(array($form_state['values']['show']['type']));
-      }
-      else {
-        $value = $form_state['values']['show']['type'];
-      }
-
-      $filters[$bundle_key] = array(
-        'id' => $bundle_key,
-        'table' => $table,
-        'field' => $bundle_key,
-        'value' => $value,
-      );
-    }
-
-    // @todo: Figure out why this isn't part of node_views_wizard.
-    if (!empty($form_state['values']['show']['tagged_with']['tids'])) {
-      $filters['tid'] = array(
-        'id' => 'tid',
-        'table' => 'taxonomy_index',
-        'field' => 'tid',
-        'value' => $form_state['values']['show']['tagged_with']['tids'],
-        'vocabulary' => $form_state['values']['show']['tagged_with']['vocabulary'],
-      );
-      // If the user entered more than one valid term in the autocomplete
-      // field, they probably intended both of them to be applied.
-      if (count($form_state['values']['show']['tagged_with']['tids']) > 1) {
-        $filters['tid']['operator'] = 'and';
-        // Sort the terms so the filter will be displayed as it normally would
-        // on the edit screen.
-        sort($filters['tid']['value']);
-      }
-    }
-
-    return $filters;
-  }
-
-  protected function default_display_sorts($form, $form_state) {
-    $sorts = array();
-
-    // Add any sorts provided by the plugin.
-    if (isset($this->plugin['sorts'])) {
-      foreach ($this->plugin['sorts'] as $name => $info) {
-        $sorts[$name] = $info;
-      }
-    }
-
-    // Add any sorts specified by the user when filling out the wizard.
-    $sorts = array_merge($sorts, $this->default_display_sorts_user($form, $form_state));
-
-    return $sorts;
-  }
-
-  protected function default_display_sorts_user($form, $form_state) {
-    $sorts = array();
-
-    // Don't add a sort if there is no form value or the user selected none as sort.
-    if (!empty($form_state['values']['show']['sort']) && $form_state['values']['show']['sort'] != 'none') {
-      list($column, $sort) = explode(':', $form_state['values']['show']['sort']);
-      // Column either be a column-name or the table-columnn-ame.
-      $column = explode('-', $column);
-      if (count($column) > 1) {
-        $table = $column[0];
-        $column = $column[1];
-      }
-      else {
-        $table = $this->base_table;
-        $column = $column[0];
-      }
-
-      $sorts[$column] = array(
-        'id' => $column,
-        'table' => $table,
-        'field' => $column,
-        'order' => $sort,
-      );
-    }
-
-    return $sorts;
-  }
-
-  protected function page_display_options($form, $form_state) {
-    $display_options = array();
-    $page = $form_state['values']['page'];
-    $display_options['title'] = $page['title'];
-    $display_options['path'] = $page['path'];
-    $display_options['style_plugin'] = $page['style']['style_plugin'];
-    // Not every style plugin supports row style plugins.
-    $display_options['row_plugin'] = isset($page['style']['row_plugin']) ? $page['style']['row_plugin'] : 'fields';
-    if (empty($page['items_per_page'])) {
-      $display_options['pager']['type'] = 'none';
-    }
-    elseif (isset($page['pager'])) {
-      $display_options['pager']['type'] = 'full';
-    }
-    else {
-      $display_options['pager']['type'] = 'some';
-    }
-    $display_options['pager']['options']['items_per_page'] = $page['items_per_page'];
-    if (!empty($page['link'])) {
-      $display_options['menu']['type'] = 'normal';
-      $display_options['menu']['title'] = $page['link_properties']['title'];
-      $display_options['menu']['name'] = $page['link_properties']['menu_name'];
-    }
-    return $display_options;
-  }
-
-  protected function block_display_options($form, $form_state) {
-    $display_options = array();
-    $block = $form_state['values']['block'];
-    $display_options['title'] = $block['title'];
-    $display_options['style_plugin'] = $block['style']['style_plugin'];
-    $display_options['row_plugin'] = isset($block['style']['row_plugin']) ? $block['style']['row_plugin'] : 'fields';
-    $display_options['pager']['type'] = $block['pager'] ? 'full' : (empty($block['items_per_page']) ? 'none' : 'some');
-    $display_options['pager']['options']['items_per_page'] = $block['items_per_page'];
-    return $display_options;
-  }
-
-  protected function page_feed_display_options($form, $form_state) {
-    $display_options = array();
-    $display_options['pager']['type'] = 'some';
-    $display_options['style_plugin'] = 'rss';
-    $display_options['row_plugin'] = $form_state['values']['page']['feed_properties']['row_plugin'];
-    $display_options['path'] = $form_state['values']['page']['feed_properties']['path'];
-    $display_options['title'] = $form_state['values']['page']['title'];
-    $display_options['displays'] = array(
-      'default' => 'default',
-      'page' => 'page',
-    );
-    return $display_options;
-  }
-
-  /**
-   * Sets options for a display and makes them the default options if possible.
-   *
-   * This function can be used to set options for a display when it is desired
-   * that the options also become the defaults for the view whenever possible.
-   * This should be done for the "primary" display created in the view wizard,
-   * so that new displays which the user adds later will be similar to this
-   * one.
-   *
-   * @param $options
-   *   An array whose keys are the name of each option and whose values are the
-   *   desired values to set.
-   * @param $display
-   *   The display which the options will be applied to. The default display
-   *   will actually be assigned the options (and this display will inherit
-   *   them) when possible.
-   * @param $default_display
-   *   The default display, which will store the options when possible.
-   */
-  protected function set_default_options($options, $display, $default_display) {
-    foreach ($options as $option => $value) {
-      // If the default display supports this option, set the value there.
-      // Otherwise, set it on the provided display.
-      $default_value = $default_display->get_option($option);
-      if (isset($default_value)) {
-        $default_display->set_option($option, $value);
-      }
-      else {
-        $display->set_option($option, $value);
-      }
-    }
-  }
-
-  /**
-   * Sets options for a display, inheriting from the defaults when possible.
-   *
-   * This function can be used to set options for a display when it is desired
-   * that the options inherit from the default display whenever possible. This
-   * avoids setting too many options as overrides, which will be harder for the
-   * user to modify later. For example, if $this->set_default_options() was
-   * previously called on a page display and then this function is called on a
-   * block display, and if the user entered the same title for both displays in
-   * the views wizard, then the view will wind up with the title stored as the
-   * default (with the page and block both inheriting from it).
-   *
-   * @param $options
-   *   An array whose keys are the name of each option and whose values are the
-   *   desired values.
-   * @param $display
-   *   The display which the options will apply to. It will get the options by
-   *   inheritance from the default display when possible.
-   * @param $default_display
-   *   The default display, from which the options will be inherited when
-   *   possible.
-   */
-  protected function set_override_options($options, $display, $default_display) {
-    foreach ($options as $option => $value) {
-      // Only override the default value if it is different from the value that
-      // was provided.
-      $default_value = $default_display->get_option($option);
-      if (!isset($default_value)) {
-        $display->set_option($option, $value);
-      }
-      elseif ($default_value !== $value) {
-        $display->override_option($option, $value);
-      }
-    }
-  }
-
-  protected function retrieve_validated_view($form, $form_state, $unset = TRUE) {
-    $key = hash('sha256', serialize($form_state['values']));
-    $view = (isset($this->validated_views[$key]) ? $this->validated_views[$key] : NULL);
-    if ($unset) {
-      unset($this->validated_views[$key]);
-    }
-    return $view;
-  }
-
-  protected function set_validated_view($form, $form_state, $view) {
-    $key = hash('sha256', serialize($form_state['values']));
-    $this->validated_views[$key] = $view;
-  }
-
-  /**
-   * Instantiates a view and validates values.
-   */
-  function validate($form, &$form_state) {
-    $view = $this->instantiate_view($form, $form_state);
-    $errors = $view->validate();
-    if (!is_array($errors) || empty($errors)) {
-      $this->set_validated_view($form, $form_state, $view);
-      return array();
-    }
-    return $errors;
-  }
-
-  /**
-   * Create a View from values that have been already submitted to validate().
-   *
-   * @throws ViewsWizardException if the values have not been validated.
-   */
- function create_view($form, &$form_state) {
-   $view = $this->retrieve_validated_view($form, $form_state);
-   if (empty($view)) {
-     throw new ViewsWizardException(t('Attempted to create_view with values that have not been validated'));
-   }
-   return $view;
- }
-
-}
diff --git a/plugins/views_wizard/views_ui_comment_views_wizard.class.php b/plugins/views_wizard/views_ui_comment_views_wizard.class.php
deleted file mode 100644
index 09d4994..0000000
--- a/plugins/views_wizard/views_ui_comment_views_wizard.class.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiCommentViewsWizard.
- */
-
-/**
- * Tests creating comment views with the wizard.
- */
-class ViewsUiCommentViewsWizard extends ViewsUiBaseViewsWizard {
-
-  protected function row_style_options($type) {
-    $options = array();
-    $options['comment'] = t('comments');
-    $options['fields'] = t('fields');
-    return $options;
-  }
-
-  protected function build_form_style(&$form, &$form_state, $type) {
-    parent::build_form_style($form, $form_state, $type);
-    $style_form =& $form['displays'][$type]['options']['style'];
-    // Some style plugins don't support row plugins so stop here if that's the
-    // case.
-    if (!isset($style_form['row_plugin']['#default_value'])) {
-      return;
-    }
-    $row_plugin = $style_form['row_plugin']['#default_value'];
-    switch ($row_plugin) {
-      case 'comment':
-        $style_form['row_options']['links'] = array(
-          '#type' => 'select',
-          '#title_display' => 'invisible',
-          '#title' => t('Should links be displayed below each comment'),
-          '#options' => array(
-            1 => t('with links (allow users to reply to the comment, etc.)'),
-            0 => t('without links'),
-          ),
-          '#default_value' => 1,
-        );
-        break;
-    }
-  }
-
-  protected function page_display_options($form, $form_state) {
-    $display_options = parent::page_display_options($form, $form_state);
-    $row_plugin = isset($form_state['values']['page']['style']['row_plugin']) ? $form_state['values']['page']['style']['row_plugin'] : NULL;
-    $row_options = isset($form_state['values']['page']['style']['row_options']) ? $form_state['values']['page']['style']['row_options'] : array();
-    $this->display_options_row($display_options, $row_plugin, $row_options);
-    return $display_options;
-  }
-
-  protected function block_display_options($form, $form_state) {
-    $display_options = parent::block_display_options($form, $form_state);
-    $row_plugin = isset($form_state['values']['block']['style']['row_plugin']) ? $form_state['values']['block']['style']['row_plugin'] : NULL;
-    $row_options = isset($form_state['values']['block']['style']['row_options']) ? $form_state['values']['block']['style']['row_options'] : array();
-    $this->display_options_row($display_options, $row_plugin, $row_options);
-    return $display_options;
-  }
-
-  /**
-   * Set the row style and row style plugins to the display_options.
-   */
-  protected  function display_options_row(&$display_options, $row_plugin, $row_options) {
-    switch ($row_plugin) {
-      case 'comment':
-        $display_options['row_plugin'] = 'comment';
-        $display_options['row_options']['links'] = !empty($row_options['links']);
-        break;
-    }
-  }
-
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-
-    // Add a relationship to nodes.
-    $display_options['relationships']['nid']['id'] = 'nid';
-    $display_options['relationships']['nid']['table'] = 'comment';
-    $display_options['relationships']['nid']['field'] = 'nid';
-    $display_options['relationships']['nid']['required'] = 1;
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: Comment: Title */
-    $display_options['fields']['subject']['id'] = 'subject';
-    $display_options['fields']['subject']['table'] = 'comment';
-    $display_options['fields']['subject']['field'] = 'subject';
-    $display_options['fields']['subject']['label'] = '';
-    $display_options['fields']['subject']['alter']['alter_text'] = 0;
-    $display_options['fields']['subject']['alter']['make_link'] = 0;
-    $display_options['fields']['subject']['alter']['absolute'] = 0;
-    $display_options['fields']['subject']['alter']['trim'] = 0;
-    $display_options['fields']['subject']['alter']['word_boundary'] = 0;
-    $display_options['fields']['subject']['alter']['ellipsis'] = 0;
-    $display_options['fields']['subject']['alter']['strip_tags'] = 0;
-    $display_options['fields']['subject']['alter']['html'] = 0;
-    $display_options['fields']['subject']['hide_empty'] = 0;
-    $display_options['fields']['subject']['empty_zero'] = 0;
-    $display_options['fields']['subject']['link_to_comment'] = 1;
-
-    return $display_options;
-  }
-}
diff --git a/plugins/views_wizard/views_ui_file_managed_views_wizard.class.php b/plugins/views_wizard/views_ui_file_managed_views_wizard.class.php
deleted file mode 100644
index 111b631..0000000
--- a/plugins/views_wizard/views_ui_file_managed_views_wizard.class.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiFileManagedViewsWizard.
- */
-
-/**
- * Tests creating managed files views with the wizard.
- */
-class ViewsUiFileManagedViewsWizard extends ViewsUiBaseViewsWizard {
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: File: Name */
-    $display_options['fields']['filename']['id'] = 'filename';
-    $display_options['fields']['filename']['table'] = 'file_managed';
-    $display_options['fields']['filename']['field'] = 'filename';
-    $display_options['fields']['filename']['label'] = '';
-    $display_options['fields']['filename']['alter']['alter_text'] = 0;
-    $display_options['fields']['filename']['alter']['make_link'] = 0;
-    $display_options['fields']['filename']['alter']['absolute'] = 0;
-    $display_options['fields']['filename']['alter']['trim'] = 0;
-    $display_options['fields']['filename']['alter']['word_boundary'] = 0;
-    $display_options['fields']['filename']['alter']['ellipsis'] = 0;
-    $display_options['fields']['filename']['alter']['strip_tags'] = 0;
-    $display_options['fields']['filename']['alter']['html'] = 0;
-    $display_options['fields']['filename']['hide_empty'] = 0;
-    $display_options['fields']['filename']['empty_zero'] = 0;
-    $display_options['fields']['filename']['link_to_file'] = 1;
-
-    return $display_options;
-  }
-}
diff --git a/plugins/views_wizard/views_ui_node_revision_views_wizard.class.php b/plugins/views_wizard/views_ui_node_revision_views_wizard.class.php
deleted file mode 100644
index 51b0e0c..0000000
--- a/plugins/views_wizard/views_ui_node_revision_views_wizard.class.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiNodeRevisionViewsWizard.
- */
-
-/**
- * Tests creating node revision views with the wizard.
- */
-class ViewsUiNodeRevisionViewsWizard extends ViewsUiNodeViewsWizard {
-
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-    $display_options['access']['perm'] = 'view revisions';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: Content revision: Created date */
-    $display_options['fields']['timestamp']['id'] = 'timestamp';
-    $display_options['fields']['timestamp']['table'] = 'node_revision';
-    $display_options['fields']['timestamp']['field'] = 'timestamp';
-    $display_options['fields']['timestamp']['alter']['alter_text'] = 0;
-    $display_options['fields']['timestamp']['alter']['make_link'] = 0;
-    $display_options['fields']['timestamp']['alter']['absolute'] = 0;
-    $display_options['fields']['timestamp']['alter']['trim'] = 0;
-    $display_options['fields']['timestamp']['alter']['word_boundary'] = 0;
-    $display_options['fields']['timestamp']['alter']['ellipsis'] = 0;
-    $display_options['fields']['timestamp']['alter']['strip_tags'] = 0;
-    $display_options['fields']['timestamp']['alter']['html'] = 0;
-    $display_options['fields']['timestamp']['hide_empty'] = 0;
-    $display_options['fields']['timestamp']['empty_zero'] = 0;
-
-    /* Field: Content revision: Title */
-    $display_options['fields']['title']['id'] = 'title';
-    $display_options['fields']['title']['table'] = 'node_revision';
-    $display_options['fields']['title']['field'] = 'title';
-    $display_options['fields']['title']['label'] = '';
-    $display_options['fields']['title']['alter']['alter_text'] = 0;
-    $display_options['fields']['title']['alter']['make_link'] = 0;
-    $display_options['fields']['title']['alter']['absolute'] = 0;
-    $display_options['fields']['title']['alter']['trim'] = 0;
-    $display_options['fields']['title']['alter']['word_boundary'] = 0;
-    $display_options['fields']['title']['alter']['ellipsis'] = 0;
-    $display_options['fields']['title']['alter']['strip_tags'] = 0;
-    $display_options['fields']['title']['alter']['html'] = 0;
-    $display_options['fields']['title']['hide_empty'] = 0;
-    $display_options['fields']['title']['empty_zero'] = 0;
-    $display_options['fields']['title']['link_to_node'] = 0;
-    $display_options['fields']['title']['link_to_node_revision'] = 1;
-
-    return $display_options;
-  }
-}
diff --git a/plugins/views_wizard/views_ui_node_views_wizard.class.php b/plugins/views_wizard/views_ui_node_views_wizard.class.php
deleted file mode 100644
index 010220e..0000000
--- a/plugins/views_wizard/views_ui_node_views_wizard.class.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiNodeViewsWizard.
- */
-
-/**
- * Tests creating node views with the wizard.
- */
-class ViewsUiNodeViewsWizard extends ViewsUiBaseViewsWizard {
-
-  protected function row_style_options($type) {
-    $options = array();
-    $options['teasers'] = t('teasers');
-    $options['full_posts'] = t('full posts');
-    $options['titles'] = t('titles');
-    $options['titles_linked'] = t('titles (linked)');
-    $options['fields'] = t('fields');
-    return $options;
-  }
-
-  protected function build_form_style(&$form, &$form_state, $type) {
-    parent::build_form_style($form, $form_state, $type);
-    $style_form =& $form['displays'][$type]['options']['style'];
-    // Some style plugins don't support row plugins so stop here if that's the
-    // case.
-    if (!isset($style_form['row_plugin']['#default_value'])) {
-      return;
-    }
-    $row_plugin = $style_form['row_plugin']['#default_value'];
-    switch ($row_plugin) {
-      case 'full_posts':
-      case 'teasers':
-        $style_form['row_options']['links'] = array(
-          '#type' => 'select',
-          '#title_display' => 'invisible',
-          '#title' => t('Should links be displayed below each node'),
-          '#options' => array(
-            1 => t('with links (allow users to add comments, etc.)'),
-            0 => t('without links'),
-          ),
-          '#default_value' => 1,
-        );
-        $style_form['row_options']['comments'] = array(
-          '#type' => 'select',
-          '#title_display' => 'invisible',
-          '#title' => t('Should comments be displayed below each node'),
-          '#options' => array(
-            1 => t('with comments'),
-            0 => t('without comments'),
-          ),
-          '#default_value' => 0,
-        );
-        break;
-    }
-  }
-
-  /**
-   * @override
-   */
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    // Add the title field, so that the display has content if the user switches
-    // to a row style that uses fields.
-    /* Field: Content: Title */
-    $display_options['fields']['title']['id'] = 'title';
-    $display_options['fields']['title']['table'] = 'node';
-    $display_options['fields']['title']['field'] = 'title';
-    $display_options['fields']['title']['label'] = '';
-    $display_options['fields']['title']['alter']['alter_text'] = 0;
-    $display_options['fields']['title']['alter']['make_link'] = 0;
-    $display_options['fields']['title']['alter']['absolute'] = 0;
-    $display_options['fields']['title']['alter']['trim'] = 0;
-    $display_options['fields']['title']['alter']['word_boundary'] = 0;
-    $display_options['fields']['title']['alter']['ellipsis'] = 0;
-    $display_options['fields']['title']['alter']['strip_tags'] = 0;
-    $display_options['fields']['title']['alter']['html'] = 0;
-    $display_options['fields']['title']['hide_empty'] = 0;
-    $display_options['fields']['title']['empty_zero'] = 0;
-    $display_options['fields']['title']['link_to_node'] = 1;
-
-    return $display_options;
-  }
-
-  protected function page_display_options($form, $form_state) {
-    $display_options = parent::page_display_options($form, $form_state);
-    $row_plugin = isset($form_state['values']['page']['style']['row_plugin']) ? $form_state['values']['page']['style']['row_plugin'] : NULL;
-    $row_options = isset($form_state['values']['page']['style']['row_options']) ? $form_state['values']['page']['style']['row_options'] : array();
-    $this->display_options_row($display_options, $row_plugin, $row_options);
-    return $display_options;
-  }
-
-  protected function block_display_options($form, $form_state) {
-    $display_options = parent::block_display_options($form, $form_state);
-    $row_plugin = isset($form_state['values']['block']['style']['row_plugin']) ? $form_state['values']['block']['style']['row_plugin'] : NULL;
-    $row_options = isset($form_state['values']['block']['style']['row_options']) ? $form_state['values']['block']['style']['row_options'] : array();
-    $this->display_options_row($display_options, $row_plugin, $row_options);
-    return $display_options;
-  }
-
-  /**
-   * Set the row style and row style plugins to the display_options.
-   */
-  protected  function display_options_row(&$display_options, $row_plugin, $row_options) {
-    switch ($row_plugin) {
-      case 'full_posts':
-        $display_options['row_plugin'] = 'node';
-        $display_options['row_options']['build_mode'] = 'full';
-        $display_options['row_options']['links'] = !empty($row_options['links']);
-        $display_options['row_options']['comments'] = !empty($row_options['comments']);
-        break;
-      case 'teasers':
-        $display_options['row_plugin'] = 'node';
-        $display_options['row_options']['build_mode'] = 'teaser';
-        $display_options['row_options']['links'] = !empty($row_options['links']);
-        $display_options['row_options']['comments'] = !empty($row_options['comments']);
-        break;
-      case 'titles_linked':
-        $display_options['row_plugin'] = 'fields';
-        $display_options['field']['title']['link_to_node'] = 1;
-        break;
-      case 'titles':
-        $display_options['row_plugin'] = 'fields';
-        $display_options['field']['title']['link_to_node'] = 0;
-        break;
-    }
-  }
-}
diff --git a/plugins/views_wizard/views_ui_taxonomy_term_views_wizard.class.php b/plugins/views_wizard/views_ui_taxonomy_term_views_wizard.class.php
deleted file mode 100644
index 4f05548..0000000
--- a/plugins/views_wizard/views_ui_taxonomy_term_views_wizard.class.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiTaxonomyTermViewsWizard.
- */
-
-/**
- * Tests creating taxonomy views with the wizard.
- */
-class ViewsUiTaxonomyTermViewsWizard extends ViewsUiBaseViewsWizard {
-
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: Taxonomy: Term */
-    $display_options['fields']['name']['id'] = 'name';
-    $display_options['fields']['name']['table'] = 'taxonomy_term_data';
-    $display_options['fields']['name']['field'] = 'name';
-    $display_options['fields']['name']['label'] = '';
-    $display_options['fields']['name']['alter']['alter_text'] = 0;
-    $display_options['fields']['name']['alter']['make_link'] = 0;
-    $display_options['fields']['name']['alter']['absolute'] = 0;
-    $display_options['fields']['name']['alter']['trim'] = 0;
-    $display_options['fields']['name']['alter']['word_boundary'] = 0;
-    $display_options['fields']['name']['alter']['ellipsis'] = 0;
-    $display_options['fields']['name']['alter']['strip_tags'] = 0;
-    $display_options['fields']['name']['alter']['html'] = 0;
-    $display_options['fields']['name']['hide_empty'] = 0;
-    $display_options['fields']['name']['empty_zero'] = 0;
-    $display_options['fields']['name']['link_to_taxonomy'] = 1;
-
-    return $display_options;
-  }
-}
diff --git a/plugins/views_wizard/views_ui_users_views_wizard.class.php b/plugins/views_wizard/views_ui_users_views_wizard.class.php
deleted file mode 100644
index 73eff48..0000000
--- a/plugins/views_wizard/views_ui_users_views_wizard.class.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of ViewsUiUsersViewsWizard.
- */
-
-/**
- * Tests creating user views with the wizard.
- */
-class ViewsUiUsersViewsWizard extends ViewsUiBaseViewsWizard {
-  protected function default_display_options($form, $form_state) {
-    $display_options = parent::default_display_options($form, $form_state);
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-    $display_options['access']['perm'] = 'access user profiles';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: User: Name */
-    $display_options['fields']['name']['id'] = 'name';
-    $display_options['fields']['name']['table'] = 'users';
-    $display_options['fields']['name']['field'] = 'name';
-    $display_options['fields']['name']['label'] = '';
-    $display_options['fields']['name']['alter']['alter_text'] = 0;
-    $display_options['fields']['name']['alter']['make_link'] = 0;
-    $display_options['fields']['name']['alter']['absolute'] = 0;
-    $display_options['fields']['name']['alter']['trim'] = 0;
-    $display_options['fields']['name']['alter']['word_boundary'] = 0;
-    $display_options['fields']['name']['alter']['ellipsis'] = 0;
-    $display_options['fields']['name']['alter']['strip_tags'] = 0;
-    $display_options['fields']['name']['alter']['html'] = 0;
-    $display_options['fields']['name']['hide_empty'] = 0;
-    $display_options['fields']['name']['empty_zero'] = 0;
-    $display_options['fields']['name']['link_to_user'] = 1;
-    $display_options['fields']['name']['overwrite_anonymous'] = 0;
-
-    return $display_options;
-  }
-}
diff --git a/views.info b/views.info
index 7e18bda..2283c90 100644
--- a/views.info
+++ b/views.info
@@ -55,9 +55,6 @@ files[] = handlers/views_handler_sort_formula.inc
 files[] = handlers/views_handler_sort_group_by_numeric.inc
 files[] = handlers/views_handler_sort_menu_hierarchy.inc
 files[] = handlers/views_handler_sort_random.inc
-; Includes
-files[] = includes/handlers.inc
-files[] = includes/plugins.inc
 ; Modules
 files[] = modules/aggregator/views_handler_argument_aggregator_fid.inc
 files[] = modules/aggregator/views_handler_argument_aggregator_iid.inc
@@ -191,55 +188,6 @@ files[] = modules/user/views_plugin_argument_default_current_user.inc
 files[] = modules/user/views_plugin_argument_default_user.inc
 files[] = modules/user/views_plugin_argument_validate_user.inc
 files[] = modules/user/views_plugin_row_user_view.inc
-; Plugins
-files[] = plugins/views_plugin_access.inc
-files[] = plugins/views_plugin_access_none.inc
-files[] = plugins/views_plugin_access_perm.inc
-files[] = plugins/views_plugin_access_role.inc
-files[] = plugins/views_plugin_argument_default.inc
-files[] = plugins/views_plugin_argument_default_php.inc
-files[] = plugins/views_plugin_argument_default_fixed.inc
-files[] = plugins/views_plugin_argument_default_raw.inc
-files[] = plugins/views_plugin_argument_validate.inc
-files[] = plugins/views_plugin_argument_validate_numeric.inc
-files[] = plugins/views_plugin_argument_validate_php.inc
-files[] = plugins/views_plugin_cache.inc
-files[] = plugins/views_plugin_cache_none.inc
-files[] = plugins/views_plugin_cache_time.inc
-files[] = plugins/views_plugin_display.inc
-files[] = plugins/views_plugin_display_attachment.inc
-files[] = plugins/views_plugin_display_block.inc
-files[] = plugins/views_plugin_display_default.inc
-files[] = plugins/views_plugin_display_embed.inc
-files[] = plugins/views_plugin_display_extender.inc
-files[] = plugins/views_plugin_display_feed.inc
-files[] = plugins/views_plugin_display_page.inc
-files[] = plugins/views_plugin_exposed_form_basic.inc
-files[] = plugins/views_plugin_exposed_form.inc
-files[] = plugins/views_plugin_exposed_form_input_required.inc
-files[] = plugins/views_plugin_localization_core.inc
-files[] = plugins/views_plugin_localization.inc
-files[] = plugins/views_plugin_localization_none.inc
-files[] = plugins/views_plugin_pager.inc
-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
-files[] = plugins/views_plugin_style.inc
-files[] = plugins/views_plugin_style_default.inc
-files[] = plugins/views_plugin_style_grid.inc
-files[] = plugins/views_plugin_style_list.inc
-files[] = plugins/views_plugin_style_jump_menu.inc
-files[] = plugins/views_plugin_style_rss.inc
-files[] = plugins/views_plugin_style_summary.inc
-files[] = plugins/views_plugin_style_summary_jump_menu.inc
-files[] = plugins/views_plugin_style_summary_unformatted.inc
-files[] = plugins/views_plugin_style_table.inc
 
 ; Tests
 files[] = tests/test_plugins/views_test_plugin_access_test_dynamic.inc
diff --git a/views_ui.module b/views_ui.module
index b3864bd..cbb206a 100644
--- a/views_ui.module
+++ b/views_ui.module
@@ -640,10 +640,12 @@ function views_ui_views_plugins_alter(&$plugins) {
   // paths underneath "admin/structure/views/view/{$view->name}" (i.e., paths
   // for editing and performing other contextual actions on the view).
   foreach ($plugins['display'] as &$display) {
+/*
     $display['contextual links']['views_ui'] = array(
       'parent path' => 'admin/structure/views/view',
       'argument properties' => array('name'),
     );
+*/
   }
 }
 
