diff --git a/core/assets/vendor/backbone/backbone.js b/core/assets/vendor/backbone/backbone.js
index 3fec403..418fc7d 100644
--- a/core/assets/vendor/backbone/backbone.js
+++ b/core/assets/vendor/backbone/backbone.js
@@ -1,7 +1,6 @@
-//     Backbone.js 1.1.0
+//     Backbone.js 0.9.2
 
-//     (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
-//     (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
 //     Backbone may be freely distributed under the MIT license.
 //     For all details and documentation:
 //     http://backbonejs.org
@@ -11,7 +10,7 @@
   // Initial Setup
   // -------------
 
-  // Save a reference to the global object (`window` in the browser, `exports`
+  // Save a reference to the global object (`window` in the browser, `global`
   // on the server).
   var root = this;
 
@@ -19,14 +18,14 @@
   // restored later on, if `noConflict` is used.
   var previousBackbone = root.Backbone;
 
-  // Create local references to array methods we'll want to use later.
-  var array = [];
-  var push = array.push;
-  var slice = array.slice;
-  var splice = array.splice;
+  // Create a local reference to array methods.
+  var ArrayProto = Array.prototype;
+  var push = ArrayProto.push;
+  var slice = ArrayProto.slice;
+  var splice = ArrayProto.splice;
 
   // The top-level namespace. All public Backbone classes and modules will
-  // be attached to this. Exported for both the browser and the server.
+  // be attached to this. Exported for both CommonJS and the browser.
   var Backbone;
   if (typeof exports !== 'undefined') {
     Backbone = exports;
@@ -35,15 +34,14 @@
   }
 
   // Current version of the library. Keep in sync with `package.json`.
-  Backbone.VERSION = '1.1.0';
+  Backbone.VERSION = '0.9.2';
 
   // Require Underscore, if we're on the server, and it's not already present.
   var _ = root._;
   if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
 
-  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
-  // the `$` variable.
-  Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
+  // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
+  Backbone.$ = root.jQuery || root.Zepto || root.ender;
 
   // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
   // to its previous owner. Returns a reference to this Backbone object.
@@ -53,7 +51,7 @@
   };
 
   // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
-  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+  // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
   // set a `X-Http-Method-Override` header.
   Backbone.emulateHTTP = false;
 
@@ -64,12 +62,14 @@
   Backbone.emulateJSON = false;
 
   // Backbone.Events
-  // ---------------
+  // -----------------
+
+  // Regular expression used to split event strings
+  var eventSplitter = /\s+/;
 
   // A module that can be mixed in to *any object* in order to provide it with
-  // custom events. You may bind with `on` or remove with `off` callback
-  // functions to an event; `trigger`-ing an event fires all callbacks in
-  // succession.
+  // custom events. You may bind with `on` or remove with `off` callback functions
+  // to an event; `trigger`-ing an event fires all callbacks in succession.
   //
   //     var object = {};
   //     _.extend(object, Backbone.Events);
@@ -78,55 +78,49 @@
   //
   var Events = Backbone.Events = {
 
-    // Bind an event to a `callback` function. Passing `"all"` will bind
-    // the callback to all events fired.
-    on: function(name, callback, context) {
-      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
-      this._events || (this._events = {});
-      var events = this._events[name] || (this._events[name] = []);
-      events.push({callback: callback, context: context, ctx: context || this});
+    // Bind one or more space separated events, `events`, to a `callback`
+    // function. Passing `"all"` will bind the callback to all events fired.
+    on: function(events, callback, context) {
+      var calls, event, list;
+      if (!callback) return this;
+
+      events = events.split(eventSplitter);
+      calls = this._callbacks || (this._callbacks = {});
+
+      while (event = events.shift()) {
+        list = calls[event] || (calls[event] = []);
+        list.push(callback, context);
+      }
+
       return this;
     },
 
-    // Bind an event to only be triggered a single time. After the first time
-    // the callback is invoked, it will be removed.
-    once: function(name, callback, context) {
-      if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
-      var self = this;
-      var once = _.once(function() {
-        self.off(name, once);
-        callback.apply(this, arguments);
-      });
-      once._callback = callback;
-      return this.on(name, once, context);
-    },
-
-    // Remove one or many callbacks. If `context` is null, removes all
-    // callbacks with that function. If `callback` is null, removes all
-    // callbacks for the event. If `name` is null, removes all bound
-    // callbacks for all events.
-    off: function(name, callback, context) {
-      var retain, ev, events, names, i, l, j, k;
-      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
-      if (!name && !callback && !context) {
-        this._events = {};
+    // Remove one or many callbacks. If `context` is null, removes all callbacks
+    // with that function. If `callback` is null, removes all callbacks for the
+    // event. If `events` is null, removes all bound callbacks for all events.
+    off: function(events, callback, context) {
+      var event, calls, list, i;
+
+      // No events, or removing *all* events.
+      if (!(calls = this._callbacks)) return this;
+      if (!(events || callback || context)) {
+        delete this._callbacks;
         return this;
       }
-      names = name ? [name] : _.keys(this._events);
-      for (i = 0, l = names.length; i < l; i++) {
-        name = names[i];
-        if (events = this._events[name]) {
-          this._events[name] = retain = [];
-          if (callback || context) {
-            for (j = 0, k = events.length; j < k; j++) {
-              ev = events[j];
-              if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
-                  (context && context !== ev.context)) {
-                retain.push(ev);
-              }
-            }
+
+      events = events ? events.split(eventSplitter) : _.keys(calls);
+
+      // Loop through the callback list, splicing where appropriate.
+      while (event = events.shift()) {
+        if (!(list = calls[event]) || !(callback || context)) {
+          delete calls[event];
+          continue;
+        }
+
+        for (i = list.length - 2; i >= 0; i -= 2) {
+          if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
+            list.splice(i, 2);
           }
-          if (!retain.length) delete this._events[name];
         }
       }
 
@@ -137,122 +131,76 @@
     // passed the same arguments as `trigger` is, apart from the event name
     // (unless you're listening on `"all"`, which will cause your callback to
     // receive the true name of the event as the first argument).
-    trigger: function(name) {
-      if (!this._events) return this;
-      var args = slice.call(arguments, 1);
-      if (!eventsApi(this, 'trigger', name, args)) return this;
-      var events = this._events[name];
-      var allEvents = this._events.all;
-      if (events) triggerEvents(events, args);
-      if (allEvents) triggerEvents(allEvents, arguments);
-      return this;
-    },
-
-    // Tell this object to stop listening to either specific events ... or
-    // to every object it's currently listening to.
-    stopListening: function(obj, name, callback) {
-      var listeningTo = this._listeningTo;
-      if (!listeningTo) return this;
-      var remove = !name && !callback;
-      if (!callback && typeof name === 'object') callback = this;
-      if (obj) (listeningTo = {})[obj._listenId] = obj;
-      for (var id in listeningTo) {
-        obj = listeningTo[id];
-        obj.off(name, callback, this);
-        if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
-      }
-      return this;
-    }
+    trigger: function(events) {
+      var event, calls, list, i, length, args, all, rest;
+      if (!(calls = this._callbacks)) return this;
 
-  };
+      rest = [];
+      events = events.split(eventSplitter);
 
-  // Regular expression used to split event strings.
-  var eventSplitter = /\s+/;
+      // Fill up `rest` with the callback arguments.  Since we're only copying
+      // the tail of `arguments`, a loop is much faster than Array#slice.
+      for (i = 1, length = arguments.length; i < length; i++) {
+        rest[i - 1] = arguments[i];
+      }
 
-  // Implement fancy features of the Events API such as multiple event
-  // names `"change blur"` and jQuery-style event maps `{change: action}`
-  // in terms of the existing API.
-  var eventsApi = function(obj, action, name, rest) {
-    if (!name) return true;
+      // For each event, walk through the list of callbacks twice, first to
+      // trigger the event, then to trigger any `"all"` callbacks.
+      while (event = events.shift()) {
+        // Copy callback lists to prevent modification.
+        if (all = calls.all) all = all.slice();
+        if (list = calls[event]) list = list.slice();
+
+        // Execute event callbacks.
+        if (list) {
+          for (i = 0, length = list.length; i < length; i += 2) {
+            list[i].apply(list[i + 1] || this, rest);
+          }
+        }
 
-    // Handle event maps.
-    if (typeof name === 'object') {
-      for (var key in name) {
-        obj[action].apply(obj, [key, name[key]].concat(rest));
+        // Execute "all" callbacks.
+        if (all) {
+          args = [event].concat(rest);
+          for (i = 0, length = all.length; i < length; i += 2) {
+            all[i].apply(all[i + 1] || this, args);
+          }
+        }
       }
-      return false;
-    }
 
-    // Handle space separated event names.
-    if (eventSplitter.test(name)) {
-      var names = name.split(eventSplitter);
-      for (var i = 0, l = names.length; i < l; i++) {
-        obj[action].apply(obj, [names[i]].concat(rest));
-      }
-      return false;
+      return this;
     }
 
-    return true;
-  };
-
-  // A difficult-to-believe, but optimized internal dispatch function for
-  // triggering events. Tries to keep the usual cases speedy (most internal
-  // Backbone events have 3 arguments).
-  var triggerEvents = function(events, args) {
-    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
-    switch (args.length) {
-      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
-      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
-      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
-      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
-      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
-    }
   };
 
-  var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
-
-  // Inversion-of-control versions of `on` and `once`. Tell *this* object to
-  // listen to an event in another object ... keeping track of what it's
-  // listening to.
-  _.each(listenMethods, function(implementation, method) {
-    Events[method] = function(obj, name, callback) {
-      var listeningTo = this._listeningTo || (this._listeningTo = {});
-      var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
-      listeningTo[id] = obj;
-      if (!callback && typeof name === 'object') callback = this;
-      obj[implementation](name, callback, this);
-      return this;
-    };
-  });
-
   // Aliases for backwards compatibility.
   Events.bind   = Events.on;
   Events.unbind = Events.off;
 
-  // Allow the `Backbone` object to serve as a global event bus, for folks who
-  // want global "pubsub" in a convenient place.
-  _.extend(Backbone, Events);
-
   // Backbone.Model
   // --------------
 
-  // Backbone **Models** are the basic data object in the framework --
-  // frequently representing a row in a table in a database on your server.
-  // A discrete chunk of data and a bunch of useful, related methods for
-  // performing computations and transformations on that data.
-
-  // Create a new model with the specified attributes. A client id (`cid`)
+  // Create a new model, with defined attributes. A client id (`cid`)
   // is automatically generated and assigned for you.
   var Model = Backbone.Model = function(attributes, options) {
-    var attrs = attributes || {};
-    options || (options = {});
-    this.cid = _.uniqueId('c');
+    var defaults;
+    attributes || (attributes = {});
+    if (options && options.collection) this.collection = options.collection;
+    if (options && options.parse) attributes = this.parse(attributes);
+    if (defaults = _.result(this, 'defaults')) {
+      attributes = _.extend({}, defaults, attributes);
+    }
     this.attributes = {};
-    if (options.collection) this.collection = options.collection;
-    if (options.parse) attrs = this.parse(attrs, options) || {};
-    attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
-    this.set(attrs, options);
+    this._escapedAttributes = {};
+    this.cid = _.uniqueId('c');
+    this.changed = {};
+    this._silent = {};
+    this._pending = {};
+    this.set(attributes, {silent: true});
+    // Reset change tracking.
     this.changed = {};
+    this._silent = {};
+    this._pending = {};
+    this._previousAttributes = _.clone(this.attributes);
     this.initialize.apply(this, arguments);
   };
 
@@ -262,8 +210,13 @@
     // A hash of attributes whose current and previous value differ.
     changed: null,
 
-    // The value returned during the last failed validation.
-    validationError: null,
+    // A hash of attributes that have silently changed since the last time
+    // `change` was called.  Will become pending attributes on the next call.
+    _silent: null,
+
+    // A hash of attributes that have changed since the last `'change'` event
+    // began.
+    _pending: null,
 
     // The default name for the JSON `id` attribute is `"id"`. MongoDB and
     // CouchDB users may want to set this to `"_id"`.
@@ -278,8 +231,7 @@
       return _.clone(this.attributes);
     },
 
-    // Proxy `Backbone.sync` by default -- but override this if you need
-    // custom syncing semantics for *this* particular model.
+    // Proxy `Backbone.sync` by default.
     sync: function() {
       return Backbone.sync.apply(this, arguments);
     },
@@ -291,7 +243,10 @@
 
     // Get the HTML-escaped value of an attribute.
     escape: function(attr) {
-      return _.escape(this.get(attr));
+      var html;
+      if (html = this._escapedAttributes[attr]) return html;
+      var val = this.get(attr);
+      return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val);
     },
 
     // Returns `true` if the attribute contains a value that is not null
@@ -300,197 +255,146 @@
       return this.get(attr) != null;
     },
 
-    // Set a hash of model attributes on the object, firing `"change"`. This is
-    // the core primitive operation of a model, updating the data and notifying
-    // anyone who needs to know about the change in state. The heart of the beast.
-    set: function(key, val, options) {
-      var attr, attrs, unset, changes, silent, changing, prev, current;
-      if (key == null) return this;
+    // Set a hash of model attributes on the object, firing `"change"` unless
+    // you choose to silence it.
+    set: function(key, value, options) {
+      var attrs, attr, val;
 
       // Handle both `"key", value` and `{key: value}` -style arguments.
-      if (typeof key === 'object') {
+      if (_.isObject(key) || key == null) {
         attrs = key;
-        options = val;
+        options = value;
       } else {
-        (attrs = {})[key] = val;
+        attrs = {};
+        attrs[key] = value;
       }
 
+      // Extract attributes and options.
       options || (options = {});
+      if (!attrs) return this;
+      if (attrs instanceof Model) attrs = attrs.attributes;
+      if (options.unset) for (attr in attrs) attrs[attr] = void 0;
 
       // Run validation.
       if (!this._validate(attrs, options)) return false;
 
-      // Extract attributes and options.
-      unset           = options.unset;
-      silent          = options.silent;
-      changes         = [];
-      changing        = this._changing;
-      this._changing  = true;
-
-      if (!changing) {
-        this._previousAttributes = _.clone(this.attributes);
-        this.changed = {};
-      }
-      current = this.attributes, prev = this._previousAttributes;
-
       // Check for changes of `id`.
       if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
 
-      // For each `set` attribute, update or delete the current value.
+      var changes = options.changes = {};
+      var now = this.attributes;
+      var escaped = this._escapedAttributes;
+      var prev = this._previousAttributes || {};
+
+      // For each `set` attribute...
       for (attr in attrs) {
         val = attrs[attr];
-        if (!_.isEqual(current[attr], val)) changes.push(attr);
-        if (!_.isEqual(prev[attr], val)) {
+
+        // If the new and current value differ, record the change.
+        if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
+          delete escaped[attr];
+          (options.silent ? this._silent : changes)[attr] = true;
+        }
+
+        // Update or delete the current value.
+        options.unset ? delete now[attr] : now[attr] = val;
+
+        // If the new and previous value differ, record the change.  If not,
+        // then remove changes for this attribute.
+        if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
           this.changed[attr] = val;
+          if (!options.silent) this._pending[attr] = true;
         } else {
           delete this.changed[attr];
-        }
-        unset ? delete current[attr] : current[attr] = val;
-      }
-
-      // Trigger all relevant attribute changes.
-      if (!silent) {
-        if (changes.length) this._pending = true;
-        for (var i = 0, l = changes.length; i < l; i++) {
-          this.trigger('change:' + changes[i], this, current[changes[i]], options);
+          delete this._pending[attr];
         }
       }
 
-      // You might be wondering why there's a `while` loop here. Changes can
-      // be recursively nested within `"change"` events.
-      if (changing) return this;
-      if (!silent) {
-        while (this._pending) {
-          this._pending = false;
-          this.trigger('change', this, options);
-        }
-      }
-      this._pending = false;
-      this._changing = false;
+      // Fire the `"change"` events.
+      if (!options.silent) this.change(options);
       return this;
     },
 
-    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
-    // if the attribute doesn't exist.
+    // Remove an attribute from the model, firing `"change"` unless you choose
+    // to silence it. `unset` is a noop if the attribute doesn't exist.
     unset: function(attr, options) {
-      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+      options = _.extend({}, options, {unset: true});
+      return this.set(attr, null, options);
     },
 
-    // Clear all attributes on the model, firing `"change"`.
+    // Clear all attributes on the model, firing `"change"` unless you choose
+    // to silence it.
     clear: function(options) {
-      var attrs = {};
-      for (var key in this.attributes) attrs[key] = void 0;
-      return this.set(attrs, _.extend({}, options, {unset: true}));
-    },
-
-    // Determine if the model has changed since the last `"change"` event.
-    // If you specify an attribute name, determine if that attribute has changed.
-    hasChanged: function(attr) {
-      if (attr == null) return !_.isEmpty(this.changed);
-      return _.has(this.changed, attr);
-    },
-
-    // Return an object containing all the attributes that have changed, or
-    // false if there are no changed attributes. Useful for determining what
-    // parts of a view need to be updated and/or what attributes need to be
-    // persisted to the server. Unset attributes will be set to undefined.
-    // You can also pass an attributes object to diff against the model,
-    // determining if there *would be* a change.
-    changedAttributes: function(diff) {
-      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
-      var val, changed = false;
-      var old = this._changing ? this._previousAttributes : this.attributes;
-      for (var attr in diff) {
-        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
-        (changed || (changed = {}))[attr] = val;
-      }
-      return changed;
-    },
-
-    // Get the previous value of an attribute, recorded at the time the last
-    // `"change"` event was fired.
-    previous: function(attr) {
-      if (attr == null || !this._previousAttributes) return null;
-      return this._previousAttributes[attr];
-    },
-
-    // Get all of the attributes of the model at the time of the previous
-    // `"change"` event.
-    previousAttributes: function() {
-      return _.clone(this._previousAttributes);
+      options = _.extend({}, options, {unset: true});
+      return this.set(_.clone(this.attributes), options);
     },
 
     // Fetch the model from the server. If the server's representation of the
-    // model differs from its current attributes, they will be overridden,
+    // model differs from its current attributes, they will be overriden,
     // triggering a `"change"` event.
     fetch: function(options) {
       options = options ? _.clone(options) : {};
-      if (options.parse === void 0) options.parse = true;
       var model = this;
       var success = options.success;
-      options.success = function(resp) {
-        if (!model.set(model.parse(resp, options), options)) return false;
+      options.success = function(resp, status, xhr) {
+        if (!model.set(model.parse(resp, xhr), options)) return false;
         if (success) success(model, resp, options);
-        model.trigger('sync', model, resp, options);
       };
-      wrapError(this, options);
       return this.sync('read', this, options);
     },
 
     // Set a hash of model attributes, and sync the model to the server.
     // If the server returns an attributes hash that differs, the model's
     // state will be `set` again.
-    save: function(key, val, options) {
-      var attrs, method, xhr, attributes = this.attributes;
+    save: function(key, value, options) {
+      var attrs, current, done;
 
-      // Handle both `"key", value` and `{key: value}` -style arguments.
-      if (key == null || typeof key === 'object') {
+      // Handle both `("key", value)` and `({key: value})` -style calls.
+      if (_.isObject(key) || key == null) {
         attrs = key;
-        options = val;
+        options = value;
       } else {
-        (attrs = {})[key] = val;
+        attrs = {};
+        attrs[key] = value;
       }
+      options = options ? _.clone(options) : {};
 
-      options = _.extend({validate: true}, options);
-
-      // If we're not waiting and attributes exist, save acts as
-      // `set(attr).save(null, opts)` with validation. Otherwise, check if
-      // the model will be valid when the attributes, if any, are set.
-      if (attrs && !options.wait) {
-        if (!this.set(attrs, options)) return false;
-      } else {
+      // If we're "wait"-ing to set changed attributes, validate early.
+      if (options.wait) {
         if (!this._validate(attrs, options)) return false;
+        current = _.clone(this.attributes);
       }
 
-      // Set temporary attributes if `{wait: true}`.
-      if (attrs && options.wait) {
-        this.attributes = _.extend({}, attributes, attrs);
+      // Regular saves `set` attributes before persisting to the server.
+      var silentOptions = _.extend({}, options, {silent: true});
+      if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
+        return false;
       }
 
+      // Do not persist invalid models.
+      if (!attrs && !this.isValid()) return false;
+
       // After a successful server-side save, the client is (optionally)
       // updated with the server-side state.
-      if (options.parse === void 0) options.parse = true;
       var model = this;
       var success = options.success;
-      options.success = function(resp) {
-        // Ensure attributes are restored during synchronous saves.
-        model.attributes = attributes;
-        var serverAttrs = model.parse(resp, options);
+      options.success = function(resp, status, xhr) {
+        done = true;
+        var serverAttrs = model.parse(resp, xhr);
         if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
-        if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
-          return false;
-        }
+        if (!model.set(serverAttrs, options)) return false;
         if (success) success(model, resp, options);
-        model.trigger('sync', model, resp, options);
       };
-      wrapError(this, options);
 
-      method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
-      if (method === 'patch') options.attrs = attrs;
-      xhr = this.sync(method, this, options);
+      // Finish configuring and sending the Ajax request.
+      var xhr = this.sync(this.isNew() ? 'create' : 'update', this, options);
 
-      // Restore attributes.
-      if (attrs && options.wait) this.attributes = attributes;
+      // When using `wait`, reset attributes to original values unless
+      // `success` has been called already.
+      if (!done && options.wait) {
+        this.clear(silentOptions);
+        this.set(current, silentOptions);
+      }
 
       return xhr;
     },
@@ -510,14 +414,12 @@
       options.success = function(resp) {
         if (options.wait || model.isNew()) destroy();
         if (success) success(model, resp, options);
-        if (!model.isNew()) model.trigger('sync', model, resp, options);
       };
 
       if (this.isNew()) {
         options.success();
         return false;
       }
-      wrapError(this, options);
 
       var xhr = this.sync('delete', this, options);
       if (!options.wait) destroy();
@@ -535,7 +437,7 @@
 
     // **parse** converts a response into the hash of attributes to be `set` on
     // the model. The default implementation is just to pass the response along.
-    parse: function(resp, options) {
+    parse: function(resp, xhr) {
       return resp;
     },
 
@@ -549,48 +451,103 @@
       return this.id == null;
     },
 
-    // Check if the model is currently in a valid state.
+    // Call this method to manually fire a `"change"` event for this model and
+    // a `"change:attribute"` event for each changed attribute.
+    // Calling this will cause all objects observing the model to update.
+    change: function(options) {
+      options || (options = {});
+      var changing = this._changing;
+      this._changing = true;
+
+      // Silent changes become pending changes.
+      for (var attr in this._silent) this._pending[attr] = true;
+
+      // Silent changes are triggered.
+      var changes = _.extend({}, options.changes, this._silent);
+      this._silent = {};
+      for (var attr in changes) {
+        this.trigger('change:' + attr, this, this.get(attr), options);
+      }
+      if (changing) return this;
+
+      // Continue firing `"change"` events while there are pending changes.
+      while (!_.isEmpty(this._pending)) {
+        this._pending = {};
+        this.trigger('change', this, options);
+        // Pending and silent changes still remain.
+        for (var attr in this.changed) {
+          if (this._pending[attr] || this._silent[attr]) continue;
+          delete this.changed[attr];
+        }
+        this._previousAttributes = _.clone(this.attributes);
+      }
+
+      this._changing = false;
+      return this;
+    },
+
+    // Determine if the model has changed since the last `"change"` event.
+    // If you specify an attribute name, determine if that attribute has changed.
+    hasChanged: function(attr) {
+      if (attr == null) return !_.isEmpty(this.changed);
+      return _.has(this.changed, attr);
+    },
+
+    // Return an object containing all the attributes that have changed, or
+    // false if there are no changed attributes. Useful for determining what
+    // parts of a view need to be updated and/or what attributes need to be
+    // persisted to the server. Unset attributes will be set to undefined.
+    // You can also pass an attributes object to diff against the model,
+    // determining if there *would be* a change.
+    changedAttributes: function(diff) {
+      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+      var val, changed = false, old = this._previousAttributes;
+      for (var attr in diff) {
+        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+        (changed || (changed = {}))[attr] = val;
+      }
+      return changed;
+    },
+
+    // Get the previous value of an attribute, recorded at the time the last
+    // `"change"` event was fired.
+    previous: function(attr) {
+      if (attr == null || !this._previousAttributes) return null;
+      return this._previousAttributes[attr];
+    },
+
+    // Get all of the attributes of the model at the time of the previous
+    // `"change"` event.
+    previousAttributes: function() {
+      return _.clone(this._previousAttributes);
+    },
+
+    // Check if the model is currently in a valid state. It's only possible to
+    // get into an *invalid* state if you're using silent changes.
     isValid: function(options) {
-      return this._validate({}, _.extend(options || {}, { validate: true }));
+      return !this.validate || !this.validate(this.attributes, options);
     },
 
     // Run validation against the next complete set of model attributes,
-    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+    // returning `true` if all is well. If a specific `error` callback has
+    // been passed, call that instead of firing the general `"error"` event.
     _validate: function(attrs, options) {
-      if (!options.validate || !this.validate) return true;
+      if (options.silent || !this.validate) return true;
       attrs = _.extend({}, this.attributes, attrs);
-      var error = this.validationError = this.validate(attrs, options) || null;
+      var error = this.validate(attrs, options);
       if (!error) return true;
-      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+      if (options && options.error) options.error(this, error, options);
+      this.trigger('error', this, error, options);
       return false;
     }
 
   });
 
-  // Underscore methods that we want to implement on the Model.
-  var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
-
-  // Mix in each Underscore method as a proxy to `Model#attributes`.
-  _.each(modelMethods, function(method) {
-    Model.prototype[method] = function() {
-      var args = slice.call(arguments);
-      args.unshift(this.attributes);
-      return _[method].apply(_, args);
-    };
-  });
-
   // Backbone.Collection
   // -------------------
 
-  // If models tend to represent a single row of data, a Backbone Collection is
-  // more analagous to a table full of data ... or a small slice or page of that
-  // table, or a collection of rows that belong together for a particular reason
-  // -- all of the messages in this particular folder, all of the documents
-  // belonging to this particular author, and so on. Collections maintain
-  // indexes of their models, both in order, and for lookup by `id`.
-
-  // Create a new **Collection**, perhaps to contain a specific type of `model`.
-  // If a `comparator` is specified, the Collection will maintain
+  // Provides a standard collection class for our sets of models, ordered
+  // or unordered. If a `comparator` is specified, the Collection will maintain
   // its models in sort order, as they're added and removed.
   var Collection = Backbone.Collection = function(models, options) {
     options || (options = {});
@@ -598,13 +555,12 @@
     if (options.comparator !== void 0) this.comparator = options.comparator;
     this._reset();
     this.initialize.apply(this, arguments);
-    if (models) this.reset(models, _.extend({silent: true}, options));
+    if (models) {
+      if (options.parse) models = this.parse(models);
+      this.reset(models, {silent: true, parse: options.parse});
+    }
   };
 
-  // Default options for `Collection#set`.
-  var setOptions = {add: true, remove: true, merge: true};
-  var addOptions = {add: true, remove: false};
-
   // Define the Collection's inheritable methods.
   _.extend(Collection.prototype, Events, {
 
@@ -627,22 +583,71 @@
       return Backbone.sync.apply(this, arguments);
     },
 
-    // Add a model, or list of models to the set.
+    // Add a model, or list of models to the set. Pass **silent** to avoid
+    // firing the `add` event for every new model.
     add: function(models, options) {
-      return this.set(models, _.extend({merge: false}, options, addOptions));
+      var i, args, length, model, existing;
+      var at = options && options.at;
+      models = _.isArray(models) ? models.slice() : [models];
+
+      // Begin by turning bare objects into model references, and preventing
+      // invalid models from being added.
+      for (i = 0, length = models.length; i < length; i++) {
+        if (models[i] = this._prepareModel(models[i], options)) continue;
+        throw new Error("Can't add an invalid model to a collection");
+      }
+
+      for (i = models.length - 1; i >= 0; i--) {
+        model = models[i];
+        existing = model.id != null && this._byId[model.id];
+
+        // If a duplicate is found, splice it out and optionally merge it into
+        // the existing model.
+        if (existing || this._byCid[model.cid]) {
+          if (options && options.merge && existing) {
+            existing.set(model, options);
+          }
+          models.splice(i, 1);
+          continue;
+        }
+
+        // Listen to added models' events, and index models for lookup by
+        // `id` and by `cid`.
+        model.on('all', this._onModelEvent, this);
+        this._byCid[model.cid] = model;
+        if (model.id != null) this._byId[model.id] = model;
+      }
+
+      // Update `length` and splice in new models.
+      this.length += models.length;
+      args = [at != null ? at : this.models.length, 0];
+      push.apply(args, models);
+      splice.apply(this.models, args);
+
+      // Sort the collection if appropriate.
+      if (this.comparator && at == null) this.sort({silent: true});
+
+      if (options && options.silent) return this;
+
+      // Trigger `add` events.
+      while (model = models.shift()) {
+        model.trigger('add', model, this, options);
+      }
+
+      return this;
     },
 
-    // Remove a model, or a list of models from the set.
+    // Remove a model, or a list of models from the set. Pass silent to avoid
+    // firing the `remove` event for every model removed.
     remove: function(models, options) {
-      var singular = !_.isArray(models);
-      models = singular ? [models] : _.clone(models);
-      options || (options = {});
       var i, l, index, model;
+      options || (options = {});
+      models = _.isArray(models) ? models.slice() : [models];
       for (i = 0, l = models.length; i < l; i++) {
-        model = models[i] = this.get(models[i]);
+        model = this.getByCid(models[i]) || this.get(models[i]);
         if (!model) continue;
         delete this._byId[model.id];
-        delete this._byId[model.cid];
+        delete this._byCid[model.cid];
         index = this.indexOf(model);
         this.models.splice(index, 1);
         this.length--;
@@ -652,123 +657,14 @@
         }
         this._removeReference(model);
       }
-      return singular ? models[0] : models;
-    },
-
-    // Update a collection by `set`-ing a new list of models, adding new ones,
-    // removing models that are no longer present, and merging models that
-    // already exist in the collection, as necessary. Similar to **Model#set**,
-    // the core operation for updating the data contained by the collection.
-    set: function(models, options) {
-      options = _.defaults({}, options, setOptions);
-      if (options.parse) models = this.parse(models, options);
-      var singular = !_.isArray(models);
-      models = singular ? (models ? [models] : []) : _.clone(models);
-      var i, l, id, model, attrs, existing, sort;
-      var at = options.at;
-      var targetModel = this.model;
-      var sortable = this.comparator && (at == null) && options.sort !== false;
-      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
-      var toAdd = [], toRemove = [], modelMap = {};
-      var add = options.add, merge = options.merge, remove = options.remove;
-      var order = !sortable && add && remove ? [] : false;
-
-      // Turn bare objects into model references, and prevent invalid models
-      // from being added.
-      for (i = 0, l = models.length; i < l; i++) {
-        attrs = models[i];
-        if (attrs instanceof Model) {
-          id = model = attrs;
-        } else {
-          id = attrs[targetModel.prototype.idAttribute];
-        }
-
-        // If a duplicate is found, prevent it from being added and
-        // optionally merge it into the existing model.
-        if (existing = this.get(id)) {
-          if (remove) modelMap[existing.cid] = true;
-          if (merge) {
-            attrs = attrs === model ? model.attributes : attrs;
-            if (options.parse) attrs = existing.parse(attrs, options);
-            existing.set(attrs, options);
-            if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
-          }
-          models[i] = existing;
-
-        // If this is a new, valid model, push it to the `toAdd` list.
-        } else if (add) {
-          model = models[i] = this._prepareModel(attrs, options);
-          if (!model) continue;
-          toAdd.push(model);
-
-          // Listen to added models' events, and index models for lookup by
-          // `id` and by `cid`.
-          model.on('all', this._onModelEvent, this);
-          this._byId[model.cid] = model;
-          if (model.id != null) this._byId[model.id] = model;
-        }
-        if (order) order.push(existing || model);
-      }
-
-      // Remove nonexistent models if appropriate.
-      if (remove) {
-        for (i = 0, l = this.length; i < l; ++i) {
-          if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
-        }
-        if (toRemove.length) this.remove(toRemove, options);
-      }
-
-      // See if sorting is needed, update `length` and splice in new models.
-      if (toAdd.length || (order && order.length)) {
-        if (sortable) sort = true;
-        this.length += toAdd.length;
-        if (at != null) {
-          for (i = 0, l = toAdd.length; i < l; i++) {
-            this.models.splice(at + i, 0, toAdd[i]);
-          }
-        } else {
-          if (order) this.models.length = 0;
-          var orderedModels = order || toAdd;
-          for (i = 0, l = orderedModels.length; i < l; i++) {
-            this.models.push(orderedModels[i]);
-          }
-        }
-      }
-
-      // Silently sort the collection if appropriate.
-      if (sort) this.sort({silent: true});
-
-      // Unless silenced, it's time to fire all appropriate add/sort events.
-      if (!options.silent) {
-        for (i = 0, l = toAdd.length; i < l; i++) {
-          (model = toAdd[i]).trigger('add', model, this, options);
-        }
-        if (sort || (order && order.length)) this.trigger('sort', this, options);
-      }
-
-      // Return the added (or merged) model (or models).
-      return singular ? models[0] : models;
-    },
-
-    // When you have more items than you want to add or remove individually,
-    // you can reset the entire set with a new list of models, without firing
-    // any granular `add` or `remove` events. Fires `reset` when finished.
-    // Useful for bulk operations and optimizations.
-    reset: function(models, options) {
-      options || (options = {});
-      for (var i = 0, l = this.models.length; i < l; i++) {
-        this._removeReference(this.models[i]);
-      }
-      options.previousModels = this.models;
-      this._reset();
-      models = this.add(models, _.extend({silent: true}, options));
-      if (!options.silent) this.trigger('reset', this, options);
-      return models;
+      return this;
     },
 
     // Add a model to the end of the collection.
     push: function(model, options) {
-      return this.add(model, _.extend({at: this.length}, options));
+      model = this._prepareModel(model, options);
+      this.add(model, options);
+      return model;
     },
 
     // Remove a model from the end of the collection.
@@ -780,7 +676,9 @@
 
     // Add a model to the beginning of the collection.
     unshift: function(model, options) {
-      return this.add(model, _.extend({at: 0}, options));
+      model = this._prepareModel(model, options);
+      this.add(model, _.extend({at: 0}, options));
+      return model;
     },
 
     // Remove a model from the beginning of the collection.
@@ -791,14 +689,19 @@
     },
 
     // Slice out a sub-array of models from the collection.
-    slice: function() {
-      return slice.apply(this.models, arguments);
+    slice: function(begin, end) {
+      return this.models.slice(begin, end);
     },
 
     // Get a model from the set by id.
-    get: function(obj) {
-      if (obj == null) return void 0;
-      return this._byId[obj.id] || this._byId[obj.cid] || this._byId[obj];
+    get: function(id) {
+      if (id == null) return void 0;
+      return this._byId[id.id != null ? id.id : id];
+    },
+
+    // Get a model from the set by client id.
+    getByCid: function(cid) {
+      return cid && this._byCid[cid.cid || cid];
     },
 
     // Get the model at the given index.
@@ -806,11 +709,10 @@
       return this.models[index];
     },
 
-    // Return models with matching attributes. Useful for simple cases of
-    // `filter`.
-    where: function(attrs, first) {
-      if (_.isEmpty(attrs)) return first ? void 0 : [];
-      return this[first ? 'find' : 'filter'](function(model) {
+    // Return models with matching attributes. Useful for simple cases of `filter`.
+    where: function(attrs) {
+      if (_.isEmpty(attrs)) return [];
+      return this.filter(function(model) {
         for (var key in attrs) {
           if (attrs[key] !== model.get(key)) return false;
         }
@@ -818,27 +720,21 @@
       });
     },
 
-    // Return the first model with matching attributes. Useful for simple cases
-    // of `find`.
-    findWhere: function(attrs) {
-      return this.where(attrs, true);
-    },
-
     // Force the collection to re-sort itself. You don't need to call this under
     // normal circumstances, as the set will maintain sort order as each item
     // is added.
     sort: function(options) {
-      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
-      options || (options = {});
+      if (!this.comparator) {
+        throw new Error('Cannot sort a set without a comparator');
+      }
 
-      // Run sort based on type of `comparator`.
       if (_.isString(this.comparator) || this.comparator.length === 1) {
         this.models = this.sortBy(this.comparator, this);
       } else {
         this.models.sort(_.bind(this.comparator, this));
       }
 
-      if (!options.silent) this.trigger('sort', this, options);
+      if (!options || !options.silent) this.trigger('reset', this, options);
       return this;
     },
 
@@ -847,21 +743,31 @@
       return _.invoke(this.models, 'get', attr);
     },
 
+    // When you have more items than you want to add or remove individually,
+    // you can reset the entire set with a new list of models, without firing
+    // any `add` or `remove` events. Fires `reset` when finished.
+    reset: function(models, options) {
+      for (var i = 0, l = this.models.length; i < l; i++) {
+        this._removeReference(this.models[i]);
+      }
+      this._reset();
+      if (models) this.add(models, _.extend({silent: true}, options));
+      if (!options || !options.silent) this.trigger('reset', this, options);
+      return this;
+    },
+
     // Fetch the default set of models for this collection, resetting the
-    // collection when they arrive. If `reset: true` is passed, the response
-    // data will be passed through the `reset` method instead of `set`.
+    // collection when they arrive. If `add: true` is passed, appends the
+    // models to the collection instead of resetting.
     fetch: function(options) {
       options = options ? _.clone(options) : {};
       if (options.parse === void 0) options.parse = true;
-      var success = options.success;
       var collection = this;
-      options.success = function(resp) {
-        var method = options.reset ? 'reset' : 'set';
-        collection[method](resp, options);
+      var success = options.success;
+      options.success = function(resp, status, xhr) {
+        collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
         if (success) success(collection, resp, options);
-        collection.trigger('sync', collection, resp, options);
       };
-      wrapError(this, options);
       return this.sync('read', this, options);
     },
 
@@ -869,10 +775,11 @@
     // collection immediately, unless `wait: true` is passed, in which case we
     // wait for the server to agree.
     create: function(model, options) {
-      options = options ? _.clone(options) : {};
-      if (!(model = this._prepareModel(model, options))) return false;
-      if (!options.wait) this.add(model, options);
       var collection = this;
+      options = options ? _.clone(options) : {};
+      model = this._prepareModel(model, options);
+      if (!model) return false;
+      if (!options.wait) collection.add(model, options);
       var success = options.success;
       options.success = function(model, resp, options) {
         if (options.wait) collection.add(model, options);
@@ -884,7 +791,7 @@
 
     // **parse** converts a response into a list of models to be added to the
     // collection. The default implementation is just to pass it through.
-    parse: function(resp, options) {
+    parse: function(resp, xhr) {
       return resp;
     },
 
@@ -893,30 +800,35 @@
       return new this.constructor(this.models);
     },
 
-    // Private method to reset all internal state. Called when the collection
-    // is first initialized or reset.
-    _reset: function() {
+    // Proxy to _'s chain. Can't be proxied the same way the rest of the
+    // underscore methods are proxied because it relies on the underscore
+    // constructor.
+    chain: function() {
+      return _(this.models).chain();
+    },
+
+    // Reset all internal state. Called when the collection is reset.
+    _reset: function(options) {
       this.length = 0;
       this.models = [];
       this._byId  = {};
+      this._byCid = {};
     },
 
-    // Prepare a hash of attributes (or other model) to be added to this
-    // collection.
+    // Prepare a model or hash of attributes to be added to this collection.
     _prepareModel: function(attrs, options) {
       if (attrs instanceof Model) {
         if (!attrs.collection) attrs.collection = this;
         return attrs;
       }
-      options = options ? _.clone(options) : {};
+      options || (options = {});
       options.collection = this;
       var model = new this.model(attrs, options);
-      if (!model.validationError) return model;
-      this.trigger('invalid', this, model.validationError, options);
-      return false;
+      if (!model._validate(model.attributes, options)) return false;
+      return model;
     },
 
-    // Internal method to sever a model's ties to a collection.
+    // Internal method to remove a model's ties to a collection.
     _removeReference: function(model) {
       if (this === model.collection) delete model.collection;
       model.off('all', this._onModelEvent, this);
@@ -939,14 +851,12 @@
   });
 
   // Underscore methods that we want to implement on the Collection.
-  // 90% of the core usefulness of Backbone Collections is actually implemented
-  // right here:
   var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
     'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
     'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
-    'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
-    'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
-    'lastIndexOf', 'isEmpty', 'chain'];
+    'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take',
+    'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle',
+    'lastIndexOf', 'isEmpty'];
 
   // Mix in each Underscore method as a proxy to `Collection#models`.
   _.each(methods, function(method) {
@@ -970,235 +880,8 @@
     };
   });
 
-  // Backbone.View
-  // -------------
-
-  // Backbone Views are almost more convention than they are actual code. A View
-  // is simply a JavaScript object that represents a logical chunk of UI in the
-  // DOM. This might be a single item, an entire list, a sidebar or panel, or
-  // even the surrounding frame which wraps your whole app. Defining a chunk of
-  // UI as a **View** allows you to define your DOM events declaratively, without
-  // having to worry about render order ... and makes it easy for the view to
-  // react to specific changes in the state of your models.
-
-  // Creating a Backbone.View creates its initial element outside of the DOM,
-  // if an existing element is not provided...
-  var View = Backbone.View = function(options) {
-    this.cid = _.uniqueId('view');
-    options || (options = {});
-    _.extend(this, _.pick(options, viewOptions));
-    this._ensureElement();
-    this.initialize.apply(this, arguments);
-    this.delegateEvents();
-  };
-
-  // Cached regex to split keys for `delegate`.
-  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
-
-  // List of view options to be merged as properties.
-  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
-
-  // Set up all inheritable **Backbone.View** properties and methods.
-  _.extend(View.prototype, Events, {
-
-    // The default `tagName` of a View's element is `"div"`.
-    tagName: 'div',
-
-    // jQuery delegate for element lookup, scoped to DOM elements within the
-    // current view. This should be preferred to global lookups where possible.
-    $: function(selector) {
-      return this.$el.find(selector);
-    },
-
-    // Initialize is an empty function by default. Override it with your own
-    // initialization logic.
-    initialize: function(){},
-
-    // **render** is the core function that your view should override, in order
-    // to populate its element (`this.el`), with the appropriate HTML. The
-    // convention is for **render** to always return `this`.
-    render: function() {
-      return this;
-    },
-
-    // Remove this view by taking the element out of the DOM, and removing any
-    // applicable Backbone.Events listeners.
-    remove: function() {
-      this.$el.remove();
-      this.stopListening();
-      return this;
-    },
-
-    // Change the view's element (`this.el` property), including event
-    // re-delegation.
-    setElement: function(element, delegate) {
-      if (this.$el) this.undelegateEvents();
-      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
-      this.el = this.$el[0];
-      if (delegate !== false) this.delegateEvents();
-      return this;
-    },
-
-    // Set callbacks, where `this.events` is a hash of
-    //
-    // *{"event selector": "callback"}*
-    //
-    //     {
-    //       'mousedown .title':  'edit',
-    //       'click .button':     'save',
-    //       'click .open':       function(e) { ... }
-    //     }
-    //
-    // pairs. Callbacks will be bound to the view, with `this` set properly.
-    // Uses event delegation for efficiency.
-    // Omitting the selector binds the event to `this.el`.
-    // This only works for delegate-able events: not `focus`, `blur`, and
-    // not `change`, `submit`, and `reset` in Internet Explorer.
-    delegateEvents: function(events) {
-      if (!(events || (events = _.result(this, 'events')))) return this;
-      this.undelegateEvents();
-      for (var key in events) {
-        var method = events[key];
-        if (!_.isFunction(method)) method = this[events[key]];
-        if (!method) continue;
-
-        var match = key.match(delegateEventSplitter);
-        var eventName = match[1], selector = match[2];
-        method = _.bind(method, this);
-        eventName += '.delegateEvents' + this.cid;
-        if (selector === '') {
-          this.$el.on(eventName, method);
-        } else {
-          this.$el.on(eventName, selector, method);
-        }
-      }
-      return this;
-    },
-
-    // Clears all callbacks previously bound to the view with `delegateEvents`.
-    // You usually don't need to use this, but may wish to if you have multiple
-    // Backbone views attached to the same DOM element.
-    undelegateEvents: function() {
-      this.$el.off('.delegateEvents' + this.cid);
-      return this;
-    },
-
-    // Ensure that the View has a DOM element to render into.
-    // If `this.el` is a string, pass it through `$()`, take the first
-    // matching element, and re-assign it to `el`. Otherwise, create
-    // an element from the `id`, `className` and `tagName` properties.
-    _ensureElement: function() {
-      if (!this.el) {
-        var attrs = _.extend({}, _.result(this, 'attributes'));
-        if (this.id) attrs.id = _.result(this, 'id');
-        if (this.className) attrs['class'] = _.result(this, 'className');
-        var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
-        this.setElement($el, false);
-      } else {
-        this.setElement(_.result(this, 'el'), false);
-      }
-    }
-
-  });
-
-  // Backbone.sync
-  // -------------
-
-  // Override this function to change the manner in which Backbone persists
-  // models to the server. You will be passed the type of request, and the
-  // model in question. By default, makes a RESTful Ajax request
-  // to the model's `url()`. Some possible customizations could be:
-  //
-  // * Use `setTimeout` to batch rapid-fire updates into a single request.
-  // * Send up the models as XML instead of JSON.
-  // * Persist models via WebSockets instead of Ajax.
-  //
-  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
-  // as `POST`, with a `_method` parameter containing the true HTTP method,
-  // as well as all requests with the body as `application/x-www-form-urlencoded`
-  // instead of `application/json` with the model in a param named `model`.
-  // Useful when interfacing with server-side languages like **PHP** that make
-  // it difficult to read the body of `PUT` requests.
-  Backbone.sync = function(method, model, options) {
-    var type = methodMap[method];
-
-    // Default options, unless specified.
-    _.defaults(options || (options = {}), {
-      emulateHTTP: Backbone.emulateHTTP,
-      emulateJSON: Backbone.emulateJSON
-    });
-
-    // Default JSON-request options.
-    var params = {type: type, dataType: 'json'};
-
-    // Ensure that we have a URL.
-    if (!options.url) {
-      params.url = _.result(model, 'url') || urlError();
-    }
-
-    // Ensure that we have the appropriate request data.
-    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
-      params.contentType = 'application/json';
-      params.data = JSON.stringify(options.attrs || model.toJSON(options));
-    }
-
-    // For older servers, emulate JSON by encoding the request into an HTML-form.
-    if (options.emulateJSON) {
-      params.contentType = 'application/x-www-form-urlencoded';
-      params.data = params.data ? {model: params.data} : {};
-    }
-
-    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
-    // And an `X-HTTP-Method-Override` header.
-    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
-      params.type = 'POST';
-      if (options.emulateJSON) params.data._method = type;
-      var beforeSend = options.beforeSend;
-      options.beforeSend = function(xhr) {
-        xhr.setRequestHeader('X-HTTP-Method-Override', type);
-        if (beforeSend) return beforeSend.apply(this, arguments);
-      };
-    }
-
-    // Don't process data on a non-GET request.
-    if (params.type !== 'GET' && !options.emulateJSON) {
-      params.processData = false;
-    }
-
-    // If we're sending a `PATCH` request, and we're in an old Internet Explorer
-    // that still has ActiveX enabled by default, override jQuery to use that
-    // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
-    if (params.type === 'PATCH' && noXhrPatch) {
-      params.xhr = function() {
-        return new ActiveXObject("Microsoft.XMLHTTP");
-      };
-    }
-
-    // Make the request, allowing the user to override any Ajax options.
-    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
-    model.trigger('request', model, xhr, options);
-    return xhr;
-  };
-
-  var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
-
-  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
-  var methodMap = {
-    'create': 'POST',
-    'update': 'PUT',
-    'patch':  'PATCH',
-    'delete': 'DELETE',
-    'read':   'GET'
-  };
-
-  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
-  // Override this if you'd like to use a different library.
-  Backbone.ajax = function() {
-    return Backbone.$.ajax.apply(Backbone.$, arguments);
-  };
-
-  // Backbone.Router
-  // ---------------
+  // Backbone.Router
+  // -------------------
 
   // Routers map faux-URLs to actions, and fire events when routes are
   // matched. Creating a new one sets its `routes` hash, if not set statically.
@@ -1211,10 +894,9 @@
 
   // Cached regular expressions for matching named param parts and splatted
   // parts of route strings.
-  var optionalParam = /\((.*?)\)/g;
-  var namedParam    = /(\(\?)?:\w+/g;
+  var namedParam    = /:\w+/g;
   var splatParam    = /\*\w+/g;
-  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+  var escapeRegExp  = /[-[\]{}()+?.,\\^$|#\s]/g;
 
   // Set up all inheritable **Backbone.Router** properties and methods.
   _.extend(Router.prototype, Events, {
@@ -1231,19 +913,13 @@
     //
     route: function(route, name, callback) {
       if (!_.isRegExp(route)) route = this._routeToRegExp(route);
-      if (_.isFunction(name)) {
-        callback = name;
-        name = '';
-      }
       if (!callback) callback = this[name];
-      var router = this;
-      Backbone.history.route(route, function(fragment) {
-        var args = router._extractParameters(route, fragment);
-        callback && callback.apply(router, args);
-        router.trigger.apply(router, ['route:' + name].concat(args));
-        router.trigger('route', name, args);
-        Backbone.history.trigger('route', router, name, args);
-      });
+      Backbone.history.route(route, _.bind(function(fragment) {
+        var args = this._extractParameters(route, fragment);
+        callback && callback.apply(this, args);
+        this.trigger.apply(this, ['route:' + name].concat(args));
+        Backbone.history.trigger('route', this, name, args);
+      }, this));
       return this;
     },
 
@@ -1258,10 +934,12 @@
     // routes can be defined at the bottom of the route map.
     _bindRoutes: function() {
       if (!this.routes) return;
-      this.routes = _.result(this, 'routes');
-      var route, routes = _.keys(this.routes);
-      while ((route = routes.pop()) != null) {
-        this.route(route, this.routes[route]);
+      var routes = [];
+      for (var route in this.routes) {
+        routes.unshift([route, this.routes[route]]);
+      }
+      for (var i = 0, l = routes.length; i < l; i++) {
+        this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
       }
     },
 
@@ -1269,22 +947,15 @@
     // against the current location hash.
     _routeToRegExp: function(route) {
       route = route.replace(escapeRegExp, '\\$&')
-                   .replace(optionalParam, '(?:$1)?')
-                   .replace(namedParam, function(match, optional) {
-                     return optional ? match : '([^\/]+)';
-                   })
+                   .replace(namedParam, '([^\/]+)')
                    .replace(splatParam, '(.*?)');
       return new RegExp('^' + route + '$');
     },
 
     // Given a route, and a URL fragment that it matches, return the array of
-    // extracted decoded parameters. Empty or unmatched parameters will be
-    // treated as `null` to normalize cross-browser behavior.
+    // extracted parameters.
     _extractParameters: function(route, fragment) {
-      var params = route.exec(fragment).slice(1);
-      return _.map(params, function(param) {
-        return param ? decodeURIComponent(param) : null;
-      });
+      return route.exec(fragment).slice(1);
     }
 
   });
@@ -1292,24 +963,21 @@
   // Backbone.History
   // ----------------
 
-  // Handles cross-browser history management, based on either
-  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
-  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
-  // and URL fragments. If the browser supports neither (old IE, natch),
-  // falls back to polling.
+  // Handles cross-browser history management, based on URL fragments. If the
+  // browser does not support `onhashchange`, falls back to polling.
   var History = Backbone.History = function() {
     this.handlers = [];
     _.bindAll(this, 'checkUrl');
 
-    // Ensure that `History` can be used outside of the browser.
+    // #1653 - Ensure that `History` can be used outside of the browser.
     if (typeof window !== 'undefined') {
       this.location = window.location;
       this.history = window.history;
     }
   };
 
-  // Cached regex for stripping a leading hash/slash and trailing space.
-  var routeStripper = /^[#\/]|\s+$/g;
+  // Cached regex for cleaning leading hashes and slashes.
+  var routeStripper = /^[#\/]/;
 
   // Cached regex for stripping leading and trailing slashes.
   var rootStripper = /^\/+|\/+$/g;
@@ -1320,9 +988,6 @@
   // Cached regex for removing a trailing slash.
   var trailingSlash = /\/$/;
 
-  // Cached regex for stripping urls of hash and query.
-  var pathStripper = /[?#].*$/;
-
   // Has the history handling already been started?
   History.started = false;
 
@@ -1347,12 +1012,12 @@
         if (this._hasPushState || !this._wantsHashChange || forcePushState) {
           fragment = this.location.pathname;
           var root = this.root.replace(trailingSlash, '');
-          if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
+          if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
         } else {
           fragment = this.getHash();
         }
       }
-      return fragment.replace(routeStripper, '');
+      return decodeURIComponent(fragment.replace(routeStripper, ''));
     },
 
     // Start the hash change handling, returning `true` if the current URL matches
@@ -1363,7 +1028,7 @@
 
       // Figure out the initial configuration. Do we need an iframe?
       // Is pushState desired ... is it available?
-      this.options          = _.extend({root: '/'}, this.options, options);
+      this.options          = _.extend({}, {root: '/'}, this.options, options);
       this.root             = this.options.root;
       this._wantsHashChange = this.options.hashChange !== false;
       this._wantsPushState  = !!this.options.pushState;
@@ -1383,9 +1048,9 @@
       // Depending on whether we're using pushState or hashes, and whether
       // 'onhashchange' is supported, determine how we check the URL state.
       if (this._hasPushState) {
-        Backbone.$(window).on('popstate', this.checkUrl);
+        Backbone.$(window).bind('popstate', this.checkUrl);
       } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
-        Backbone.$(window).on('hashchange', this.checkUrl);
+        Backbone.$(window).bind('hashchange', this.checkUrl);
       } else if (this._wantsHashChange) {
         this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
       }
@@ -1394,27 +1059,21 @@
       // opened by a non-pushState browser.
       this.fragment = fragment;
       var loc = this.location;
-      var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
-
-      // Transition from hashChange to pushState or vice versa if both are
-      // requested.
-      if (this._wantsHashChange && this._wantsPushState) {
-
-        // If we've started off with a route from a `pushState`-enabled
-        // browser, but we're currently in a browser that doesn't support it...
-        if (!this._hasPushState && !atRoot) {
-          this.fragment = this.getFragment(null, true);
-          this.location.replace(this.root + this.location.search + '#' + this.fragment);
-          // Return immediately as browser will do redirect to new url
-          return true;
-
-        // Or if we've started out with a hash-based route, but we're currently
-        // in a browser where it could be `pushState`-based instead...
-        } else if (this._hasPushState && atRoot && loc.hash) {
-          this.fragment = this.getHash().replace(routeStripper, '');
-          this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
-        }
+      var atRoot = (loc.pathname.replace(/[^/]$/, '$&/') === this.root) && !loc.search;
+
+      // If we've started off with a route from a `pushState`-enabled browser,
+      // but we're currently in a browser that doesn't support it...
+      if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
+        this.fragment = this.getFragment(null, true);
+        this.location.replace(this.root + this.location.search + '#' + this.fragment);
+        // Return immediately as browser will do redirect to new url
+        return true;
 
+      // Or if we've started out with a hash-based route, but we're currently
+      // in a browser where it could be `pushState`-based instead...
+      } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
+        this.fragment = this.getHash().replace(routeStripper, '');
+        this.history.replaceState({}, document.title, this.root + this.fragment);
       }
 
       if (!this.options.silent) return this.loadUrl();
@@ -1423,7 +1082,7 @@
     // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
     // but possibly useful for unit testing Routers.
     stop: function() {
-      Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
+      Backbone.$(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
       clearInterval(this._checkUrlInterval);
       History.started = false;
     },
@@ -1443,20 +1102,21 @@
       }
       if (current === this.fragment) return false;
       if (this.iframe) this.navigate(current);
-      this.loadUrl();
+      this.loadUrl() || this.loadUrl(this.getHash());
     },
 
     // Attempt to load the current URL fragment. If a route succeeds with a
     // match, returns `true`. If no defined routes matches the fragment,
     // returns `false`.
-    loadUrl: function(fragment) {
-      fragment = this.fragment = this.getFragment(fragment);
-      return _.any(this.handlers, function(handler) {
+    loadUrl: function(fragmentOverride) {
+      var fragment = this.fragment = this.getFragment(fragmentOverride);
+      var matched = _.any(this.handlers, function(handler) {
         if (handler.route.test(fragment)) {
           handler.callback(fragment);
           return true;
         }
       });
+      return matched;
     },
 
     // Save a fragment into the hash history, or replace the URL state if the
@@ -1468,18 +1128,11 @@
     // you wish to modify the current URL without adding an entry to the history.
     navigate: function(fragment, options) {
       if (!History.started) return false;
-      if (!options || options === true) options = {trigger: !!options};
-
-      var url = this.root + (fragment = this.getFragment(fragment || ''));
-
-      // Strip the fragment of the query and hash for matching.
-      fragment = fragment.replace(pathStripper, '');
-
+      if (!options || options === true) options = {trigger: options};
+      fragment = this.getFragment(fragment || '');
       if (this.fragment === fragment) return;
       this.fragment = fragment;
-
-      // Don't include a trailing slash on the root.
-      if (fragment === '' && url !== '/') url = url.slice(0, -1);
+      var url = this.root + fragment;
 
       // If pushState is available, we use it to set the fragment as a real URL.
       if (this._hasPushState) {
@@ -1502,7 +1155,7 @@
       } else {
         return this.location.assign(url);
       }
-      if (options.trigger) return this.loadUrl(fragment);
+      if (options.trigger) this.loadUrl(fragment);
     },
 
     // Update the hash location, either replacing the current entry, or adding
@@ -1512,7 +1165,7 @@
         var href = location.href.replace(/(javascript:|#).*$/, '');
         location.replace(href + '#' + fragment);
       } else {
-        // Some browsers require that `hash` contains a leading #.
+        // #1649 - Some browsers require that `hash` contains a leading #.
         location.hash = '#' + fragment;
       }
     }
@@ -1522,6 +1175,247 @@
   // Create the default Backbone.history.
   Backbone.history = new History;
 
+  // Backbone.View
+  // -------------
+
+  // Creating a Backbone.View creates its initial element outside of the DOM,
+  // if an existing element is not provided...
+  var View = Backbone.View = function(options) {
+    this.cid = _.uniqueId('view');
+    this._configure(options || {});
+    this._ensureElement();
+    this.initialize.apply(this, arguments);
+    this.delegateEvents();
+  };
+
+  // Cached regex to split keys for `delegate`.
+  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+  // List of view options to be merged as properties.
+  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
+
+  // Set up all inheritable **Backbone.View** properties and methods.
+  _.extend(View.prototype, Events, {
+
+    // The default `tagName` of a View's element is `"div"`.
+    tagName: 'div',
+
+    // jQuery delegate for element lookup, scoped to DOM elements within the
+    // current view. This should be prefered to global lookups where possible.
+    $: function(selector) {
+      return this.$el.find(selector);
+    },
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // **render** is the core function that your view should override, in order
+    // to populate its element (`this.el`), with the appropriate HTML. The
+    // convention is for **render** to always return `this`.
+    render: function() {
+      return this;
+    },
+
+    // Clean up references to this view in order to prevent latent effects and
+    // memory leaks.
+    dispose: function() {
+      this.undelegateEvents();
+      if (this.model) this.model.off(null, null, this);
+      if (this.collection) this.collection.off(null, null, this);
+      return this;
+    },
+
+    // Remove this view from the DOM. Note that the view isn't present in the
+    // DOM by default, so calling this method may be a no-op.
+    remove: function() {
+      this.dispose();
+      this.$el.remove();
+      return this;
+    },
+
+    // For small amounts of DOM Elements, where a full-blown template isn't
+    // needed, use **make** to manufacture elements, one at a time.
+    //
+    //     var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
+    //
+    make: function(tagName, attributes, content) {
+      var el = document.createElement(tagName);
+      if (attributes) Backbone.$(el).attr(attributes);
+      if (content != null) Backbone.$(el).html(content);
+      return el;
+    },
+
+    // Change the view's element (`this.el` property), including event
+    // re-delegation.
+    setElement: function(element, delegate) {
+      if (this.$el) this.undelegateEvents();
+      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
+      this.el = this.$el[0];
+      if (delegate !== false) this.delegateEvents();
+      return this;
+    },
+
+    // Set callbacks, where `this.events` is a hash of
+    //
+    // *{"event selector": "callback"}*
+    //
+    //     {
+    //       'mousedown .title':  'edit',
+    //       'click .button':     'save'
+    //       'click .open':       function(e) { ... }
+    //     }
+    //
+    // pairs. Callbacks will be bound to the view, with `this` set properly.
+    // Uses event delegation for efficiency.
+    // Omitting the selector binds the event to `this.el`.
+    // This only works for delegate-able events: not `focus`, `blur`, and
+    // not `change`, `submit`, and `reset` in Internet Explorer.
+    delegateEvents: function(events) {
+      if (!(events || (events = _.result(this, 'events')))) return;
+      this.undelegateEvents();
+      for (var key in events) {
+        var method = events[key];
+        if (!_.isFunction(method)) method = this[events[key]];
+        if (!method) throw new Error('Method "' + events[key] + '" does not exist');
+        var match = key.match(delegateEventSplitter);
+        var eventName = match[1], selector = match[2];
+        method = _.bind(method, this);
+        eventName += '.delegateEvents' + this.cid;
+        if (selector === '') {
+          this.$el.bind(eventName, method);
+        } else {
+          this.$el.delegate(selector, eventName, method);
+        }
+      }
+    },
+
+    // Clears all callbacks previously bound to the view with `delegateEvents`.
+    // You usually don't need to use this, but may wish to if you have multiple
+    // Backbone views attached to the same DOM element.
+    undelegateEvents: function() {
+      this.$el.unbind('.delegateEvents' + this.cid);
+    },
+
+    // Performs the initial configuration of a View with a set of options.
+    // Keys with special meaning *(model, collection, id, className)*, are
+    // attached directly to the view.
+    _configure: function(options) {
+      if (this.options) options = _.extend({}, this.options, options);
+      for (var i = 0, l = viewOptions.length; i < l; i++) {
+        var attr = viewOptions[i];
+        if (options[attr]) this[attr] = options[attr];
+      }
+      this.options = options;
+    },
+
+    // Ensure that the View has a DOM element to render into.
+    // If `this.el` is a string, pass it through `$()`, take the first
+    // matching element, and re-assign it to `el`. Otherwise, create
+    // an element from the `id`, `className` and `tagName` properties.
+    _ensureElement: function() {
+      if (!this.el) {
+        var attrs = _.extend({}, _.result(this, 'attributes'));
+        if (this.id) attrs.id = _.result(this, 'id');
+        if (this.className) attrs['class'] = _.result(this, 'className');
+        this.setElement(this.make(_.result(this, 'tagName'), attrs), false);
+      } else {
+        this.setElement(this.el, false);
+      }
+    }
+
+  });
+
+  // Backbone.sync
+  // -------------
+
+  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+  var methodMap = {
+    'create': 'POST',
+    'update': 'PUT',
+    'delete': 'DELETE',
+    'read':   'GET'
+  };
+
+  // Override this function to change the manner in which Backbone persists
+  // models to the server. You will be passed the type of request, and the
+  // model in question. By default, makes a RESTful Ajax request
+  // to the model's `url()`. Some possible customizations could be:
+  //
+  // * Use `setTimeout` to batch rapid-fire updates into a single request.
+  // * Send up the models as XML instead of JSON.
+  // * Persist models via WebSockets instead of Ajax.
+  //
+  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
+  // as `POST`, with a `_method` parameter containing the true HTTP method,
+  // as well as all requests with the body as `application/x-www-form-urlencoded`
+  // instead of `application/json` with the model in a param named `model`.
+  // Useful when interfacing with server-side languages like **PHP** that make
+  // it difficult to read the body of `PUT` requests.
+  Backbone.sync = function(method, model, options) {
+    var type = methodMap[method];
+
+    // Default options, unless specified.
+    options || (options = {});
+
+    // Default JSON-request options.
+    var params = {type: type, dataType: 'json'};
+
+    // Ensure that we have a URL.
+    if (!options.url) {
+      params.url = _.result(model, 'url') || urlError();
+    }
+
+    // Ensure that we have the appropriate request data.
+    if (!options.data && model && (method === 'create' || method === 'update')) {
+      params.contentType = 'application/json';
+      params.data = JSON.stringify(model);
+    }
+
+    // For older servers, emulate JSON by encoding the request into an HTML-form.
+    if (Backbone.emulateJSON) {
+      params.contentType = 'application/x-www-form-urlencoded';
+      params.data = params.data ? {model: params.data} : {};
+    }
+
+    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
+    // And an `X-HTTP-Method-Override` header.
+    if (Backbone.emulateHTTP) {
+      if (type === 'PUT' || type === 'DELETE') {
+        if (Backbone.emulateJSON) params.data._method = type;
+        params.type = 'POST';
+        params.beforeSend = function(xhr) {
+          xhr.setRequestHeader('X-HTTP-Method-Override', type);
+        };
+      }
+    }
+
+    // Don't process data on a non-GET request.
+    if (params.type !== 'GET' && !Backbone.emulateJSON) {
+      params.processData = false;
+    }
+
+    var success = options.success;
+    options.success = function(resp, status, xhr) {
+      if (success) success(resp, status, xhr);
+      model.trigger('sync', model, resp, options);
+    };
+
+    var error = options.error;
+    options.error = function(xhr, status, thrown) {
+      if (error) error(model, xhr, options);
+      model.trigger('error', model, xhr, options);
+    };
+
+    // Make the request, allowing the user to override any Ajax options.
+    return Backbone.ajax(_.extend(params, options));
+  };
+
+  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
+  Backbone.ajax = function() {
+    return Backbone.$.ajax.apply(Backbone.$, arguments);
+  };
+
   // Helpers
   // -------
 
@@ -1538,15 +1432,12 @@
     if (protoProps && _.has(protoProps, 'constructor')) {
       child = protoProps.constructor;
     } else {
-      child = function(){ return parent.apply(this, arguments); };
+      child = function(){ parent.apply(this, arguments); };
     }
 
-    // Add static properties to the constructor function, if supplied.
-    _.extend(child, parent, staticProps);
-
     // Set the prototype chain to inherit from `parent`, without calling
     // `parent`'s constructor function.
-    var Surrogate = function(){ this.constructor = child; };
+    function Surrogate(){ this.constructor = child; };
     Surrogate.prototype = parent.prototype;
     child.prototype = new Surrogate;
 
@@ -1554,6 +1445,9 @@
     // if supplied.
     if (protoProps) _.extend(child.prototype, protoProps);
 
+    // Add static properties to the constructor function, if supplied.
+    _.extend(child, parent, staticProps);
+
     // Set a convenience property in case the parent's prototype is needed
     // later.
     child.__super__ = parent.prototype;
@@ -1561,21 +1455,12 @@
     return child;
   };
 
-  // Set up inheritance for the model, collection, router, view and history.
-  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
+  // Set up inheritance for the model, collection, router, and view.
+  Model.extend = Collection.extend = Router.extend = View.extend = extend;
 
   // Throw an error when a URL is needed, and none is supplied.
   var urlError = function() {
     throw new Error('A "url" property or function must be specified');
   };
 
-  // Wrap an optional error callback with a fallback error event.
-  var wrapError = function(model, options) {
-    var error = options.error;
-    options.error = function(resp) {
-      if (error) error(model, resp, options);
-      model.trigger('error', model, resp, options);
-    };
-  };
-
 }).call(this);
diff --git a/core/assets/vendor/underscore/underscore.js b/core/assets/vendor/underscore/underscore.js
index 8887e19..013dcad 100644
--- a/core/assets/vendor/underscore/underscore.js
+++ b/core/assets/vendor/underscore/underscore.js
@@ -1,6 +1,6 @@
-//     Underscore.js 1.5.2
+//     Underscore.js 1.4.0
 //     http://underscorejs.org
-//     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
 //     Underscore may be freely distributed under the MIT license.
 
 (function() {
@@ -8,7 +8,7 @@
   // Baseline setup
   // --------------
 
-  // Establish the root object, `window` in the browser, or `exports` on the server.
+  // Establish the root object, `window` in the browser, or `global` on the server.
   var root = this;
 
   // Save the previous value of the `_` variable.
@@ -21,12 +21,12 @@
   var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
 
   // Create quick reference variables for speed access to core prototypes.
-  var
-    push             = ArrayProto.push,
-    slice            = ArrayProto.slice,
-    concat           = ArrayProto.concat,
-    toString         = ObjProto.toString,
-    hasOwnProperty   = ObjProto.hasOwnProperty;
+  var push             = ArrayProto.push,
+      slice            = ArrayProto.slice,
+      concat           = ArrayProto.concat,
+      unshift          = ArrayProto.unshift,
+      toString         = ObjProto.toString,
+      hasOwnProperty   = ObjProto.hasOwnProperty;
 
   // All **ECMAScript 5** native function implementations that we hope to use
   // are declared here.
@@ -61,11 +61,11 @@
     }
     exports._ = _;
   } else {
-    root._ = _;
+    root['_'] = _;
   }
 
   // Current version.
-  _.VERSION = '1.5.2';
+  _.VERSION = '1.4.0';
 
   // Collection Functions
   // --------------------
@@ -74,17 +74,17 @@
   // Handles objects with the built-in `forEach`, arrays, and raw objects.
   // Delegates to **ECMAScript 5**'s native `forEach` if available.
   var each = _.each = _.forEach = function(obj, iterator, context) {
-    if (obj == null) return;
     if (nativeForEach && obj.forEach === nativeForEach) {
       obj.forEach(iterator, context);
     } else if (obj.length === +obj.length) {
-      for (var i = 0, length = obj.length; i < length; i++) {
+      for (var i = 0, l = obj.length; i < l; i++) {
         if (iterator.call(context, obj[i], i, obj) === breaker) return;
       }
     } else {
-      var keys = _.keys(obj);
-      for (var i = 0, length = keys.length; i < length; i++) {
-        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
+      for (var key in obj) {
+        if (_.has(obj, key)) {
+          if (iterator.call(context, obj[key], key, obj) === breaker) return;
+        }
       }
     }
   };
@@ -93,21 +93,17 @@
   // Delegates to **ECMAScript 5**'s native `map` if available.
   _.map = _.collect = function(obj, iterator, context) {
     var results = [];
-    if (obj == null) return results;
     if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
     each(obj, function(value, index, list) {
-      results.push(iterator.call(context, value, index, list));
+      results[results.length] = iterator.call(context, value, index, list);
     });
     return results;
   };
 
-  var reduceError = 'Reduce of empty array with no initial value';
-
   // **Reduce** builds up a single result from a list of values, aka `inject`,
   // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
   _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
     var initial = arguments.length > 2;
-    if (obj == null) obj = [];
     if (nativeReduce && obj.reduce === nativeReduce) {
       if (context) iterator = _.bind(iterator, context);
       return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
@@ -120,7 +116,7 @@
         memo = iterator.call(context, memo, value, index, list);
       }
     });
-    if (!initial) throw new TypeError(reduceError);
+    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
     return memo;
   };
 
@@ -128,10 +124,9 @@
   // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
   _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
     var initial = arguments.length > 2;
-    if (obj == null) obj = [];
     if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
       if (context) iterator = _.bind(iterator, context);
-      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+      return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
     }
     var length = obj.length;
     if (length !== +length) {
@@ -147,7 +142,7 @@
         memo = iterator.call(context, memo, obj[index], index, list);
       }
     });
-    if (!initial) throw new TypeError(reduceError);
+    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
     return memo;
   };
 
@@ -168,19 +163,20 @@
   // Aliased as `select`.
   _.filter = _.select = function(obj, iterator, context) {
     var results = [];
-    if (obj == null) return results;
     if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
     each(obj, function(value, index, list) {
-      if (iterator.call(context, value, index, list)) results.push(value);
+      if (iterator.call(context, value, index, list)) results[results.length] = value;
     });
     return results;
   };
 
   // Return all the elements for which a truth test fails.
   _.reject = function(obj, iterator, context) {
-    return _.filter(obj, function(value, index, list) {
-      return !iterator.call(context, value, index, list);
-    }, context);
+    var results = [];
+    each(obj, function(value, index, list) {
+      if (!iterator.call(context, value, index, list)) results[results.length] = value;
+    });
+    return results;
   };
 
   // Determine whether all of the elements match a truth test.
@@ -189,7 +185,6 @@
   _.every = _.all = function(obj, iterator, context) {
     iterator || (iterator = _.identity);
     var result = true;
-    if (obj == null) return result;
     if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
     each(obj, function(value, index, list) {
       if (!(result = result && iterator.call(context, value, index, list))) return breaker;
@@ -203,7 +198,6 @@
   var any = _.some = _.any = function(obj, iterator, context) {
     iterator || (iterator = _.identity);
     var result = false;
-    if (obj == null) return result;
     if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
     each(obj, function(value, index, list) {
       if (result || (result = iterator.call(context, value, index, list))) return breaker;
@@ -214,19 +208,19 @@
   // Determine if the array or object contains a given value (using `===`).
   // Aliased as `include`.
   _.contains = _.include = function(obj, target) {
-    if (obj == null) return false;
+    var found = false;
     if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
-    return any(obj, function(value) {
+    found = any(obj, function(value) {
       return value === target;
     });
+    return found;
   };
 
   // Invoke a method (with arguments) on every item in a collection.
   _.invoke = function(obj, method) {
     var args = slice.call(arguments, 2);
-    var isFunc = _.isFunction(method);
     return _.map(obj, function(value) {
-      return (isFunc ? method : value[method]).apply(value, args);
+      return (_.isFunction(method) ? method : value[method]).apply(value, args);
     });
   };
 
@@ -236,10 +230,10 @@
   };
 
   // Convenience version of a common use case of `filter`: selecting only objects
-  // containing specific `key:value` pairs.
-  _.where = function(obj, attrs, first) {
-    if (_.isEmpty(attrs)) return first ? void 0 : [];
-    return _[first ? 'find' : 'filter'](obj, function(value) {
+  // with specific `key:value` pairs.
+  _.where = function(obj, attrs) {
+    if (_.isEmpty(attrs)) return [];
+    return _.filter(obj, function(value) {
       for (var key in attrs) {
         if (attrs[key] !== value[key]) return false;
       }
@@ -247,24 +241,18 @@
     });
   };
 
-  // Convenience version of a common use case of `find`: getting the first object
-  // containing specific `key:value` pairs.
-  _.findWhere = function(obj, attrs) {
-    return _.where(obj, attrs, true);
-  };
-
   // Return the maximum element or (element-based computation).
   // Can't optimize arrays of integers longer than 65,535 elements.
-  // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
+  // See: https://bugs.webkit.org/show_bug.cgi?id=80797
   _.max = function(obj, iterator, context) {
     if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
       return Math.max.apply(Math, obj);
     }
     if (!iterator && _.isEmpty(obj)) return -Infinity;
-    var result = {computed : -Infinity, value: -Infinity};
+    var result = {computed : -Infinity};
     each(obj, function(value, index, list) {
       var computed = iterator ? iterator.call(context, value, index, list) : value;
-      computed > result.computed && (result = {value : value, computed : computed});
+      computed >= result.computed && (result = {value : value, computed : computed});
     });
     return result.value;
   };
@@ -275,7 +263,7 @@
       return Math.min.apply(Math, obj);
     }
     if (!iterator && _.isEmpty(obj)) return Infinity;
-    var result = {computed : Infinity, value: Infinity};
+    var result = {computed : Infinity};
     each(obj, function(value, index, list) {
       var computed = iterator ? iterator.call(context, value, index, list) : value;
       computed < result.computed && (result = {value : value, computed : computed});
@@ -283,8 +271,7 @@
     return result.value;
   };
 
-  // Shuffle an array, using the modern version of the
-  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisherâ€“Yates_shuffle).
+  // Shuffle an array.
   _.shuffle = function(obj) {
     var rand;
     var index = 0;
@@ -297,16 +284,6 @@
     return shuffled;
   };
 
-  // Sample **n** random values from an array.
-  // If **n** is not specified, returns a single random element from the array.
-  // The internal `guard` argument allows it to work with `map`.
-  _.sample = function(obj, n, guard) {
-    if (arguments.length < 2 || guard) {
-      return obj[_.random(obj.length - 1)];
-    }
-    return _.shuffle(obj).slice(0, Math.max(0, n));
-  };
-
   // An internal function to generate lookup iterators.
   var lookupIterator = function(value) {
     return _.isFunction(value) ? value : function(obj){ return obj[value]; };
@@ -317,9 +294,9 @@
     var iterator = lookupIterator(value);
     return _.pluck(_.map(obj, function(value, index, list) {
       return {
-        value: value,
-        index: index,
-        criteria: iterator.call(context, value, index, list)
+        value : value,
+        index : index,
+        criteria : iterator.call(context, value, index, list)
       };
     }).sort(function(left, right) {
       var a = left.criteria;
@@ -328,41 +305,38 @@
         if (a > b || a === void 0) return 1;
         if (a < b || b === void 0) return -1;
       }
-      return left.index - right.index;
+      return left.index < right.index ? -1 : 1;
     }), 'value');
   };
 
   // An internal function used for aggregate "group by" operations.
-  var group = function(behavior) {
-    return function(obj, value, context) {
-      var result = {};
-      var iterator = value == null ? _.identity : lookupIterator(value);
-      each(obj, function(value, index) {
-        var key = iterator.call(context, value, index, obj);
-        behavior(result, key, value);
-      });
-      return result;
-    };
+  var group = function(obj, value, context, behavior) {
+    var result = {};
+    var iterator = lookupIterator(value);
+    each(obj, function(value, index) {
+      var key = iterator.call(context, value, index, obj);
+      behavior(result, key, value);
+    });
+    return result;
   };
 
   // Groups the object's values by a criterion. Pass either a string attribute
   // to group by, or a function that returns the criterion.
-  _.groupBy = group(function(result, key, value) {
-    (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
-  });
-
-  // Indexes the object's values by a criterion, similar to `groupBy`, but for
-  // when you know that your index values will be unique.
-  _.indexBy = group(function(result, key, value) {
-    result[key] = value;
-  });
+  _.groupBy = function(obj, value, context) {
+    return group(obj, value, context, function(result, key, value) {
+      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
+    });
+  };
 
   // Counts instances of an object that group by a certain criterion. Pass
   // either a string attribute to count by, or a function that returns the
   // criterion.
-  _.countBy = group(function(result, key) {
-    _.has(result, key) ? result[key]++ : result[key] = 1;
-  });
+  _.countBy = function(obj, value, context) {
+    return group(obj, value, context, function(result, key, value) {
+      if (!_.has(result, key)) result[key] = 0;
+      result[key]++;
+    });
+  };
 
   // Use a comparator function to figure out the smallest index at which
   // an object should be inserted so as to maintain order. Uses binary search.
@@ -377,17 +351,15 @@
     return low;
   };
 
-  // Safely create a real, live array from anything iterable.
+  // Safely convert anything iterable into a real, live array.
   _.toArray = function(obj) {
     if (!obj) return [];
-    if (_.isArray(obj)) return slice.call(obj);
-    if (obj.length === +obj.length) return _.map(obj, _.identity);
+    if (obj.length === +obj.length) return slice.call(obj);
     return _.values(obj);
   };
 
   // Return the number of elements in an object.
   _.size = function(obj) {
-    if (obj == null) return 0;
     return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
   };
 
@@ -398,8 +370,7 @@
   // values in the array. Aliased as `head` and `take`. The **guard** check
   // allows it to work with `_.map`.
   _.first = _.head = _.take = function(array, n, guard) {
-    if (array == null) return void 0;
-    return (n == null) || guard ? array[0] : slice.call(array, 0, n);
+    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
   };
 
   // Returns everything but the last entry of the array. Especially useful on
@@ -413,11 +384,10 @@
   // Get the last element of an array. Passing **n** will return the last N
   // values in the array. The **guard** check allows it to work with `_.map`.
   _.last = function(array, n, guard) {
-    if (array == null) return void 0;
-    if ((n == null) || guard) {
-      return array[array.length - 1];
-    } else {
+    if ((n != null) && !guard) {
       return slice.call(array, Math.max(array.length - n, 0));
+    } else {
+      return array[array.length - 1];
     }
   };
 
@@ -431,16 +401,13 @@
 
   // Trim out all falsy values from an array.
   _.compact = function(array) {
-    return _.filter(array, _.identity);
+    return _.filter(array, function(value){ return !!value; });
   };
 
   // Internal implementation of a recursive `flatten` function.
   var flatten = function(input, shallow, output) {
-    if (shallow && _.every(input, _.isArray)) {
-      return concat.apply(output, input);
-    }
     each(input, function(value) {
-      if (_.isArray(value) || _.isArguments(value)) {
+      if (_.isArray(value)) {
         shallow ? push.apply(output, value) : flatten(value, shallow, output);
       } else {
         output.push(value);
@@ -449,7 +416,7 @@
     return output;
   };
 
-  // Flatten out an array, either recursively (by default), or just one level.
+  // Return a completely flattened version of an array.
   _.flatten = function(array, shallow) {
     return flatten(array, shallow, []);
   };
@@ -463,11 +430,6 @@
   // been sorted, you have the option of using a faster algorithm.
   // Aliased as `unique`.
   _.uniq = _.unique = function(array, isSorted, iterator, context) {
-    if (_.isFunction(isSorted)) {
-      context = iterator;
-      iterator = isSorted;
-      isSorted = false;
-    }
     var initial = iterator ? _.map(array, iterator, context) : array;
     var results = [];
     var seen = [];
@@ -483,7 +445,7 @@
   // Produce an array that contains the union: each distinct element from all of
   // the passed-in arrays.
   _.union = function() {
-    return _.uniq(_.flatten(arguments, true));
+    return _.uniq(concat.apply(ArrayProto, arguments));
   };
 
   // Produce an array that contains every item shared between all the
@@ -507,10 +469,11 @@
   // Zip together multiple lists into a single array -- elements that share
   // an index go together.
   _.zip = function() {
-    var length = _.max(_.pluck(arguments, "length").concat(0));
+    var args = slice.call(arguments);
+    var length = _.max(_.pluck(args, 'length'));
     var results = new Array(length);
     for (var i = 0; i < length; i++) {
-      results[i] = _.pluck(arguments, '' + i);
+      results[i] = _.pluck(args, "" + i);
     }
     return results;
   };
@@ -519,9 +482,8 @@
   // pairs, or two parallel arrays of the same length -- one of keys, and one of
   // the corresponding values.
   _.object = function(list, values) {
-    if (list == null) return {};
     var result = {};
-    for (var i = 0, length = list.length; i < length; i++) {
+    for (var i = 0, l = list.length; i < l; i++) {
       if (values) {
         result[list[i]] = values[i];
       } else {
@@ -538,24 +500,22 @@
   // If the array is large and already in sort order, pass `true`
   // for **isSorted** to use binary search.
   _.indexOf = function(array, item, isSorted) {
-    if (array == null) return -1;
-    var i = 0, length = array.length;
+    var i = 0, l = array.length;
     if (isSorted) {
       if (typeof isSorted == 'number') {
-        i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
+        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
       } else {
         i = _.sortedIndex(array, item);
         return array[i] === item ? i : -1;
       }
     }
     if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
-    for (; i < length; i++) if (array[i] === item) return i;
+    for (; i < l; i++) if (array[i] === item) return i;
     return -1;
   };
 
   // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
   _.lastIndexOf = function(array, item, from) {
-    if (array == null) return -1;
     var hasIndex = from != null;
     if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
       return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
@@ -575,11 +535,11 @@
     }
     step = arguments[2] || 1;
 
-    var length = Math.max(Math.ceil((stop - start) / step), 0);
+    var len = Math.max(Math.ceil((stop - start) / step), 0);
     var idx = 0;
-    var range = new Array(length);
+    var range = new Array(len);
 
-    while(idx < length) {
+    while(idx < len) {
       range[idx++] = start;
       start += step;
     }
@@ -594,38 +554,29 @@
   var ctor = function(){};
 
   // Create a function bound to a given object (assigning `this`, and arguments,
-  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
-  // available.
-  _.bind = function(func, context) {
-    var args, bound;
-    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+  // optionally). Binding with arguments is also known as `curry`.
+  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+  // We check for `func.bind` first, to fail fast when `func` is undefined.
+  _.bind = function bind(func, context) {
+    var bound, args;
+    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
     if (!_.isFunction(func)) throw new TypeError;
     args = slice.call(arguments, 2);
     return bound = function() {
       if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
       ctor.prototype = func.prototype;
       var self = new ctor;
-      ctor.prototype = null;
       var result = func.apply(self, args.concat(slice.call(arguments)));
       if (Object(result) === result) return result;
       return self;
     };
   };
 
-  // Partially apply a function by creating a version that has had some of its
-  // arguments pre-filled, without changing its dynamic `this` context.
-  _.partial = function(func) {
-    var args = slice.call(arguments, 1);
-    return function() {
-      return func.apply(this, args.concat(slice.call(arguments)));
-    };
-  };
-
   // Bind all of an object's methods to that object. Useful for ensuring that
   // all callbacks defined on an object belong to it.
   _.bindAll = function(obj) {
     var funcs = slice.call(arguments, 1);
-    if (funcs.length === 0) throw new Error("bindAll must be passed function names");
+    if (funcs.length == 0) funcs = _.functions(obj);
     each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
     return obj;
   };
@@ -654,34 +605,27 @@
   };
 
   // Returns a function, that, when invoked, will only be triggered at most once
-  // during a given window of time. Normally, the throttled function will run
-  // as much as it can, without ever going more than once per `wait` duration;
-  // but if you'd like to disable the execution on the leading edge, pass
-  // `{leading: false}`. To disable execution on the trailing edge, ditto.
-  _.throttle = function(func, wait, options) {
-    var context, args, result;
-    var timeout = null;
-    var previous = 0;
-    options || (options = {});
-    var later = function() {
-      previous = options.leading === false ? 0 : new Date;
-      timeout = null;
-      result = func.apply(context, args);
-    };
+  // during a given window of time.
+  _.throttle = function(func, wait) {
+    var context, args, timeout, throttling, more, result;
+    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
     return function() {
-      var now = new Date;
-      if (!previous && options.leading === false) previous = now;
-      var remaining = wait - (now - previous);
-      context = this;
-      args = arguments;
-      if (remaining <= 0) {
-        clearTimeout(timeout);
+      context = this; args = arguments;
+      var later = function() {
         timeout = null;
-        previous = now;
+        if (more) {
+          result = func.apply(context, args);
+        }
+        whenDone();
+      };
+      if (!timeout) timeout = setTimeout(later, wait);
+      if (throttling) {
+        more = true;
+      } else {
+        throttling = true;
         result = func.apply(context, args);
-      } else if (!timeout && options.trailing !== false) {
-        timeout = setTimeout(later, remaining);
       }
+      whenDone();
       return result;
     };
   };
@@ -691,24 +635,16 @@
   // N milliseconds. If `immediate` is passed, trigger the function on the
   // leading edge, instead of the trailing.
   _.debounce = function(func, wait, immediate) {
-    var timeout, args, context, timestamp, result;
+    var timeout, result;
     return function() {
-      context = this;
-      args = arguments;
-      timestamp = new Date();
+      var context = this, args = arguments;
       var later = function() {
-        var last = (new Date()) - timestamp;
-        if (last < wait) {
-          timeout = setTimeout(later, wait - last);
-        } else {
-          timeout = null;
-          if (!immediate) result = func.apply(context, args);
-        }
+        timeout = null;
+        if (!immediate) result = func.apply(context, args);
       };
       var callNow = immediate && !timeout;
-      if (!timeout) {
-        timeout = setTimeout(later, wait);
-      }
+      clearTimeout(timeout);
+      timeout = setTimeout(later, wait);
       if (callNow) result = func.apply(context, args);
       return result;
     };
@@ -753,6 +689,7 @@
 
   // Returns a function that will only be executed after being called N times.
   _.after = function(times, func) {
+    if (times <= 0) return func();
     return function() {
       if (--times < 1) {
         return func.apply(this, arguments);
@@ -768,39 +705,28 @@
   _.keys = nativeKeys || function(obj) {
     if (obj !== Object(obj)) throw new TypeError('Invalid object');
     var keys = [];
-    for (var key in obj) if (_.has(obj, key)) keys.push(key);
+    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
     return keys;
   };
 
   // Retrieve the values of an object's properties.
   _.values = function(obj) {
-    var keys = _.keys(obj);
-    var length = keys.length;
-    var values = new Array(length);
-    for (var i = 0; i < length; i++) {
-      values[i] = obj[keys[i]];
-    }
+    var values = [];
+    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
     return values;
   };
 
   // Convert an object into a list of `[key, value]` pairs.
   _.pairs = function(obj) {
-    var keys = _.keys(obj);
-    var length = keys.length;
-    var pairs = new Array(length);
-    for (var i = 0; i < length; i++) {
-      pairs[i] = [keys[i], obj[keys[i]]];
-    }
+    var pairs = [];
+    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
     return pairs;
   };
 
   // Invert the keys and values of an object. The values must be serializable.
   _.invert = function(obj) {
     var result = {};
-    var keys = _.keys(obj);
-    for (var i = 0, length = keys.length; i < length; i++) {
-      result[obj[keys[i]]] = keys[i];
-    }
+    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
     return result;
   };
 
@@ -817,10 +743,8 @@
   // Extend a given object with all the properties in passed-in object(s).
   _.extend = function(obj) {
     each(slice.call(arguments, 1), function(source) {
-      if (source) {
-        for (var prop in source) {
-          obj[prop] = source[prop];
-        }
+      for (var prop in source) {
+        obj[prop] = source[prop];
       }
     });
     return obj;
@@ -849,10 +773,8 @@
   // Fill in a given object with default properties.
   _.defaults = function(obj) {
     each(slice.call(arguments, 1), function(source) {
-      if (source) {
-        for (var prop in source) {
-          if (obj[prop] === void 0) obj[prop] = source[prop];
-        }
+      for (var prop in source) {
+        if (obj[prop] == null) obj[prop] = source[prop];
       }
     });
     return obj;
@@ -875,7 +797,7 @@
   // Internal recursive comparison function for `isEqual`.
   var eq = function(a, b, aStack, bStack) {
     // Identical objects are equal. `0 === -0`, but they aren't identical.
-    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
     if (a === b) return a !== 0 || 1 / a == 1 / b;
     // A strict comparison is necessary because `null == undefined`.
     if (a == null || b == null) return a === b;
@@ -917,13 +839,6 @@
       // unique nested structures.
       if (aStack[length] == a) return bStack[length] == b;
     }
-    // Objects with different constructors are not equivalent, but `Object`s
-    // from different frames are.
-    var aCtor = a.constructor, bCtor = b.constructor;
-    if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
-                             _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
-      return false;
-    }
     // Add the first object to the stack of traversed objects.
     aStack.push(a);
     bStack.push(b);
@@ -940,6 +855,13 @@
         }
       }
     } else {
+      // Objects with different constructors are not equivalent, but `Object`s
+      // from different frames are.
+      var aCtor = a.constructor, bCtor = b.constructor;
+      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
+        return false;
+      }
       // Deep compare objects.
       for (var key in a) {
         if (_.has(a, key)) {
@@ -1017,7 +939,7 @@
 
   // Is a given object a finite number?
   _.isFinite = function(obj) {
-    return isFinite(obj) && !isNaN(parseFloat(obj));
+    return _.isNumber(obj) && isFinite(obj);
   };
 
   // Is the given value `NaN`? (NaN is the only number which does not equal itself).
@@ -1063,9 +985,7 @@
 
   // Run a function **n** times.
   _.times = function(n, iterator, context) {
-    var accum = Array(Math.max(0, n));
-    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
-    return accum;
+    for (var i = 0; i < n; i++) iterator.call(context, i);
   };
 
   // Return a random integer between min and max (inclusive).
@@ -1074,7 +994,7 @@
       max = min;
       min = 0;
     }
-    return min + Math.floor(Math.random() * (max - min + 1));
+    return min + (0 | Math.random() * (max - min + 1));
   };
 
   // List of HTML entities for escaping.
@@ -1084,7 +1004,8 @@
       '<': '&lt;',
       '>': '&gt;',
       '"': '&quot;',
-      "'": '&#x27;'
+      "'": '&#x27;',
+      '/': '&#x2F;'
     }
   };
   entityMap.unescape = _.invert(entityMap.escape);
@@ -1105,17 +1026,17 @@
     };
   });
 
-  // If the value of the named `property` is a function then invoke it with the
-  // `object` as context; otherwise, return it.
+  // If the value of the named property is a function then invoke it;
+  // otherwise, return it.
   _.result = function(object, property) {
-    if (object == null) return void 0;
+    if (object == null) return null;
     var value = object[property];
     return _.isFunction(value) ? value.call(object) : value;
   };
 
   // Add your own custom functions to the Underscore object.
   _.mixin = function(obj) {
-    each(_.functions(obj), function(name) {
+    each(_.functions(obj), function(name){
       var func = _[name] = obj[name];
       _.prototype[name] = function() {
         var args = [this._wrapped];
@@ -1129,7 +1050,7 @@
   // Useful for temporary DOM ids.
   var idCounter = 0;
   _.uniqueId = function(prefix) {
-    var id = ++idCounter + '';
+    var id = idCounter++;
     return prefix ? prefix + id : id;
   };
 
@@ -1164,7 +1085,6 @@
   // Underscore templating handles arbitrary delimiters, preserves whitespace,
   // and correctly escapes quotes within interpolated code.
   _.template = function(text, data, settings) {
-    var render;
     settings = _.defaults({}, settings, _.templateSettings);
 
     // Combine delimiters into one regular expression via alternation.
@@ -1180,18 +1100,11 @@
     text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
       source += text.slice(index, offset)
         .replace(escaper, function(match) { return '\\' + escapes[match]; });
-
-      if (escape) {
-        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-      }
-      if (interpolate) {
-        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-      }
-      if (evaluate) {
-        source += "';\n" + evaluate + "\n__p+='";
-      }
+      source +=
+        escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
+        interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
+        evaluate ? "';\n" + evaluate + "\n__p+='" : '';
       index = offset + match.length;
-      return match;
     });
     source += "';\n";
 
@@ -1203,7 +1116,7 @@
       source + "return __p;\n";
 
     try {
-      render = new Function(settings.variable || 'obj', '_', source);
+      var render = new Function(settings.variable || 'obj', '_', source);
     } catch (e) {
       e.source = source;
       throw e;
diff --git a/core/core.services.yml b/core/core.services.yml
index 69e3ef2..a2d373c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -107,7 +107,7 @@ services:
     class: Drupal\Core\Config\InstallStorage
   config.typed:
     class: Drupal\Core\Config\TypedConfigManager
-    arguments: ['@config.storage', '@config.storage.schema', '@cache.config']
+    arguments: ['@config.storage', '@config.storage.schema']
   database:
     class: Drupal\Core\Database\Connection
     factory_class: Drupal\Core\Database\Database
@@ -286,7 +286,7 @@ services:
       - { name: persist }
   link_generator:
     class: Drupal\Core\Utility\LinkGenerator
-    arguments: ['@url_generator', '@module_handler', '@language_manager', '@path.alias_manager.cached']
+    arguments: ['@url_generator', '@module_handler', '@language_manager']
     calls:
       - [setRequest, ['@?request']]
   router.dynamic:
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 1568f45..91d12af 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -138,19 +138,24 @@
 const DRUPAL_BOOTSTRAP_PAGE_CACHE = 2;
 
 /**
- * Fourth bootstrap phase: initialize the variable system.
+ * Fourth bootstrap phase: initialize database layer.
  */
-const DRUPAL_BOOTSTRAP_VARIABLES = 3;
+const DRUPAL_BOOTSTRAP_DATABASE = 3;
 
 /**
- * Fifth bootstrap phase: load code for subsystems and modules.
+ * Fifth bootstrap phase: initialize the variable system.
  */
-const DRUPAL_BOOTSTRAP_CODE = 4;
+const DRUPAL_BOOTSTRAP_VARIABLES = 4;
+
+/**
+ * Sixth bootstrap phase: load code for subsystems and modules.
+ */
+const DRUPAL_BOOTSTRAP_CODE = 5;
 
 /**
  * Final bootstrap phase: initialize language, path, theme, and modules.
  */
-const DRUPAL_BOOTSTRAP_FULL = 5;
+const DRUPAL_BOOTSTRAP_FULL = 6;
 
 /**
  * Role ID for anonymous users; should match what's in the "role" table.
@@ -1743,6 +1748,7 @@ function drupal_anonymous_user() {
  *   - DRUPAL_BOOTSTRAP_CONFIGURATION: Initializes configuration.
  *   - DRUPAL_BOOTSTRAP_KERNEL: Initalizes a kernel.
  *   - DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to serve a cached page.
+ *   - DRUPAL_BOOTSTRAP_DATABASE: Initializes the database layer.
  *   - DRUPAL_BOOTSTRAP_VARIABLES: Initializes the variable system.
  *   - DRUPAL_BOOTSTRAP_CODE: Loads code for subsystems and modules.
  *   - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
@@ -1760,6 +1766,7 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
     DRUPAL_BOOTSTRAP_CONFIGURATION,
     DRUPAL_BOOTSTRAP_KERNEL,
     DRUPAL_BOOTSTRAP_PAGE_CACHE,
+    DRUPAL_BOOTSTRAP_DATABASE,
     DRUPAL_BOOTSTRAP_VARIABLES,
     DRUPAL_BOOTSTRAP_CODE,
     DRUPAL_BOOTSTRAP_FULL,
@@ -1802,6 +1809,10 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
           _drupal_bootstrap_page_cache();
           break;
 
+        case DRUPAL_BOOTSTRAP_DATABASE:
+          _drupal_bootstrap_database();
+          break;
+
         case DRUPAL_BOOTSTRAP_VARIABLES:
           _drupal_bootstrap_variables();
           break;
@@ -2004,7 +2015,6 @@ function _drupal_bootstrap_page_cache() {
   global $user;
 
   require_once __DIR__ . '/cache.inc';
-  require_once __DIR__ . '/database.inc';
   // Check for a cache mode force from settings.php.
   if (settings()->get('page_cache_without_database')) {
     $cache_enabled = TRUE;
@@ -2079,6 +2089,15 @@ function _drupal_initialize_db_test_prefix() {
 }
 
 /**
+ * Initializes the database system by loading database.inc.
+ */
+function _drupal_bootstrap_database() {
+  // Initialize the database system. Note that the connection
+  // won't be initialized until it is actually requested.
+  require_once __DIR__ . '/database.inc';
+}
+
+/**
  * Loads system variables and all enabled bootstrap modules.
  */
 function _drupal_bootstrap_variables() {
diff --git a/core/includes/common.inc b/core/includes/common.inc
index db03ed9..aff7665 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1214,24 +1214,12 @@ function drupal_http_header_attributes(array $attributes = array()) {
  *     internal to the site, $options['language'] is used to determine whether
  *     the link is "active", or pointing to the current page (the language as
  *     well as the path must match). This element is also used by url().
- *   - 'set_active_class' (default FALSE): Whether l() should compare the $path,
- *     language and query options to the current URL to determine whether the
- *     link is "active". If so, an "active" class will be applied to the link.
- *     It is important to use this sparingly since it is usually unnecessary and
- *     requires extra processing.
- *     For anonymous users, the "active" class will be calculated on the server,
- *     because most sites serve each anonymous user the same cached page anyway.
- *     For authenticated users, the "active" class will be calculated on the
- *     client (through JavaScript), only data- attributes are added to links to
- *     prevent breaking the render cache. The JavaScript is added in
- *     system_page_build().
  *   - Additional $options elements used by the url() function.
  *
  * @return string
  *   An HTML string containing a link to the given path.
  *
  * @see url()
- * @see system_page_build()
  */
 function l($text, $path, array $options = array()) {
   // Start building a structured representation of our link to be altered later.
@@ -1247,7 +1235,6 @@ function l($text, $path, array $options = array()) {
     'query' => array(),
     'html' => FALSE,
     'language' => NULL,
-    'set_active_class' => FALSE,
   );
 
   // Add a hreflang attribute if we know the language of this link's url and
@@ -1256,21 +1243,35 @@ function l($text, $path, array $options = array()) {
     $variables['options']['attributes']['hreflang'] = $variables['options']['language']->id;
   }
 
-  // Set the "active" class if the 'set_active_class' option is not empty.
-  if (!empty($variables['options']['set_active_class'])) {
-    // Add a "data-drupal-link-query" attribute to let the drupal.active-link
-    // library know the query in a standardized manner.
-    if (!empty($variables['options']['query'])) {
-      $query = $variables['options']['query'];
-      ksort($query);
-      $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query);
-    }
+  // Because l() is called very often we statically cache values that require an
+  // extra function call.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast['active'])) {
+    $drupal_static_fast['active'] = &drupal_static(__FUNCTION__);
+  }
+  $active = &$drupal_static_fast['active'];
+  if (!isset($active)) {
+    $active = array(
+      'path' => current_path(),
+      'front_page' => drupal_is_front_page(),
+      'language' => language(Language::TYPE_URL)->id,
+      'query' => \Drupal::service('request')->query->all(),
+    );
+  }
 
-    // Add a "data-drupal-link-system-path" attribute to let the
-    // drupal.active-link library know the path in a standardized manner.
-    if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) {
-      $variables['options']['attributes']['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($path);
-    }
+  // Determine whether this link is "active', meaning that it links to the
+  // current page. It is important that we stop checking "active" conditions if
+  // we know the link is not active. This helps ensure that l() remains fast.
+  // An active link's path is equal to the current path.
+  $variables['url_is_active'] = ($path == $active['path'] || ($path == '<front>' && $active['front_page']))
+  // The language of an active link is equal to the current language.
+  && (empty($variables['options']['language']) || $variables['options']['language']->id == $active['language'])
+  // The query parameters of an active link are equal to the current parameters.
+  && ($variables['options']['query'] == $active['query']);
+
+  // Add the "active" class if appropriate.
+  if ($variables['url_is_active']) {
+    $variables['options']['attributes']['class'][] = 'active';
   }
 
   // Remove all HTML and PHP tags from a tooltip, calling expensive strip_tags()
@@ -2148,7 +2149,6 @@ function drupal_add_js($data = NULL, $options = NULL) {
           // @todo Make this less hacky: http://drupal.org/node/1547376.
           $scriptPath = $GLOBALS['script_path'];
           $pathPrefix = '';
-          $current_query = \Drupal::service('request')->query->all();
           url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
           $current_path = current_path();
           $current_path_is_admin = FALSE;
@@ -2156,20 +2156,13 @@ function drupal_add_js($data = NULL, $options = NULL) {
           if (!(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE === 'update')) {
             $current_path_is_admin = path_is_admin($current_path);
           }
-          $path = array(
+          $javascript['settings']['data'][] = array(
             'basePath' => base_path(),
             'scriptPath' => $scriptPath,
             'pathPrefix' => $pathPrefix,
             'currentPath' => $current_path,
             'currentPathIsAdmin' => $current_path_is_admin,
-            'isFront' => drupal_is_front_page(),
-            'currentLanguage' => \Drupal::languageManager()->getLanguage(Language::TYPE_URL)->id,
           );
-          if (!empty($current_query)) {
-            ksort($current_query);
-            $path['currentQuery'] = (object) $current_query;
-          }
-          $javascript['settings']['data'][] = array('path' => $path);
         }
         // All JavaScript settings are placed in the header of the page with
         // the library weight so that inline scripts appear afterwards.
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 5594343..b44c59a 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -390,8 +390,7 @@ function install_begin_request(&$install_state) {
 
     $container->register('config.typed', 'Drupal\Core\Config\TypedConfigManager')
       ->addArgument(new Reference('config.storage'))
-      ->addArgument(new Reference('config.storage.schema'))
-      ->addArgument(new Reference('cache.config'));
+      ->addArgument(new Reference('config.storage.schema'));
 
     $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
       ->addArgument(new Reference('config.storage'))
@@ -2104,13 +2103,12 @@ function install_configure_form($form, &$form_state, &$install_state) {
     drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning');
   }
 
-  $form['#attached']['library'][] = array('system', 'drupal.system');
+  drupal_add_library('system', 'drupal.system');
   // Add JavaScript time zone detection.
-  $form['#attached']['library'][] = array('system', 'drupal.timezone');
+  drupal_add_library('system', 'drupal.timezone');
   // We add these strings as settings because JavaScript translation does not
   // work during installation.
-  $js = array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail')));
-  $form['#attached']['js'][] = array('data' => $js, 'type' => 'setting');
+  drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting');
 
   // Cache a fully-built schema. This is necessary for any invocation of
   // index.php because: (1) setting cache table entries requires schema
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 208ef9b..856c424 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1704,7 +1704,6 @@ function theme_menu_link(array $variables) {
   if ($element['#below']) {
     $sub_menu = drupal_render($element['#below']);
   }
-  $element['#localized_options']['set_active_class'] = TRUE;
   $output = l($element['#title'], $element['#href'], $element['#localized_options']);
   return '<li' . new Attribute($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
 }
@@ -1740,8 +1739,6 @@ function theme_menu_local_task($variables) {
     $link['localized_options']['html'] = TRUE;
     $link_text = t('!local-task-title!active', array('!local-task-title' => $link['title'], '!active' => $active));
   }
-  $link['localized_options']['set_active_class'] = TRUE;
-
   if (!empty($link['href'])) {
     // @todo - remove this once all pages are converted to routes.
     $a_tag = l($link_text, $link['href'], $link['localized_options']);
@@ -1773,7 +1770,6 @@ function theme_menu_local_action($variables) {
   );
   $link['localized_options']['attributes']['class'][] = 'button';
   $link['localized_options']['attributes']['class'][] = 'button-action';
-  $link['localized_options']['set_active_class'] = TRUE;
 
   $output = '<li>';
   // @todo Remove this check and the call to l() when all pages are converted to
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 65349a3..3db84a9 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -91,6 +91,7 @@ function drupal_theme_initialize() {
     return;
   }
 
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
   $themes = list_themes();
 
   // @todo Let the theme.negotiator listen to the kernel request event.
@@ -236,15 +237,9 @@ function _drupal_theme_initialize($theme, $base_theme = array()) {
   }
 
   // Add scripts used by this theme.
-  $js = array();
   foreach ($final_scripts as $script) {
-    $js['#attached']['js'][] = array(
-      'data' => $script,
-      'group' => JS_THEME,
-      'every_page' => TRUE,
-    );
+    drupal_add_js($script, array('group' => JS_THEME, 'every_page' => TRUE));
   }
-  drupal_render($js);
 
   $theme_engine = NULL;
 
@@ -1188,18 +1183,6 @@ function template_preprocess_status_messages(&$variables) {
  *     l() as its $options parameter.
  *   - attributes: A keyed array of attributes for the UL containing the
  *     list of links.
- *   - set_active_class: (optional) Whether theme_links() should compare the
- *     route_name + route_parameters or href (path), language and query options
- *     to the current URL for each of the links, to determine whether the link
- *     is "active". If so, an "active" class will be applied to the list item
- *     containing the link. It is important to use this sparingly since it is
- *     usually unnecessary and requires extra processing.
- *     For anonymous users, the "active" class will be calculated on the server,
- *     because most sites serve each anonymous user the same cached page anyway.
- *     For authenticated users, the "active" class will be calculated on the
- *     client (through JavaScript), only data- attributes are added to list
- *     items to prevent breaking the render cache. The JavaScript is added in
- *     system_page_build().
  *   - heading: (optional) A heading to precede the links. May be an
  *     associative array or a string. If it's an array, it can have the
  *     following elements:
@@ -1215,19 +1198,6 @@ function template_preprocess_status_messages(&$variables) {
  *     navigate to or skip the links. See
  *     http://juicystudio.com/article/screen-readers-display-none.php and
  *     http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
- *
- * theme_links() unfortunately duplicates the "active" class handling of l() and
- * LinkGenerator::generate() because it needs to be able to set the "active"
- * class not on the links themselves ("a" tags), but on the list items ("li"
- * tags) that contain the links. This is necessary for CSS to be able to style
- * list items differently when the link is active, since CSS does not yet allow
- * one to style list items only if it contains a certain element with a certain
- * class. I.e. we cannot yet convert this jQuery selector to a CSS selector:
- *   jQuery('li:has("a.active")')
- *
- * @see l()
- * @see \Drupal\Core\Utility\LinkGenerator::generate()
- * @see system_page_build()
  */
 function theme_links($variables) {
   $links = $variables['links'];
@@ -1261,7 +1231,8 @@ function theme_links($variables) {
 
     $num_links = count($links);
     $i = 0;
-    $active_route = \Drupal::linkGenerator()->getActive();
+    $active = \Drupal::linkGenerator()->getActive();
+    $language_url = \Drupal::languageManager()->getLanguage(Language::TYPE_URL);
 
     foreach ($links as $key => $link) {
       $i++;
@@ -1273,16 +1244,16 @@ function theme_links($variables) {
         'ajax' => NULL,
       );
 
-      $li_attributes = array('class' => array());
+      $class = array();
       // Use the array key as class name.
-      $li_attributes['class'][] = drupal_html_class($key);
+      $class[] = drupal_html_class($key);
       // Add odd/even, first, and last classes.
-      $li_attributes['class'][] = ($i % 2 ? 'odd' : 'even');
+      $class[] = ($i % 2 ? 'odd' : 'even');
       if ($i == 1) {
-        $li_attributes['class'][] = 'first';
+        $class[] = 'first';
       }
       if ($i == $num_links) {
-        $li_attributes['class'][] = 'last';
+        $class[] = 'last';
       }
 
       $link_element = array(
@@ -1295,36 +1266,32 @@ function theme_links($variables) {
         '#ajax' => $link['ajax'],
       );
 
-      // Handle links and ensure that the active class is added on the LIs, but
-      // only if the 'set_active_class' option is not empty.
-      if (isset($link['href']) || isset($link['route_name'])) {
-        if (!empty($variables['set_active_class'])) {
-          if (!empty($link['language'])) {
-            $li_attributes['hreflang'] = $link['language']->id;
-          }
-
-          // Add a "data-drupal-link-query" attribute to let the
-          // drupal.active-link library know the query in a standardized manner.
-          if (!empty($link['query'])) {
-            $query = $link['query'];
-            ksort($query);
-            $li_attributes['data-drupal-link-query'] = Json::encode($query);
-          }
-
-          if (isset($link['route_name'])) {
-            $path = \Drupal::service('url_generator')->getPathFromRoute($link['route_name'], $link['route_parameters']);
-          }
-          else {
-            $path = $link['href'];
-          }
+      // Handle links and ensure that the active class is added on the LIs.
+      if (isset($link['route_name'])) {
+        $variables = array(
+          'options' => array(),
+        );
+        if (!empty($link['language'])) {
+          $variables['options']['language'] = $link['language'];
+        }
 
-          // Add a "data-drupal-link-system-path" attribute to let the
-          // drupal.active-link library know the path in a standardized manner.
-          $li_attributes['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($path);
+        if (($link['route_name'] == $active['route_name'])
+        // The language of an active link is equal to the current language.
+        && (empty($variables['options']['language']) || ($variables['options']['language']->id == $active['language']))
+        && ($link['route_parameters'] == $active['parameters'])) {
+          $class[] = 'active';
         }
 
         $item = drupal_render($link_element);
       }
+      elseif (isset($link['href'])) {
+        $is_current_path = ($link['href'] == current_path() || ($link['href'] == '<front>' && drupal_is_front_page()));
+        $is_current_language = (empty($link['language']) || $link['language']->id == $language_url->id);
+        if ($is_current_path && $is_current_language) {
+          $class[] = 'active';
+        }
+        $item = drupal_render($link_element);
+      }
       // Handle title-only text items.
       else {
         // Merge in default array properties into $link.
@@ -1337,7 +1304,7 @@ function theme_links($variables) {
         }
       }
 
-      $output .= '<li' . new Attribute($li_attributes) . '>';
+      $output .= '<li' . new Attribute(array('class' => $class)) . '>';
       $output .= $item;
       $output .= '</li>';
     }
@@ -2271,8 +2238,7 @@ function template_preprocess_page(&$variables) {
       '#heading' => array(
         'text' => t('Main menu'),
         'class' => array('visually-hidden'),
-      ),
-      '#set_active_class' => TRUE,
+      )
     );
   }
   if (!empty($variables['secondary_menu'])) {
@@ -2282,8 +2248,7 @@ function template_preprocess_page(&$variables) {
       '#heading' => array(
         'text' => t('Secondary menu'),
         'class' => array('visually-hidden'),
-      ),
-      '#set_active_class' => TRUE,
+      )
     );
   }
 
@@ -2613,7 +2578,7 @@ function drupal_common_theme() {
       'template' => 'status-messages',
     ),
     'links' => array(
-      'variables' => array('links' => array(), 'attributes' => array('class' => array('links')), 'heading' => array(), 'set_active_class' => FALSE),
+      'variables' => array('links' => array(), 'attributes' => array('class' => array('links')), 'heading' => array()),
     ),
     'dropbutton_wrapper' => array(
       'variables' => array('children' => NULL),
diff --git a/core/includes/update.inc b/core/includes/update.inc
index b17624f..73f9b7f 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -142,7 +142,7 @@ function update_prepare_d8_bootstrap() {
   }
 
   // Bootstrap the database.
-  require_once __DIR__ . '/database.inc';
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
 
   // module.inc is not yet loaded but there are calls to module_config_sort()
   // below.
diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php
index ea008bd..6d101c2 100644
--- a/core/lib/Drupal/Component/Utility/Crypt.php
+++ b/core/lib/Drupal/Component/Utility/Crypt.php
@@ -71,25 +71,21 @@ public static function randomBytes($count) {
   /**
    * Calculates a base-64 encoded, URL-safe sha-256 hmac.
    *
-   * @param mixed $data
-   *   Scalar value to be validated with the hmac.
-   * @param mixed $key
-   *   A secret key, this can be any scalar value.
+   * @param string $data
+   *   String to be validated with the hmac.
+   * @param string $key
+   *   A secret string key.
    *
    * @return string
    *   A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
    *   any = padding characters removed.
    */
   public static function hmacBase64($data, $key) {
-    // $data and $key being strings here is necessary to avoid empty string
+    // Casting $data and $key to strings here is necessary to avoid empty string
     // results of the hash function if they are not scalar values. As this
-    // function is used in security-critical contexts like token validation it
-    // is important that it never returns an empty string.
-    if (!is_scalar($data) || !is_scalar($key)) {
-      throw new \InvalidArgumentException('Both parameters passed to \Drupal\Component\Utility\Crypt::hmacBase64 must be scalar values.');
-    }
-
-    $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
+    // function is used in security-critical contexts like token validation it is
+    // important that it never returns an empty string.
+    $hmac = base64_encode(hash_hmac('sha256', (string) $data, (string) $key, TRUE));
     // Modify the hmac so it's safe to use in URLs.
     return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
   }
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index e026717..f04bbe0 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -11,7 +11,6 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Config\ConfigNameException;
 use Drupal\Core\Config\Context\ContextInterface;
-use Drupal\Core\Config\Schema\SchemaIncompleteException;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
 use Drupal\Core\TypedData\Type\IntegerInterface;
@@ -518,6 +517,37 @@ protected function getSchemaWrapper() {
   }
 
   /**
+   * Gets the definition for the configuration key.
+   *
+   * @param string $key
+   *   A string that maps to a key within the configuration data.
+   *
+   * @return \Drupal\Core\Config\Schema\Element
+   *
+   * @throws \Drupal\Core\Config\ConfigException
+   *   Thrown when schema is incomplete.
+   */
+  protected function getSchemaForKey($key) {
+    $parts = explode('.', $key);
+    $schema_wrapper = $this->getSchemaWrapper();
+    if (count($parts) == 1) {
+      $schema = $schema_wrapper->get($key);
+    }
+    else {
+      $schema = clone $schema_wrapper;
+      foreach ($parts as $nested_key) {
+        if (!is_object($schema) || !method_exists($schema, 'get')) {
+          throw new ConfigException(String::format("Incomplete schema for !key key in configuration object !name.", array('!name' => $this->name, '!key' => $key)));
+        }
+        else {
+          $schema = $schema->get($nested_key);
+        }
+      }
+    }
+    return $schema;
+  }
+
+  /**
    * Casts the value to correct data type using the configuration schema.
    *
    * @param string $key
@@ -534,7 +564,7 @@ protected function castValue($key, $value) {
     }
     elseif (is_scalar($value)) {
       try {
-        $element = $this->getSchemaWrapper()->get($key);
+        $element = $this->getSchemaForKey($key);
         if ($element instanceof PrimitiveInterface) {
           // Special handling for integers and floats since the configuration
           // system is primarily concerned with saving values from the Form API
@@ -556,7 +586,7 @@ protected function castValue($key, $value) {
           $value = $element->getString();
         }
       }
-      catch (SchemaIncompleteException $e) {
+      catch (\Exception $e) {
         // @todo throw an exception due to an incomplete schema. Only possible
         //   once https://drupal.org/node/1910624 is complete.
       }
diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index dd5b9bb..66f51e4 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -263,9 +263,6 @@ public function import() {
    */
   public function validate() {
     if (!$this->validated) {
-      if (!$this->storageComparer->validateSiteUuid()) {
-        throw new ConfigImporterException('Site UUID in source storage does not match the target storage.');
-      }
       $this->notify('validate');
       $this->validated = TRUE;
     }
diff --git a/core/lib/Drupal/Core/Config/Schema/Mapping.php b/core/lib/Drupal/Core/Config/Schema/Mapping.php
index 256076f..92e9a90 100644
--- a/core/lib/Drupal/Core/Config/Schema/Mapping.php
+++ b/core/lib/Drupal/Core/Config/Schema/Mapping.php
@@ -7,8 +7,10 @@
 
 namespace Drupal\Core\Config\Schema;
 
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\TypedData\ComplexDataInterface;
-use Drupal\Component\Utility\String;
+use Drupal\Core\TypedData\TypedDataInterface;
+use \InvalidArgumentException;
 
 /**
  * Defines a mapping configuration element.
@@ -34,29 +36,17 @@ protected function parse() {
 
   /**
    * Implements Drupal\Core\TypedData\ComplexDataInterface::get().
-   *
-   * Since all configuration objects are mappings the function will except a dot
-   * delimited key to access nested values, for example, 'page.front'.
    */
   public function get($property_name) {
-    $parts = explode('.', $property_name);
-    $root_key = array_shift($parts);
     $elements = $this->getElements();
-    if (isset($elements[$root_key])) {
-      $element = $elements[$root_key];
+    if (isset($elements[$property_name])) {
+      return $elements[$property_name];
     }
     else {
-      throw new SchemaIncompleteException(String::format("The configuration property @key doesn't exist.", array('@key' => $property_name)));
+      throw new InvalidArgumentException(format_string("The configuration property @key doesn't exist.", array(
+          '@key' => $property_name,
+      )));
     }
-
-    // If $property_name contained a dot recurse into the keys.
-    foreach ($parts as $key) {
-     if (!is_object($element) || !method_exists($element, 'get')) {
-        throw new SchemaIncompleteException(String::format("The configuration property @key does not exist.", array('@key' => $property_name)));
-      }
-      $element = $element->get($key);
-    }
-    return $element;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php b/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php
deleted file mode 100644
index 34a458e..0000000
--- a/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Config\Schema\SchemaIncompleteException.
- */
-
-namespace Drupal\Core\Config\Schema;
-
-/**
- * An exception thrown when a config schema is incomplete.
- */
-class SchemaIncompleteException extends \RuntimeException {
-}
diff --git a/core/lib/Drupal/Core/Config/Schema/Sequence.php b/core/lib/Drupal/Core/Config/Schema/Sequence.php
index 6333349..44dbe1d 100644
--- a/core/lib/Drupal/Core/Config/Schema/Sequence.php
+++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
@@ -18,7 +18,7 @@ class Sequence extends ArrayElement implements ListInterface {
    * Overrides ArrayElement::parse()
    */
   protected function parse() {
-    $definition = $this->getItemDefinition();
+    $definition = $definition = $this->getItemDefinition();
     $elements = array();
     foreach ($this->value as $key => $value) {
       $elements[$key] = $this->parseElement($key, $value, $definition);
@@ -60,7 +60,7 @@ public function onChange($delta) {
    *   Typed configuration element.
    */
   public function get($key) {
-    $elements = $this->getElements();
+    $elements = $this->parse();
     return $elements[$key];
   }
 
diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php
index c08cb5a..834f439 100644
--- a/core/lib/Drupal/Core/Config/StorageComparer.php
+++ b/core/lib/Drupal/Core/Config/StorageComparer.php
@@ -195,13 +195,4 @@ protected function getTargetNames() {
     return $this->targetNames;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function validateSiteUuid() {
-    $source = $this->sourceStorage->read('system.site');
-    $target = $this->targetStorage->read('system.site');
-    return $source['uuid'] === $target['uuid'];
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Config/StorageComparerInterface.php b/core/lib/Drupal/Core/Config/StorageComparerInterface.php
index 0f62d0c..5ca0f3e 100644
--- a/core/lib/Drupal/Core/Config/StorageComparerInterface.php
+++ b/core/lib/Drupal/Core/Config/StorageComparerInterface.php
@@ -117,12 +117,4 @@ public function reset();
    */
   public function hasChanges($ops = array('delete', 'create', 'update'));
 
-  /**
-   * Validates that the system.site::uuid in the source and target match.
-   *
-   * @return bool
-   *   TRUE if identical, FALSE if not.
-   */
-  public function validateSiteUuid();
-
 }
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index 09ec0c5..71aa0bc 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -11,7 +11,7 @@
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\String;
-use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\TypedConfigManagerInterface;
 
 /**
  * Manages config type plugins.
@@ -19,13 +19,6 @@
 class TypedConfigManager extends PluginManagerBase implements TypedConfigManagerInterface {
 
   /**
-   * The cache ID for the definitions.
-   *
-   * @var string
-   */
-  const CACHE_ID = 'typed_config_definitions';
-
-  /**
    * A storage controller instance for reading configuration data.
    *
    * @var \Drupal\Core\Config\StorageInterface
@@ -47,26 +40,16 @@ class TypedConfigManager extends PluginManagerBase implements TypedConfigManager
   protected $definitions;
 
   /**
-   * Cache backend for the definitions.
-   *
-   * @var \Drupal\Core\Cache\CacheBackendInterface
-   */
-  protected $cache;
-
-  /**
    * Creates a new typed configuration manager.
    *
    * @param \Drupal\Core\Config\StorageInterface $configStorage
    *   The storage controller object to use for reading schema data
    * @param \Drupal\Core\Config\StorageInterface $schemaStorage
    *   The storage controller object to use for reading schema data
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
-   *   The cache backend to use for caching the definitions.
    */
-  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache) {
+  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage) {
     $this->configStorage = $configStorage;
     $this->schemaStorage = $schemaStorage;
-    $this->cache = $cache;
   }
 
   /**
@@ -174,35 +157,23 @@ public function getDefinition($base_plugin_id) {
   }
 
   /**
-   * {@inheritdoc}
+   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
     if (!isset($this->definitions)) {
-      if ($cache = $this->cache->get($this::CACHE_ID)) {
-        $this->definitions = $cache->data;
-      }
-      else {
-        $this->definitions = array();
-        foreach ($this->schemaStorage->readMultiple($this->schemaStorage->listAll()) as $schema) {
+      $this->definitions = array();
+      foreach ($this->schemaStorage->listAll() as $name) {
+        if ($schema = $this->schemaStorage->read($name)) {
           foreach ($schema as $type => $definition) {
             $this->definitions[$type] = $definition;
           }
         }
-        $this->cache->set($this::CACHE_ID, $this->definitions);
       }
     }
     return $this->definitions;
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function clearCachedDefinitions() {
-    $this->definitions = NULL;
-    $this->cache->delete($this::CACHE_ID);
-  }
-
-  /**
    * Gets fallback metadata name.
    *
    * @param string $name
diff --git a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
index 2c27ccb..4e875df 100644
--- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
@@ -26,6 +26,14 @@ class EntityType extends Plugin {
   public $entity_type_class = 'Drupal\Core\Entity\EntityType';
 
   /**
+   * @todo content_translation_entity_info_alter() uses this but it is
+   *   undocumented. Fix in https://drupal.org/node/1968970.
+   *
+   * @var array
+   */
+  public $translation = array();
+
+  /**
    * {@inheritdoc}
    */
   public function get() {
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 9d502d2..7c68f0a 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -333,27 +333,14 @@ protected function clearTranslationCache() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function __sleep() {
-    // Get the values of instantiated field objects, only serialize the values.
-    foreach ($this->fields as $name => $fields) {
-      foreach ($fields as $langcode => $field) {
-        $this->values[$name][$langcode] = $field->getValue();
-      }
-    }
-    $this->fields = array();
-    $this->fieldDefinitions = NULL;
-    $this->clearTranslationCache();
-    return array_keys(get_object_vars($this));
-  }
-
-
-  /**
    * Magic __wakeup() implementation.
    */
   public function __wakeup() {
     $this->init();
+    // @todo This should be done before serializing the entity, but we would
+    //   need to provide the full list of data to be serialized. See the
+    //   dedicated issue at https://drupal.org/node/2027795.
+    $this->clearTranslationCache();
   }
 
   /**
@@ -958,14 +945,17 @@ public function __clone() {
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides Entity::label() to access the label field with the new API.
    */
-  public function label() {
+  public function label($langcode = NULL) {
     $label = NULL;
     $entity_info = $this->entityInfo();
+    if (!isset($langcode)) {
+      $langcode = $this->activeLangcode;
+    }
     // @todo Convert to is_callable() and call_user_func().
     if (($label_callback = $entity_info->getLabelCallback()) && function_exists($label_callback)) {
-      $label = $label_callback($this);
+      $label = $label_callback($this, $langcode);
     }
     elseif (($label_key = $entity_info->getKey('label')) && isset($this->{$label_key})) {
       $label = $this->{$label_key}->value;
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 2e4a7ea..178fe51 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -106,12 +106,12 @@ public function bundle() {
   /**
    * {@inheritdoc}
    */
-  public function label() {
+  public function label($langcode = NULL) {
     $label = NULL;
     $entity_info = $this->entityInfo();
     // @todo Convert to is_callable() and call_user_func().
     if (($label_callback = $entity_info->getLabelCallback()) && function_exists($label_callback)) {
-      $label = $label_callback($this);
+      $label = $label_callback($this, $langcode);
     }
     elseif (($label_key = $entity_info->getKey('label')) && isset($this->{$label_key})) {
       $label = $this->{$label_key};
diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php
index b9f1d5e..66ed701 100644
--- a/core/lib/Drupal/Core/Entity/EntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityInterface.php
@@ -89,10 +89,15 @@ public function bundle();
   /**
    * Returns the label of the entity.
    *
+   * @param $langcode
+   *   (optional) The language code of the language that should be used for
+   *   getting the label. If set to NULL, the entity's active language is
+   *   used.
+   *
    * @return
    *   The label of the entity, or NULL if there is no label defined.
    */
-  public function label();
+  public function label($langcode = NULL);
 
   /**
    * Returns the URI elements of the entity.
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 4cb05aa..9a121d3 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -9,11 +9,6 @@
 
 /**
  * Provides an interface for an entity type and its metadata.
- *
- * Additional information can be provided by modules: hook_entity_info() can be
- * implemented to define new properties, while hook_entity_info_alter() can be
- * implemented to alter existing data and fill-in defaults. Module-specific
- * properties should be documented in the hook implementations defining them.
  */
 interface EntityTypeInterface {
 
@@ -198,6 +193,9 @@ public function getController($controller_type);
    *   - access: The name of the class that is used for access checks. The class
    *     must implement \Drupal\Core\Entity\EntityAccessControllerInterface.
    *     Defaults to \Drupal\Core\Entity\EntityAccessController.
+   *   - translation: The name of the controller class that should be used to
+   *     handle the translation process. The class must implement
+   *     \Drupal\content_translation\ContentTranslationControllerInterface.
    */
   public function getControllers();
 
@@ -371,15 +369,15 @@ public function setLinkTemplate($key, $route_name);
   /**
    * Gets the callback for the label of the entity.
    *
-   * The function takes an entity and returns the label of the entity. Use
-   * language() on the entity to get information on the requested language. The
-   * entity label is the main string associated with an entity; for example, the
-   * title of a node or the subject of a comment. If there is an entity object
-   * property that defines the label, use the 'label' element of the
-   * 'entity_keys' return value component to provide this information (see
-   * below). If more complex logic is needed to determine the label of an
-   * entity, you can instead specify a callback function here, which will be
-   * called to determine the entity label. See also the
+   * The function takes an entity and optional langcode argument, and returns
+   * the label of the entity. If langcode is omitted, the entity's default
+   * language is used. The entity label is the main string associated with an
+   * entity; for example, the title of a node or the subject of a comment. If
+   * there is an entity object property that defines the label, use the 'label'
+   * element of the 'entity_keys' return value component to provide this
+   * information (see below). If more complex logic is needed to determine the
+   * label of an entity, you can instead specify a callback function here, which
+   * will be called to determine the entity label. See also the
    * \Drupal\Core\Entity\EntityInterface::label() method, which implements this
    * logic.
    *
diff --git a/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php b/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php
index 4d8fbf9..61e6a5e 100644
--- a/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php
+++ b/core/lib/Drupal/Core/Field/ConfigEntityReferenceItemBase.php
@@ -36,20 +36,6 @@ public function isEmpty() {
   /**
    * {@inheritdoc}
    */
-  public function getValue() {
-    $values = parent::getValue();
-
-    // If there is an unsaved entity, return it as part of the field item values
-    // to ensure idempotency of getValue() / setValue().
-    if (empty($this->target_id) && !empty($this->entity)) {
-      $values['entity'] = $this->entity;
-    }
-    return $values;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function preSave() {
     $entity = $this->get('entity')->getValue();
     $target_id = $this->get('target_id')->getValue();
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
deleted file mode 100644
index 4f28a6e..0000000
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\ImageToolkit\ImageToolkitBase.
- */
-
-namespace Drupal\Core\ImageToolkit;
-
-use Drupal\Core\Plugin\PluginBase;
-
-abstract class ImageToolkitBase extends PluginBase implements ImageToolkitInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRequirements() {
-    return array();
-  }
-
-}
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
index a5f96f3..351d6d6 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitInterface.php
@@ -217,20 +217,6 @@ public function scaleAndCrop(ImageInterface $image, $width, $height);
   public function getInfo(ImageInterface $image);
 
   /**
-   * Gets toolkit requirements in a format suitable for hook_requirements().
-   *
-   * @return array
-   *   An associative requirements array as is returned by hook_requirements().
-   *   If the toolkit claims no requirements to the system, returns an empty
-   *   array. The array can have arbitrary keys and they do not have to be
-   *   prefixed by e.g. the module name or toolkit ID, as the system will make
-   *   the keys globally unique.
-   *
-   * @see hook_requirements()
-   */
-  public function getRequirements();
-
-  /**
    * Verifies Image Toolkit is set up correctly.
    *
    * @return bool
diff --git a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
index 1172428..31b5c27 100644
--- a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
+++ b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Routing;
 
 use Drupal\Core\Routing\RoutingEvents;
+use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -17,8 +18,21 @@
 abstract class RouteSubscriberBase implements EventSubscriberInterface {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
    * Alters existing routes for a specific collection.
    *
+   * In case a route subscriber adds additional routes in addition to (or
+   * instead of) altering existing ones, it should allow those routes to be
+   * altered by other modules as well by invoking an additional
+   * RoutingEvents::ALTER event. RouteSubscriberBase::invokeAdditionalAlter() is
+   * provided for that purpose.
+   *
    * @param \Symfony\Component\Routing\RouteCollection $collection
    *   The route collection for adding routes.
    * @param string $provider
@@ -29,10 +43,43 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
   }
 
   /**
+   * Invokes an additional alter event for routes added during alter events.
+   *
+   * It is suggested to create a new route collection with the newly added
+   * routes, then invoke the RoutingEvents::ALTER event using this method and
+   * then add them to the existing route collection passed into
+   * RouteSubscriberBase::alterRoutes(). For example:
+   * @code
+   *   public function alterRoutes(RouteCollection $collection, $provider) {
+   *     // Create an additional route collection and add routes to it.
+   *     $additional_collection = new RouteCollection();
+   *     $additional_collection->add(..., ...);
+   *     ...
+   *     // Invoke the RoutingEvents::ALTER event.
+   *     $this->invokeAdditionalAlter($additional_collection);
+   *
+   *     // Add the new routes to the existing route collection.
+   *     $collection->addCollection($additional_collection);
+   *   }
+   * @endcode
+   * The provider of the newly added routes is the class name of the route
+   * subscriber. To avoid infinite recursion, RouteSubscriberBase::alterRoutes()
+   * will not be called for the additional route collection.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $additional_collection
+   *   The collection of additional routes to be altered.
+   */
+  protected function invokeAdditionalAlter(RouteCollection $additional_collection) {
+    $new_event = new RouteBuildEvent($additional_collection, get_class($this));
+    $this->eventDispatcher->dispatch(RoutingEvents::ALTER, $new_event);
+  }
+
+  /**
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
     $events[RoutingEvents::ALTER] = 'onAlterRoutes';
+    $events[RoutingEvents::FINISHED] = 'onFinishedRebuilding';
     return $events;
   }
 
@@ -43,8 +90,25 @@ public static function getSubscribedEvents() {
    *   The route build event.
    */
   public function onAlterRoutes(RouteBuildEvent $event) {
+    $this->eventDispatcher = $event->getDispatcher();
+
     $collection = $event->getRouteCollection();
-    $this->alterRoutes($collection, $event->getProvider());
+    $provider = $event->getProvider();
+    // Avoid infinite recursion for additional routes that were provided by a
+    // route subscriber.
+    // @see \Drupal\Core\Routing\RouteSubscriberBase::invokeAdditionalAlter()
+    if ($provider != get_class($this)) {
+      $this->alterRoutes($collection, $provider);
+    }
+  }
+
+  /**
+   * Provides an opportunity to run code when route rebuilding has finished.
+   *
+   * @param \Symfony\Component\EventDispatcher\Event $event
+   *   The RoutingEvents::FINISHED event.
+   */
+  public function onFinishedRebuilding(Event $event) {
   }
 
 }
diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index ba2b06e..3f63620 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -7,15 +7,12 @@
 
 namespace Drupal\Core\Utility;
 
-use Drupal\Component\Utility\Json;
 use Drupal\Component\Utility\String;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageManager;
-use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Routing\UrlGeneratorInterface;
-use Drupal\Core\Session\AccountInterface;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -25,6 +22,13 @@
 class LinkGenerator implements LinkGeneratorInterface {
 
   /**
+   * Stores some information about the current request, like the language.
+   *
+   * @var array
+   */
+  protected $active;
+
+  /**
    * The url generator.
    *
    * @var \Drupal\Core\Routing\UrlGeneratorInterface
@@ -46,13 +50,6 @@ class LinkGenerator implements LinkGeneratorInterface {
   protected $languageManager;
 
   /**
-   * The path alias manager.
-   *
-   * @var \Drupal\Core\Path\AliasManagerInterface
-   */
-  protected $aliasManager;
-
-  /**
    * Constructs a LinkGenerator instance.
    *
    * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
@@ -61,14 +58,11 @@ class LinkGenerator implements LinkGeneratorInterface {
    *   The module handler.
    * @param \Drupal\Core\Language\LanguageManager $language_manager
    *   The language manager.
-   * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
-   *   The path alias manager.
    */
-  public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, AliasManagerInterface $alias_manager) {
+  public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler, LanguageManager $language_manager) {
     $this->urlGenerator = $url_generator;
     $this->moduleHandler = $module_handler;
     $this->languageManager = $language_manager;
-    $this->aliasManager = $alias_manager;
   }
 
   /**
@@ -99,15 +93,6 @@ public function getActive() {
 
   /**
    * {@inheritdoc}
-   *
-   * For anonymous users, the "active" class will be calculated on the server,
-   * because most sites serve each anonymous user the same cached page anyway.
-   * For authenticated users, the "active" class will be calculated on the
-   * client (through JavaScript), only data- attributes are added to links to
-   * prevent breaking the render cache. The JavaScript is added in
-   * system_page_build().
-   *
-   * @see system_page_build()
    */
   public function generate($text, $route_name, array $parameters = array(), array $options = array()) {
     // Start building a structured representation of our link to be altered later.
@@ -125,31 +110,30 @@ public function generate($text, $route_name, array $parameters = array(), array
       'query' => array(),
       'html' => FALSE,
       'language' => NULL,
-      'set_active_class' => FALSE,
     );
-
     // Add a hreflang attribute if we know the language of this link's url and
     // hreflang has not already been set.
     if (!empty($variables['options']['language']) && !isset($variables['options']['attributes']['hreflang'])) {
       $variables['options']['attributes']['hreflang'] = $variables['options']['language']->id;
     }
 
-    // Set the "active" class if the 'set_active_class' option is not empty.
-    if (!empty($variables['options']['set_active_class'])) {
-      // Add a "data-drupal-link-query" attribute to let the
-      // drupal.active-link library know the query in a standardized manner.
-      if (!empty($variables['options']['query'])) {
-        $query = $variables['options']['query'];
-        ksort($query);
-        $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query);
-      }
-
-      // Add a "data-drupal-link-system-path" attribute to let the
-      // drupal.active-link library know the path in a standardized manner.
-      if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) {
-        $path = $this->urlGenerator->getPathFromRoute($route_name, $parameters);
-        $variables['options']['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($path);
-      }
+    // This is only needed for the active class. The generator also combines
+    // the parameters and $options['query'] and adds parameters that are not
+    // path slugs as query strings.
+    $full_parameters = $parameters + (array) $variables['options']['query'];
+
+    // Determine whether this link is "active", meaning that it has the same
+    // URL path and query string as the current page. Note that this may be
+    // removed from l() in https://drupal.org/node/1979468 and would be removed
+    // or altered here also.
+    $variables['url_is_active'] = $route_name == $this->active['route_name']
+      // The language of an active link is equal to the current language.
+      && (empty($variables['options']['language']) || $variables['options']['language']->id == $this->active['language'])
+      && $full_parameters == $this->active['parameters'];
+
+    // Add the "active" class if appropriate.
+    if ($variables['url_is_active']) {
+      $variables['options']['attributes']['class'][] = 'active';
     }
 
     // Remove all HTML and PHP tags from a tooltip, calling expensive strip_tags()
diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
index b832873..8bc7eb6 100644
--- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
@@ -36,8 +36,8 @@
    * @param array $options
    *   (optional) An associative array of additional options. Defaults to an
    *   empty array. It may contain the following elements:
-   *   - 'query': An array of query key/value-pairs (without any URL-encoding)
-   *     to append to the URL.
+   *   - 'query': An array of query key/value-pairs (without any URL-encoding) to
+   *     append to the URL.
    *   - absolute: Whether to force the output to be an absolute link (beginning
    *     with http:). Useful for links that will be displayed outside the site,
    *     such as in an RSS feed. Defaults to FALSE.
@@ -55,11 +55,6 @@
    *     internal to the site, $options['language'] is used to determine whether
    *     the link is "active", or pointing to the current page (the language as
    *     well as the path must match).
-   *   - 'set_active_class' (default FALSE): Whether this method should compare
-   *     the $route_name, $parameters, language and query options to the current
-   *     URL to determine whether the link is "active". If so, an "active" class
-   *     will be applied to the link. It is important to use this sparingly
-   *     since it is usually unnecessary and requires extra processing.
    *
    * @return string
    *   An HTML string containing a link to the given route and parameters.
diff --git a/core/misc/active-link.js b/core/misc/active-link.js
deleted file mode 100644
index cb1caa6..0000000
--- a/core/misc/active-link.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file
- * Attaches behaviors for Drupal's active link marking.
- */
-
-(function (Drupal, drupalSettings) {
-
-"use strict";
-
-/**
- * Append active class.
- *
- * The link is only active if its path corresponds to the current path, the
- * language of the linked path is equal to the current language, and if the
- * query parameters of the link equal those of the current request, since the
- * same request with different query parameters may yield a different page
- * (e.g. pagers, exposed View filters).
- *
- * Does not discriminate based on element type, so allows you to set the active
- * class on any element: a, li…
- */
-Drupal.behaviors.l = {
-  attach: function queryL (context) {
-    // Start by finding all potentially active links.
-    var path = drupalSettings.path;
-    var queryString = JSON.stringify(path.currentQuery);
-    var querySelector = path.currentQuery ? "[data-drupal-link-query='" + queryString + "']" : ':not([data-drupal-link-query])';
-    var originalSelectors = ['[data-drupal-link-system-path="' + path.currentPath + '"]'];
-    var selectors;
-
-    // If this is the front page, we have to check for the <front> path as well.
-    if (path.isFront) {
-      originalSelectors.push('[data-drupal-link-system-path="<front>"]');
-    }
-
-    // Add language filtering.
-    selectors = [].concat(
-      // Links without any hreflang attributes (most of them).
-      originalSelectors.map(function (selector) { return selector + ':not([hreflang])';}),
-      // Links with hreflang equals to the current language.
-      originalSelectors.map(function (selector) { return selector + '[hreflang="' + path.currentLanguage + '"]';})
-    );
-
-    // Add query string selector for pagers, exposed filters.
-    selectors = selectors.map(function (current) { return current + querySelector; });
-
-    // Query the DOM.
-    var activeLinks = context.querySelectorAll(selectors.join(','));
-    for (var i = 0, il = activeLinks.length; i < il; i += 1) {
-      activeLinks[i].classList.add('active');
-    }
-  },
-  detach: function (context, settings, trigger) {
-    if (trigger === 'unload') {
-      var activeLinks = context.querySelectorAll('[data-drupal-link-system-path].active');
-      for (var i = 0, il = activeLinks.length; i < il; i += 1) {
-        activeLinks[i].classList.remove('active');
-      }
-    }
-  }
-};
-
-})(Drupal, drupalSettings);
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index 2d9011e..6ecde95 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -597,7 +597,7 @@ Drupal.AjaxCommands.prototype = {
       case 'empty':
       case 'remove':
         settings = response.settings || ajax.settings || drupalSettings;
-        Drupal.detachBehaviors(wrapper.get(0), settings);
+        Drupal.detachBehaviors(wrapper, settings);
     }
 
     // Add the new content to the page.
@@ -625,7 +625,7 @@ Drupal.AjaxCommands.prototype = {
     if (new_content.parents('html').length > 0) {
       // Apply any settings from the returned JSON if available.
       settings = response.settings || ajax.settings || drupalSettings;
-      Drupal.attachBehaviors(new_content.get(0), settings);
+      Drupal.attachBehaviors(new_content, settings);
     }
   },
 
diff --git a/core/misc/drupal.js b/core/misc/drupal.js
index e994ec6..6c04130 100644
--- a/core/misc/drupal.js
+++ b/core/misc/drupal.js
@@ -267,7 +267,7 @@ Drupal.t = function (str, args, options) {
  * Returns the URL to a Drupal page.
  */
 Drupal.url = function (path) {
-  return drupalSettings.path.basePath + drupalSettings.path.scriptPath + path;
+  return drupalSettings.basePath + drupalSettings.scriptPath + path;
 };
 
 /**
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
index f9b25b9..d75a28a 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
@@ -228,7 +228,7 @@ public function sources() {
             ->viewMultiple($items, 'summary');
         }
       }
-      $feed->url = $this->url('aggregator.feed_view', array('aggregator_feed' => $feed->id()));
+      $feed->url = $this->urlGenerator()->generateFromRoute('aggregator.feed_view', array('aggregator_feed' => $feed->id()));
       $build[$feed->id()] = array(
         '#theme' => 'aggregator_summary_items',
         '#summary_items' => $summary_items,
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
index f651742..98d08ba 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
@@ -163,7 +163,7 @@ public function id() {
   /**
    * Implements Drupal\Core\Entity\EntityInterface::label().
    */
-  public function label() {
+  public function label($langcode = NULL) {
     return $this->get('title')->value;
   }
 
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
index e48e45d9..f1b2a09 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
@@ -42,7 +42,7 @@ public function id() {
   /**
    * Implements Drupal\Core\Entity\EntityInterface::label().
    */
-  public function label() {
+  public function label($langcode = NULL) {
     return $this->get('title')->value;
   }
 
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
index 3befde0..cbabf5a 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
@@ -7,13 +7,9 @@
 
 namespace Drupal\custom_block;
 
-use Drupal\Core\Cache\Cache;
+use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\ContentEntityFormController;
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Language\Language;
-use Drupal\Core\Language\LanguageManager;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Form controller for the custom block edit forms.
@@ -21,48 +17,6 @@
 class CustomBlockFormController extends ContentEntityFormController {
 
   /**
-   * The custom block storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
-   */
-  protected $customBlockStorage;
-
-  /**
-   * The language manager.
-   *
-   * @var \Drupal\Core\Language\LanguageManager
-   */
-  protected $languageManager;
-
-  /**
-   * Constructs a CustomBlockFormController object.
-   *
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
-   * @param \Drupal\Core\Entity\EntityStorageControllerInterface $custom_block_storage
-   *   The custom block storage controller.
-   * @param \Drupal\Core\Language\LanguageManager $language_manager
-   *   The language manager.
-   */
-  public function __construct(EntityManagerInterface $entity_manager, EntityStorageControllerInterface $custom_block_storage, LanguageManager $language_manager) {
-    parent::__construct($entity_manager);
-    $this->customBlockStorage = $custom_block_storage;
-    $this->languageManager = $language_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    $entity_manager = $container->get('entity.manager');
-    return new static(
-      $entity_manager,
-      $entity_manager->getStorageController('custom_block'),
-      $container->get('language_manager')
-    );
-  }
-
-  /**
    * Overrides \Drupal\Core\Entity\EntityFormController::prepareEntity().
    *
    * Prepares the custom block object.
@@ -82,7 +36,7 @@ protected function prepareEntity() {
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides \Drupal\Core\Entity\EntityFormController::form().
    */
   public function form(array $form, array &$form_state) {
     $block = $this->entity;
@@ -99,25 +53,23 @@ public function form(array $form, array &$form_state) {
     // Basic block information.
     $form['info'] = array(
       '#type' => 'textfield',
-      '#title' => $this->t('Block description'),
+      '#title' => t('Block description'),
       '#required' => TRUE,
       '#default_value' => $block->label(),
       '#weight' => -5,
-      '#description' => $this->t('A brief description of your block. Used on the <a href="@overview">Blocks administration page</a>.', array('@overview' => $this->url('block.admin_display'))),
+      '#description' => t('A brief description of your block. Used on the <a href="@overview">Blocks administration page</a>.', array('@overview' => url('admin/structure/block'))),
     );
 
-    if ($this->moduleHandler->moduleExists('language')) {
-      $language_configuration = language_get_default_configuration('custom_block', $block->bundle());
+    $language_configuration = module_invoke('language', 'get_default_configuration', 'custom_block', $block->bundle());
 
-      // Set the correct default language.
-      if ($block->isNew()) {
-        $language_default = $this->languageManager->getLanguage($language_configuration['langcode']);
-        $block->langcode->value = $language_default->id;
-      }
+    // Set the correct default language.
+    if ($block->isNew() && !empty($language_configuration['langcode'])) {
+      $language_default = language($language_configuration['langcode']);
+      $block->langcode->value = $language_default->id;
     }
 
     $form['langcode'] = array(
-      '#title' => $this->t('Language'),
+      '#title' => t('Language'),
       '#type' => 'language_select',
       '#default_value' => $block->getUntranslated()->language()->id,
       '#languages' => Language::STATE_ALL,
@@ -133,7 +85,7 @@ public function form(array $form, array &$form_state) {
     // current user has the ability to check that option.
     $form['revision_information'] = array(
       '#type' => 'details',
-      '#title' => $this->t('Revision information'),
+      '#title' => t('Revision information'),
       '#collapsible' => TRUE,
       // Collapsed by default when "Create new revision" is unchecked.
       '#collapsed' => !$block->isNewRevision(),
@@ -150,7 +102,7 @@ public function form(array $form, array &$form_state) {
 
     $form['revision_information']['revision'] = array(
       '#type' => 'checkbox',
-      '#title' => $this->t('Create new revision'),
+      '#title' => t('Create new revision'),
       '#default_value' => $block->isNewRevision(),
       '#access' => $account->hasPermission('administer blocks'),
     );
@@ -168,10 +120,10 @@ public function form(array $form, array &$form_state) {
 
     $form['revision_information']['log'] = array(
       '#type' => 'textarea',
-      '#title' => $this->t('Revision log message'),
+      '#title' => t('Revision log message'),
       '#rows' => 4,
       '#default_value' => $block->getRevisionLog(),
-      '#description' => $this->t('Briefly desribe the changes you have made.'),
+      '#description' => t('Briefly describe the changes you have made.'),
     );
 
     return parent::form($form, $form_state, $block);
@@ -199,7 +151,7 @@ public function submit(array $form, array &$form_state) {
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides \Drupal\Core\Entity\EntityFormController::save().
    */
   public function save(array $form, array &$form_state) {
     $block = $this->entity;
@@ -211,11 +163,11 @@ public function save(array $form, array &$form_state) {
 
     if ($insert) {
       watchdog('content', '@type: added %info.', $watchdog_args, WATCHDOG_NOTICE);
-      drupal_set_message($this->t('@type %info has been created.', $t_args));
+      drupal_set_message(t('@type %info has been created.', $t_args));
     }
     else {
       watchdog('content', '@type: updated %info.', $watchdog_args, WATCHDOG_NOTICE);
-      drupal_set_message($this->t('@type %info has been updated.', $t_args));
+      drupal_set_message(t('@type %info has been updated.', $t_args));
     }
 
     if ($block->id()) {
@@ -240,20 +192,20 @@ public function save(array $form, array &$form_state) {
     else {
       // In the unlikely case something went wrong on save, the block will be
       // rebuilt and block form redisplayed.
-      drupal_set_message($this->t('The block could not be saved.'), 'error');
+      drupal_set_message(t('The block could not be saved.'), 'error');
       $form_state['rebuild'] = TRUE;
     }
 
     // Clear the page and block caches.
-    Cache::invalidateTags(array('content' => TRUE));
+    cache_invalidate_tags(array('content' => TRUE));
   }
 
   /**
-   * {@inheritdoc}
+   * Overrides \Drupal\Core\Entity\EntityFormController::delete().
    */
   public function delete(array $form, array &$form_state) {
     $destination = array();
-    $query = $this->getRequest()->query;
+    $query = \Drupal::request()->query;
     if (!is_null($query->get('destination'))) {
       $destination = drupal_get_destination();
       $query->remove('destination');
@@ -274,11 +226,12 @@ public function delete(array $form, array &$form_state) {
    */
   public function validateForm(array &$form, array &$form_state) {
     if ($this->entity->isNew()) {
-      $exists = $this->customBlockStorage->loadByProperties(array('info' => $form_state['values']['info']));
+      // @todo Inject this once https://drupal.org/node/2060865 is in.
+      $exists = \Drupal::entityManager()->getStorageController('custom_block')->loadByProperties(array('info' => $form_state['values']['info']));
       if (!empty($exists)) {
         $this->setFormError('info', $form_state, $this->t('A block with description %name already exists.', array(
-          '%name' => $form_state['values']['info'],
-        )));
+        '%name' => $form_state['values']['info']
+      )));
       }
     }
   }
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
index 36df166..96ee5f0 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
@@ -8,6 +8,7 @@
 namespace Drupal\custom_block\Form;
 
 use Drupal\Core\Entity\ContentEntityConfirmFormBase;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Provides a confirmation form for deleting a custom block entity.
@@ -40,7 +41,8 @@ public function getConfirmText() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, array &$form_state) {
+  public function buildForm(array $form, array &$form_state, Request $request = NULL) {
+    $form = parent::buildForm($form, $form_state, $request);
     $instances = $this->entity->getInstances();
 
     $form['message'] = array(
@@ -48,7 +50,7 @@ public function buildForm(array $form, array &$form_state) {
       '#access' => !empty($instances),
     );
 
-    return parent::buildForm($form, $form_state);
+    return $form;
   }
 
   /**
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php
index 8b7a681..e065e65 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php
@@ -46,7 +46,7 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   public function getQuestion() {
-    return $this->t('Are you sure you want to delete %label?', array('%label' => $this->entity->label()));
+    return t('Are you sure you want to delete %label?', array('%label' => $this->entity->label()));
   }
 
   /**
@@ -62,7 +62,7 @@ public function getCancelRoute() {
    * {@inheritdoc}
    */
   public function getConfirmText() {
-    return $this->t('Delete');
+    return t('Delete');
   }
 
   /**
diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php
index 926ef07..89dde8d 100644
--- a/core/modules/block/lib/Drupal/block/Entity/Block.php
+++ b/core/modules/block/lib/Drupal/block/Entity/Block.php
@@ -117,7 +117,7 @@ public function getPlugin() {
   /**
    * Overrides \Drupal\Core\Entity\Entity::label();
    */
-  public function label() {
+  public function label($langcode = NULL) {
     $settings = $this->get('settings');
     if ($settings['label']) {
       return $settings['label'];
diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js
index d519d66..ccf2f71 100644
--- a/core/modules/ckeditor/js/ckeditor.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.admin.js
@@ -120,8 +120,8 @@ Drupal.ckeditor = {
       this.getCKEditorFeatures(this.model.get('hiddenEditorConfig'), this.disableFeaturesDisallowedByFilters.bind(this));
 
       // Push the active editor configuration to the textarea.
-      this.model.listenTo(this.model, 'change:activeEditorConfig', this.model.sync);
-      this.listenTo(this.model, 'change:isDirty', this.parseEditorDOM);
+      this.model.on('change:activeEditorConfig', this.model.sync, this.model);
+      this.model.on('change:isDirty', this.parseEditorDOM, this);
     },
 
     /**
@@ -462,7 +462,7 @@ Drupal.ckeditor = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change:isDirty change:groupNamesVisible', this.render);
+      this.model.on('change:isDirty change:groupNamesVisible', this.render, this);
 
       // Add a toggle for the button group names.
       $(Drupal.theme('ckeditorButtonGroupNamesToggle'))
@@ -959,7 +959,7 @@ Drupal.ckeditor = {
     initialize: function () {
       // Announce the button and group positions when the model is no longer
       // dirty.
-      this.listenTo(this.model, 'change:isDirty', this.announceMove);
+      this.model.on('change:isDirty', this.announceMove, this);
     },
 
     /**
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
new file mode 100644
index 0000000..99bb6b0
--- /dev/null
+++ b/core/modules/comment/comment.admin.inc
@@ -0,0 +1,234 @@
+<?php
+
+/**
+ * @file
+ * Admin page callbacks for the Comment module.
+ */
+
+use Drupal\comment\CommentInterface;
+
+/**
+ * Page callback: Presents an administrative comment listing.
+ *
+ * @param $type
+ *   The type of the overview form ('approval' or 'new'). See
+ *   comment_admin_overview() for details.
+ *
+ * @see comment_menu()
+ * @see comment_multiple_delete_confirm()
+ *
+ * @deprecated Use \Drupal\comment\Controller\CommentController::adminPage()
+ */
+function comment_admin($type = 'new') {
+  $request = \Drupal::request();
+  $edit = $request->request->all();
+
+  if (isset($edit['operation']) && ($edit['operation'] == 'delete') && isset($edit['comments']) && $edit['comments']) {
+    return drupal_get_form('Drupal\comment\Form\ConfirmDeleteMultiple');
+  }
+  else {
+    return drupal_get_form('comment_admin_overview', $type);
+  }
+}
+
+/**
+ * Form constructor for the comment overview administration form.
+ *
+ * @param $arg
+ *   The type of overview form ('approval' or 'new').
+ *
+ * @ingroup forms
+ * @see comment_admin()
+ * @see comment_admin_overview_validate()
+ * @see comment_admin_overview_submit()
+ * @see theme_comment_admin_overview()
+ */
+function comment_admin_overview($form, &$form_state, $arg) {
+  // Build an 'Update options' form.
+  $form['options'] = array(
+    '#type' => 'details',
+    '#title' => t('Update options'),
+    '#attributes' => array('class' => array('container-inline')),
+  );
+
+  if ($arg == 'approval') {
+    $options['publish'] = t('Publish the selected comments');
+  }
+  else {
+    $options['unpublish'] = t('Unpublish the selected comments');
+  }
+  $options['delete'] = t('Delete the selected comments');
+
+  $form['options']['operation'] = array(
+    '#type' => 'select',
+    '#title' => t('Action'),
+    '#title_display' => 'invisible',
+    '#options' => $options,
+    '#default_value' => 'publish',
+  );
+  $form['options']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update'),
+  );
+
+  // Load the comments that need to be displayed.
+  $status = ($arg == 'approval') ? CommentInterface::NOT_PUBLISHED : CommentInterface::PUBLISHED;
+  $header = array(
+    'subject' => array('data' => t('Subject'), 'field' => 'subject'),
+    'author' => array('data' => t('Author'), 'field' => 'name', 'class' => array(RESPONSIVE_PRIORITY_MEDIUM)),
+    'posted_in' => array('data' => t('Posted in'), 'field' => 'node_title', 'class' => array(RESPONSIVE_PRIORITY_LOW)),
+    'changed' => array('data' => t('Updated'), 'field' => 'c.changed', 'sort' => 'desc', 'class' => array(RESPONSIVE_PRIORITY_LOW)),
+    'operations' => t('Operations'),
+  );
+
+  $query = db_select('comment', 'c')
+    ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
+    ->extend('Drupal\Core\Database\Query\TableSortExtender');
+  if (\Drupal::moduleHandler()->moduleExists('node')) {
+    // Special case to ensure node access works.
+    $query->leftJoin('node_field_data', 'n', "n.nid = c.entity_id AND c.entity_type = 'node'");
+    $query->addTag('node_access');
+  }
+  $result = $query
+    ->fields('c', array('cid', 'subject', 'name', 'changed', 'entity_id', 'entity_type', 'field_id'))
+    ->condition('c.status', $status)
+    ->limit(50)
+    ->orderByHeader($header)
+    ->execute();
+
+  $cids = array();
+  $entity_ids = array();
+  $entities = array();
+
+  // We collect entities grouped by entity_type so we can load them and use
+  // their labels.
+  foreach ($result as $row) {
+    $entity_ids[$row->entity_type][] = $row->entity_id;
+    $cids[] = $row->cid;
+  }
+  // Ensure all entities are statically cached so that we do not have to load
+  // them individually when getting their labels below.
+  foreach ($entity_ids as $entity_type => $ids) {
+    $entities[$entity_type] = entity_load_multiple($entity_type, $ids);
+  }
+  $comments = entity_load_multiple('comment', $cids);
+
+  // Build a table listing the appropriate comments.
+  $options = array();
+  $destination = drupal_get_destination();
+
+  foreach ($comments as $comment) {
+    // Use the first entity label.
+    $entity = $entities[$comment->entity_type->value][$comment->entity_id->value];
+    $entity_uri = $entity->uri();
+    // Remove the first node title from the node_titles array and attach to
+    // the comment.
+    $body = '';
+    if (!empty($comment->comment_body->value)) {
+      $body = $comment->comment_body->value;
+    }
+    $options[$comment->id()] = array(
+      'title' => array('data' => array('#title' => $comment->subject->value ?: $comment->id())),
+      'subject' => array(
+        'data' => array(
+          '#type' => 'link',
+          '#title' => $comment->subject->value,
+          '#href' => 'comment/' . $comment->id(),
+          '#options' => array('attributes' => array('title' => truncate_utf8($body, 128)), 'fragment' => 'comment-' . $comment->id()),
+        ),
+      ),
+      'author' => array(
+        'data' => array(
+          '#theme' => 'username',
+          '#account' => comment_prepare_author($comment),
+        ),
+      ),
+      'posted_in' => array(
+        'data' => array(
+          '#type' => 'link',
+          '#title' => $entity->label(),
+          '#href' => $entity_uri['path'],
+          '#options' => $entity_uri['options'],
+          '#access' => $entity->access('view'),
+        ),
+      ),
+      'changed' => format_date($comment->changed->value, 'short'),
+    );
+    $links = array();
+    $links['edit'] = array(
+      'title' => t('Edit'),
+      'route_name' => 'comment.edit_page',
+      'route_parameters' => array('comment' => $comment->id()),
+      'query' => $destination,
+    );
+    if (module_invoke('content_translation', 'translate_access', $comment)) {
+      $links['translate'] = array(
+        'title' => t('Translate'),
+        'route_name' => 'content_translation.translation_overview_comment',
+        'route_parameters' => array('comment' => $comment->id()),
+        'query' => $destination,
+      );
+    }
+    $options[$comment->id()]['operations']['data'] = array(
+      '#type' => 'operations',
+      '#links' => $links,
+    );
+  }
+
+  $form['comments'] = array(
+    '#type' => 'tableselect',
+    '#header' => $header,
+    '#options' => $options,
+    '#empty' => t('No comments available.'),
+  );
+
+  $form['pager'] = array('#theme' => 'pager');
+
+  return $form;
+}
+
+/**
+ * Form validation handler for comment_admin_overview().
+ *
+ * @see comment_admin_overview_submit()
+ */
+function comment_admin_overview_validate($form, &$form_state) {
+  $form_state['values']['comments'] = array_diff($form_state['values']['comments'], array(0));
+  // We can't execute any 'Update options' if no comments were selected.
+  if (count($form_state['values']['comments']) == 0) {
+    form_set_error('', $form_state, t('Select one or more comments to perform the update on.'));
+  }
+}
+
+/**
+ * Form submission handler for comment_admin_overview().
+ *
+ * Executes the chosen 'Update option' on the selected comments, such as
+ * publishing, unpublishing or deleting.
+ *
+ * @see comment_admin_overview_validate()
+ */
+function comment_admin_overview_submit($form, &$form_state) {
+  $operation = $form_state['values']['operation'];
+  $cids = $form_state['values']['comments'];
+
+  if ($operation == 'delete') {
+    entity_delete_multiple('comment', $cids);
+  }
+  else {
+    foreach ($cids as $value) {
+      $comment = comment_load($value);
+
+      if ($operation == 'unpublish') {
+        $comment->status->value = CommentInterface::NOT_PUBLISHED;
+      }
+      elseif ($operation == 'publish') {
+        $comment->status->value = CommentInterface::PUBLISHED;
+      }
+      $comment->save();
+    }
+  }
+  drupal_set_message(t('The update has been performed.'));
+  $form_state['redirect_route']['route_name'] = 'comment.admin';
+  cache_invalidate_tags(array('content' => TRUE));
+}
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index df12f82..ec6a2cc 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -352,7 +352,7 @@ function comment_get_recent($number = 10) {
  * @param string $field_name
  *   The field name on the entity to which comments are attached to.
  *
- * @return array|null
+ * @return array|NULL
  *   An array "page=X" if the page number is greater than zero; NULL otherwise.
  */
 function comment_new_page_count($num_comments, $new_replies, EntityInterface $entity, $field_name = 'comment') {
@@ -1456,6 +1456,9 @@ function template_preprocess_comment(&$variables) {
     $variables['parent'] = '';
   }
 
+  // Preprocess fields.
+  field_attach_preprocess($comment, $variables['elements'], $variables);
+
   // Helpful $content variable for templates.
   foreach (element_children($variables['elements']) as $key) {
     $variables['content'][$key] = $variables['elements'][$key];
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index 6273eb7..dcb3baa 100644
--- a/core/modules/comment/comment.routing.yml
+++ b/core/modules/comment/comment.routing.yml
@@ -2,7 +2,7 @@ comment.admin:
   path: '/admin/content/comment'
   defaults:
     _title: 'Comments'
-    _content: '\Drupal\comment\Controller\AdminController::adminPage'
+    _content: '\Drupal\comment\Controller\CommentController::adminPage'
     type: 'new'
   requirements:
     _permission: 'administer comments'
@@ -11,7 +11,7 @@ comment.admin_approval:
   path: '/admin/content/comment/approval'
   defaults:
     _title: 'Unapproved comments'
-    _content: '\Drupal\comment\Controller\AdminController::adminPage'
+    _content: '\Drupal\comment\Controller\CommentController::adminPage'
     type: 'approval'
   requirements:
     _permission: 'administer comments'
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
index 7378585..22963bd 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
@@ -7,13 +7,11 @@
 
 namespace Drupal\comment\Controller;
 
-use Drupal\comment\CommentManagerInterface;
-use Drupal\field\FieldInfo;
 use Drupal\Component\Utility\String;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\Core\Form\FormBuilderInterface;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\comment\CommentManagerInterface;
+use Drupal\field\FieldInfo;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -36,20 +34,12 @@ class AdminController extends ControllerBase implements ContainerInjectionInterf
   protected $commentManager;
 
   /**
-   * The form builder.
-   *
-   * @var \Drupal\Core\Form\FormBuilderInterface
-   */
-  protected $formBuilder;
-
-  /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('field.info'),
-      $container->get('comment.manager'),
-      $container->get('form_builder')
+      $container->get('comment.manager')
     );
   }
 
@@ -60,13 +50,10 @@ public static function create(ContainerInterface $container) {
    *   The field info service.
    * @param \Drupal\comment\CommentManagerInterface $comment_manager
    *   The comment manager service.
-   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
-   *   The form builder.
    */
-  public function __construct(FieldInfo $field_info, CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) {
+  public function __construct(FieldInfo $field_info, CommentManagerInterface $comment_manager) {
     $this->fieldInfo = $field_info;
     $this->commentManager = $comment_manager;
-    $this->formBuilder = $form_builder;
   }
 
   /**
@@ -238,25 +225,4 @@ public function bundleTitle($commented_entity_type, $field_name) {
     return $this->commentManager->getFieldUIPageTitle($commented_entity_type, $field_name);
   }
 
-  /**
-   * Presents an administrative comment listing.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request of the page.
-   * @param string $type
-   *   The type of the overview form ('approval' or 'new') default to 'new'.
-   *
-   * @return array
-   *   Then comment multiple delete confirmation form or the comments overview
-   *   administration form.
-   */
-  public function adminPage(Request $request, $type = 'new') {
-    if ($request->request->get('operation') == 'delete' && $request->request->get('comments')) {
-      return $this->formBuilder->getForm('\Drupal\comment\Form\ConfirmDeleteMultiple', $request);
-    }
-    else {
-      return $this->formBuilder->getForm('\Drupal\comment\Form\CommentAdminOverview', $type);
-    }
-  }
-
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
index 15f09a7..b1b127f 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -36,6 +37,13 @@ class CommentController extends ControllerBase implements ContainerInjectionInte
   protected $httpKernel;
 
   /**
+   * The current user service.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
    * Field info service.
    *
    * @var \Drupal\field\FieldInfo
@@ -52,15 +60,18 @@ class CommentController extends ControllerBase implements ContainerInjectionInte
   /**
    * Constructs a CommentController object.
    *
-   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
+   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $httpKernel
    *   HTTP kernel to handle requests.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user service.
    * @param \Drupal\field\FieldInfo $field_info
    *   Field Info service.
    * @param \Drupal\comment\CommentManagerInterface $comment_manager
    *   The comment manager service.
    */
-  public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_info, CommentManagerInterface $comment_manager) {
-    $this->httpKernel = $http_kernel;
+  public function __construct(HttpKernelInterface $httpKernel, AccountInterface $current_user, FieldInfo $field_info, CommentManagerInterface $comment_manager) {
+    $this->httpKernel = $httpKernel;
+    $this->currentUser = $current_user;
     $this->fieldInfo = $field_info;
     $this->commentManager = $comment_manager;
   }
@@ -71,6 +82,7 @@ public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_i
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('http_kernel'),
+      $container->get('current_user'),
       $container->get('field.info'),
       $container->get('comment.manager')
     );
@@ -83,7 +95,6 @@ public static function create(ContainerInterface $container) {
    *   A comment entity.
    *
    * @return \Symfony\Component\HttpFoundation\RedirectResponse.
-   *   Redirects to the permalink URL for this comment.
    */
   public function commentApprove(CommentInterface $comment) {
     $comment->status->value = CommentInterface::PUBLISHED;
@@ -167,8 +178,7 @@ public function redirectNode(EntityInterface $node) {
    *   - replies to comments
    *   - replies to entities
    *   - attempts to reply to entities that can no longer accept comments
-   *   - respecting access permissions ('access comments', 'post comments',
-   *     etc.)
+   *   - respecting access permissions ('access comments', 'post comments', etc.)
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The current request object.
@@ -182,7 +192,6 @@ public function redirectNode(EntityInterface $node) {
    *   (optional) Some comments are replies to other comments. In those cases,
    *   $pid is the parent comment's comment ID. Defaults to NULL.
    *
-   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
    * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
    *   One of the following:
    *   An associative array containing:
@@ -236,7 +245,7 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_
         }
         // Load the parent comment.
         $comment = $this->entityManager()->getStorageController('comment')->load($pid);
-        // Check if the parent comment is published and belongs to the entity.
+        // Check if the parent comment is published and belongs to the current nid.
         if (($comment->status->value == CommentInterface::NOT_PUBLISHED) || ($comment->entity_id->value != $entity->id())) {
           drupal_set_message($this->t('The comment you are replying to does not exist.'), 'error');
           return new RedirectResponse($this->urlGenerator()->generateFromPath($uri['path'], array('absolute' => TRUE)));
@@ -278,13 +287,11 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The request of the page.
    *
-   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
-   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
    * @return \Symfony\Component\HttpFoundation\JsonResponse
    *   The JSON response.
    */
   public function renderNewCommentsNodeLinks(Request $request) {
-    if ($this->currentUser()->isAnonymous()) {
+    if ($this->currentUser->isAnonymous()) {
       throw new AccessDeniedHttpException();
     }
 
@@ -302,7 +309,7 @@ public function renderNewCommentsNodeLinks(Request $request) {
       $new = comment_num_new($node->id(), 'node');
       $query = comment_new_page_count($node->{$field_name}->comment_count, $new, $node);
       $links[$nid] = array(
-        'new_comment_count' => (int) $new,
+        'new_comment_count' => (int)$new,
         'first_new_comment_link' => $this->urlGenerator()->generateFromPath('node/' . $node->id(), array('query' => $query, 'fragment' => 'new')),
       );
     }
@@ -310,4 +317,12 @@ public function renderNewCommentsNodeLinks(Request $request) {
     return new JsonResponse($links);
   }
 
+  /**
+   * @todo Remove comment_admin().
+   */
+  public function adminPage($type) {
+    module_load_include('admin.inc', 'comment');
+    return comment_admin($type);
+  }
+
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php b/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php
deleted file mode 100644
index 07c6d54..0000000
--- a/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php
+++ /dev/null
@@ -1,305 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Form\CommentAdminOverview.
- */
-
-namespace Drupal\comment\Form;
-
-use Drupal\comment\CommentInterface;
-use Drupal\comment\CommentStorageControllerInterface;
-use Drupal\Component\Utility\Unicode;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Datetime\Date;
-use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\Query\QueryFactory;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides the comments overview administration form.
- */
-class CommentAdminOverview extends FormBase {
-
-  /**
-   * The entity storage.
-   *
-   * @var \Drupal\Core\Entity\EntityManager
-   */
-  protected $entityManager;
-
-  /**
-   * The comment storage.
-   *
-   * @var \Drupal\comment\CommentStorageControllerInterface
-   */
-  protected $commentStorage;
-
-  /**
-   * The entity query service.
-   *
-   * @var \Drupal\Core\Entity\Query\QueryFactory
-   */
-  protected $entityQuery;
-
-  /**
-   * Date service object.
-   *
-   * @var \Drupal\Core\Datetime\Date
-   */
-  protected $date;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Creates a CommentAdminOverview form.
-   *
-   * @param \Drupal\Core\Entity\EntityManager $entity_manager
-   *   The entity manager service.
-   * @param \Drupal\comment\CommentStorageControllerInterface $comment_storage
-   *   The comment storage.
-   * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
-   *   The entity query service.
-   * @param \Drupal\Core\Datetime\Date $date
-   *   The date service.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   */
-  public function __construct(EntityManager $entity_manager, CommentStorageControllerInterface $comment_storage, QueryFactory $entity_query, Date $date, ModuleHandlerInterface $module_handler) {
-    $this->entityManager = $entity_manager;
-    $this->commentStorage = $comment_storage;
-    $this->entityQuery = $entity_query;
-    $this->date = $date;
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('entity.manager'),
-      $container->get('entity.manager')->getStorageController('comment'),
-      $container->get('entity.query'),
-      $container->get('date'),
-      $container->get('module_handler')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'comment_admin_overview';
-  }
-
-  /**
-   * Form constructor for the comment overview administration form.
-   *
-   * @param array $form
-   *   An associative array containing the structure of the form.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   * @param string $type
-   *   The type of the overview form ('approval' or 'new').
-   *
-   * @return array
-   *   The form structure.
-   */
-  public function buildForm(array $form, array &$form_state, $type = 'new') {
-
-    // Build an 'Update options' form.
-    $form['options'] = array(
-      '#type' => 'details',
-      '#title' => $this->t('Update options'),
-      '#attributes' => array('class' => array('container-inline')),
-    );
-
-    if ($type == 'approval') {
-      $options['publish'] = $this->t('Publish the selected comments');
-    }
-    else {
-      $options['unpublish'] = $this->t('Unpublish the selected comments');
-    }
-    $options['delete'] = $this->t('Delete the selected comments');
-
-    $form['options']['operation'] = array(
-      '#type' => 'select',
-      '#title' => $this->t('Action'),
-      '#title_display' => 'invisible',
-      '#options' => $options,
-      '#default_value' => 'publish',
-    );
-    $form['options']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => $this->t('Update'),
-    );
-
-    // Load the comments that need to be displayed.
-    $status = ($type == 'approval') ? CommentInterface::NOT_PUBLISHED : CommentInterface::PUBLISHED;
-    $header = array(
-      'subject' => array(
-        'data' => $this->t('Subject'),
-        'specifier' => 'subject',
-      ),
-      'author' => array(
-        'data' => $this->t('Author'),
-        'specifier' => 'name',
-        'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
-      ),
-      'posted_in' => array(
-        'data' => $this->t('Posted in'),
-        'class' => array(RESPONSIVE_PRIORITY_LOW),
-      ),
-      'changed' => array(
-        'data' => $this->t('Updated'),
-        'specifier' => 'changed',
-        'sort' => 'desc',
-        'class' => array(RESPONSIVE_PRIORITY_LOW),
-      ),
-      'operations' => $this->t('Operations'),
-    );
-    $cids = $this->entityQuery->get('comment')
-     ->condition('status', $status)
-     ->tableSort($header)
-     ->pager(50)
-     ->execute();
-
-    $comments = $this->commentStorage->loadMultiple($cids);
-
-    // Build a table listing the appropriate comments.
-    $options = array();
-    $destination = drupal_get_destination();
-
-    $commented_entity_ids = array();
-    $commented_entities = array();
-
-    foreach ($comments as $comment) {
-      $commented_entity_ids[$comment->entity_type->value][] = $comment->entity_id->value;
-    }
-
-    foreach ($commented_entity_ids as $entity_type => $ids) {
-      $commented_entities[$entity_type] = $this->entityManager->getStorageController($entity_type)->loadMultiple($ids);
-    }
-
-    foreach ($comments as $comment) {
-      $commented_entity = $commented_entities[$comment->entity_type->value][$comment->entity_id->value];
-      $commented_entity_uri = $commented_entity->uri();
-      $username = array(
-        '#theme' => 'username',
-        '#account' => comment_prepare_author($comment),
-      );
-      $body = '';
-      if (!empty($comment->comment_body->value)) {
-        $body = $comment->comment_body->value;
-      }
-      $comment_permalink = $comment->permalink();
-      $options[$comment->id()] = array(
-        'title' => array('data' => array('#title' => $comment->subject->value ?: $comment->id())),
-        'subject' => array(
-          'data' => array(
-            '#type' => 'link',
-            '#title' => $comment->subject->value,
-            '#href' => $comment_permalink['path'],
-            '#options' => $comment_permalink['options'] + array(
-              'attributes' => array(
-                'title' => Unicode::truncate($body, 128),
-              ),
-            ),
-          ),
-        ),
-        'author' => drupal_render($username),
-        'posted_in' => array(
-          'data' => array(
-            '#type' => 'link',
-            '#title' => $commented_entity->label(),
-            '#href' => $commented_entity_uri['path'],
-            '#options' => $commented_entity_uri['options'],
-            '#access' => $commented_entity->access('view'),
-          ),
-        ),
-        'changed' => $this->date->format($comment->changed->value, 'short'),
-      );
-      $comment_uri = $comment->uri();
-      $links = array();
-      $links['edit'] = array(
-        'title' => $this->t('edit'),
-        'route_name' => 'comment.edit_page',
-        'route_parameters' => array('comment' => $comment->id()),
-        'options' => $comment_uri['options'],
-        'query' => $destination,
-      );
-      if ($this->moduleHandler->invoke('content_translation', 'translate_access', array($comment))) {
-        $links['translate'] = array(
-          'title' => $this->t('translate'),
-          'route_name' => 'content_translation.translation_overview_comment',
-          'route_parameters' => array('comment' => $comment->id()),
-          'options' => $comment_uri['options'],
-          'query' => $destination,
-        );
-      }
-      $options[$comment->id()]['operations']['data'] = array(
-        '#type' => 'operations',
-        '#links' => $links,
-      );
-    }
-
-    $form['comments'] = array(
-      '#type' => 'tableselect',
-      '#header' => $header,
-      '#options' => $options,
-      '#empty' => $this->t('No comments available.'),
-    );
-
-    $form['pager'] = array('#theme' => 'pager');
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, array &$form_state) {
-    $form_state['values']['comments'] = array_diff($form_state['values']['comments'], array(0));
-    // We can't execute any 'Update options' if no comments were selected.
-    if (count($form_state['values']['comments']) == 0) {
-      $this->setFormError('', $form_state, $this->t('Select one or more comments to perform the update on.'));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    $operation = $form_state['values']['operation'];
-    $cids = $form_state['values']['comments'];
-
-    foreach ($cids as $cid) {
-      // Delete operation handled in \Drupal\comment\Form\ConfirmDeleteMultiple
-      // see \Drupal\comment\Controller\AdminController::adminPage().
-      if ($operation == 'unpublish') {
-        $comment = $this->commentStorage->load($cid);
-        $comment->status->value = CommentInterface::NOT_PUBLISHED;
-        $comment->save();
-      }
-      elseif ($operation == 'publish') {
-        $comment = $this->commentStorage->load($cid);
-        $comment->status->value = CommentInterface::PUBLISHED;
-        $comment->save();
-      }
-    }
-    drupal_set_message($this->t('The update has been performed.'));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'comment.admin',
-    );
-    Cache::invalidateTags(array('content' => TRUE));
-  }
-
-}
diff --git a/core/modules/comment/lib/Drupal/comment/Form/ConfirmDeleteMultiple.php b/core/modules/comment/lib/Drupal/comment/Form/ConfirmDeleteMultiple.php
index b791b30..1967277 100644
--- a/core/modules/comment/lib/Drupal/comment/Form/ConfirmDeleteMultiple.php
+++ b/core/modules/comment/lib/Drupal/comment/Form/ConfirmDeleteMultiple.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\comment\Form\ConfirmDeleteMultiple.
+ * Contains \Drupal\comment\Form\DeleteConfirmMultiple.
  */
 
 namespace Drupal\comment\Form;
@@ -70,9 +70,6 @@ public function getQuestion() {
    * {@inheritdoc}
    */
   public function getCancelRoute() {
-    return array(
-      'route_name' => 'comment.admin',
-    );
   }
 
   /**
@@ -113,7 +110,11 @@ public function buildForm(array $form, array &$form_state) {
       $form_state['redirect_route']['route_name'] = 'comment.admin';
     }
 
-    return parent::buildForm($form, $form_state);
+    $form = parent::buildForm($form, $form_state);
+
+    // @todo Convert to getCancelRoute() after http://drupal.org/node/1986606.
+    $form['actions']['cancel']['#href'] = 'admin/content/comment';
+    return $form;
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php
index e631da2..a44b5c9 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php
@@ -93,12 +93,6 @@ function testApprovalAdminInterface() {
     $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.');
     $this->drupalPostForm(NULL, $edit, t('Delete comments'));
     $this->assertText(t('No comments available.'), 'All comments were deleted.');
-    // Test message when no comments selected.
-    $edit = array(
-      'operation' => 'delete',
-    );
-    $this->drupalPostForm(NULL, $edit, t('Update'));
-    $this->assertText(t('Select one or more comments to perform the update on.'));
   }
 
   /**
diff --git a/core/modules/config/lib/Drupal/config/Form/ConfigSync.php b/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
index 8e95d7e..2994283 100644
--- a/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
+++ b/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
@@ -160,11 +160,6 @@ public function buildForm(array $form, array &$form_state) {
       $form['actions']['#access'] = FALSE;
       return $form;
     }
-    elseif (!$storage_comparer->validateSiteUuid()) {
-      drupal_set_message($this->t('The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site.'), 'error');
-      $form['actions']['#access'] = FALSE;
-      return $form;
-    }
     else {
       // Store the comparer for use in the submit.
       $form_state['storage_comparer'] = $storage_comparer;
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php
index a214b63..539879a 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php
@@ -21,13 +21,6 @@
 class ConfigExportImportUITest extends WebTestBase {
 
   /**
-   * The site UUID.
-   *
-   * @var string
-   */
-  protected $siteUuid;
-
-  /**
    * The slogan value, for a simple export test case.
    *
    * @var string
@@ -76,8 +69,6 @@ protected function setUp() {
    * Tests a simple site configuration export case: site slogan.
    */
   function testExport() {
-    $this->siteUuid = \Drupal::config('system.site')->get('uuid');
-
     // Create a role for second round.
     $this->admin_role = $this->drupalCreateRole(array('synchronize configuration', 'import configuration'));
     $this->slogan = $this->randomString(16);
@@ -113,9 +104,6 @@ function testImport() {
    *   The name of the tarball containing the configuration to be imported.
    */
   protected function doImport($filename) {
-    // The site UUIDs must match for the import to work.
-    \Drupal::config('system.site')->set('uuid', $this->siteUuid)->save();
-
     $this->assertNotEqual($this->slogan, \Drupal::config('system.site')->get('slogan'));
     $this->drupalPostForm('admin/config/development/configuration/full/import', array('files[import_tarball]' => $filename), 'Upload');
     $this->drupalPostForm(NULL, array(), 'Import all');
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php
index e495602..2f4ac16 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php
@@ -116,23 +116,6 @@ function testImportLock() {
   }
 
   /**
-   * Tests verification of site UUID before importing configuration.
-   */
-  function testImportSiteUuidValidation() {
-    $staging = \Drupal::service('config.storage.staging');
-    // Create updated configuration object.
-    $config_data = \Drupal::config('system.site')->get();
-    // Generate a new site UUID.
-    $config_data['uuid'] = \Drupal::service('uuid')->generate();
-    $staging->write('system.site', $config_data);
-
-    // Verify that there are configuration differences to import.
-    $this->drupalGet('admin/config/development/configuration');
-    $this->assertText(t('The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site.'));
-    $this->assertNoFieldById('edit-submit', t('Import all'));
-  }
-
-  /**
    * Tests the screen that shows differences between active and staging.
    */
   function testImportDiff() {
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
index 6af6295..59ea550 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
@@ -97,25 +97,6 @@ function testEmptyImportFails() {
   }
 
   /**
-   * Tests verification of site UUID before importing configuration.
-   */
-  function testSiteUuidValidate() {
-    $staging = \Drupal::service('config.storage.staging');
-    // Create updated configuration object.
-    $config_data = \Drupal::config('system.site')->get();
-    // Generate a new site UUID.
-    $config_data['uuid'] = \Drupal::service('uuid')->generate();
-    $staging->write('system.site', $config_data);
-    try {
-      $this->configImporter->reset()->import();
-      $this->assertFalse(FALSE, 'ConfigImporterException not thrown, invalid import was not stopped due to mis-matching site UUID.');
-    }
-    catch (ConfigImporterException $e) {
-      $this->assertEqual($e->getMessage(), 'Site UUID in source storage does not match the target storage.');
-    }
-  }
-
-  /**
    * Tests deletion of configuration during import.
    */
   function testDeleted() {
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
index b572708..4def427 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigMapperInterface.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Language\Language;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
 
 /**
  * Defines an interface for configuration mapper.
@@ -47,6 +48,16 @@ public function getBaseRouteParameters();
   public function getBaseRoute();
 
   /**
+   * Sets the base route object.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route object used as base route.
+   *
+   * @see \Drupal\config_translation\Routing\RouteSubscriber::alterRoutes()
+   */
+  public function setBaseRoute(Route $route);
+
+  /**
    * Returns a processed path for the base route the mapper is attached to.
    *
    * @return string
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php b/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
index 2df7387..cfbf6f8 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/ConfigNamesMapper.php
@@ -45,6 +45,13 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con
   protected $configMapperManager;
 
   /**
+   * The route provider.
+   *
+   * @var \Drupal\Core\Routing\RouteProvider
+   */
+  protected $routeProvider;
+
+  /**
    * The base route object that the mapper is attached to.
    *
    * @return \Symfony\Component\Routing\Route
@@ -95,10 +102,9 @@ public function __construct($plugin_id, array $plugin_definition, ConfigFactory
     $this->configFactory = $config_factory;
     $this->localeConfigManager = $locale_config_manager;
     $this->configMapperManager = $config_mapper_manager;
+    $this->routeProvider = $route_provider;
 
     $this->setTranslationManager($translation_manager);
-
-    $this->baseRoute = $route_provider->getRouteByName($this->getBaseRouteName());
   }
 
   /**
@@ -145,12 +151,25 @@ public function getBaseRouteParameters() {
    * {@inheritdoc}
    */
   public function getBaseRoute() {
+    // The base route cannot be set directly in the constructor because during
+    // route rebuilding we need to instantiate the mappers before the respective
+    // routes are available.
+    if (!isset($this->baseRoute)) {
+      $this->baseRoute = $this->routeProvider->getRouteByName($this->getBaseRouteName());
+    }
     return $this->baseRoute;
   }
 
   /**
    * {@inheritdoc}
    */
+  public function setBaseRoute(Route $route) {
+    $this->baseRoute = $route;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getBasePath() {
     return $this->getPathFromRoute($this->getBaseRoute(), $this->getBaseRouteParameters());
   }
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
index 335faa5..5aa1ff9 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Routing/RouteSubscriber.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Routing\RouteSubscriberBase;
 use Drupal\config_translation\ConfigMapperManagerInterface;
+use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
@@ -17,11 +18,32 @@
 class RouteSubscriber extends RouteSubscriberBase {
 
   /**
-   * The mapper plugin discovery service.
+   * An array of all configuration mappers, keyed by ID.
    *
-   * @var \Drupal\config_translation\ConfigMapperManagerInterface
+   * @var \Drupal\config_translation\ConfigMapperInterface[]
    */
-  protected $mapperManager;
+  protected $mappers;
+
+  /**
+   * An array of base route names.
+   *
+   * The array is keyed by the respective configuration mapper ID in order to
+   * map the each mapper to the base route it requires.
+   *
+   * @var array
+   */
+  protected $baseRouteNames = array();
+
+  /**
+   * An array of base route names that need to processed.
+   *
+   * At the beginning of each route rebuilding process this is identical to
+   * RouteSubscriber::$baseRouteNames and after route rebuilding this should
+   * be empty.
+   *
+   * @var array
+   */
+  protected $baseRouteNamesToProcess;
 
   /**
    * Constructs a new RouteSubscriber.
@@ -30,26 +52,67 @@ class RouteSubscriber extends RouteSubscriberBase {
    *   The mapper plugin discovery service.
    */
   public function __construct(ConfigMapperManagerInterface $mapper_manager) {
-    $this->mapperManager = $mapper_manager;
+    $this->mappers = $mapper_manager->getMappers();
+
+    // The entire list of base route names is needed so we can check each route
+    // collection for matching routes in RouteSubscriber::alterRoutes(). In
+    // order to pass the route information to the configuration mapper we then
+    // need the respective mapper ID for the base route name.
+    foreach ($this->mappers as $mapper_id => $mapper) {
+      $this->baseRouteNames[$mapper_id] = $mapper->getBaseRouteName();
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   protected function alterRoutes(RouteCollection $collection, $provider) {
-    // @todo \Drupal\config_translation\ConfigNamesMapper uses the route
-    //   provider directly, which is unsafe during rebuild. This currently only
-    //   works by coincidence; fix in https://drupal.org/node/2158571.
-    if ($provider != 'dynamic_routes') {
-      return;
+    // Reset RouteSubscriber::$baseRouteNamesToProcess at the beginning of the
+    // route rebuilding process.
+    if (!isset($this->baseRouteNamesToProcess)) {
+      $this->baseRouteNamesToProcess = $this->baseRouteNames;
     }
 
-    $mappers = $this->mapperManager->getMappers();
-    foreach ($mappers as $mapper) {
-      $collection->add($mapper->getOverviewRouteName(), $mapper->getOverviewRoute());
-      $collection->add($mapper->getAddRouteName(), $mapper->getAddRoute());
-      $collection->add($mapper->getEditRouteName(), $mapper->getEditRoute());
-      $collection->add($mapper->getDeleteRouteName(), $mapper->getDeleteRoute());
+    // Create an additional route collection for the translation routes.
+    $additional_collection = new RouteCollection();
+
+    foreach ($this->baseRouteNamesToProcess as $mapper_id => $route_name) {
+      if ($route = $collection->get($route_name)) {
+        $mapper = $this->mappers[$mapper_id];
+        $mapper->setBaseRoute($route);
+
+        $additional_collection->add($mapper->getOverviewRouteName(), $mapper->getOverviewRoute());
+        $additional_collection->add($mapper->getAddRouteName(), $mapper->getAddRoute());
+        $additional_collection->add($mapper->getEditRouteName(), $mapper->getEditRoute());
+        $additional_collection->add($mapper->getDeleteRouteName(), $mapper->getDeleteRoute());
+
+        // We do not need to check for the same base route name on the next
+        // invocation.
+        unset($this->baseRouteNamesToProcess[$mapper_id]);
+      }
+    }
+
+    if ($additional_collection->count()) {
+      // Allow the new routes to be altered before adding them to the given
+      // collection.
+      $this->invokeAdditionalAlter($additional_collection);
+      $collection->addCollection($additional_collection);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onFinishedRebuilding(Event $event) {
+    $base_route_names_to_process = $this->baseRouteNamesToProcess;
+    // Unset RouteSubscriber::$baseRouteNamesToProcess so that if route
+    // rebuilding happens again in the same request,
+    // RouteSubscriber::alterRoutes() will re-initialize it.
+    unset($this->baseRouteNamesToProcess);
+    // If there are any routes left after route rebuilding has finished,
+    // something has gone wrong.
+    if (!empty($base_route_names_to_process)) {
+      throw new \RuntimeException(sprintf('The following routes are needed by configuration mappers but were not found: %s', implode(', ', $base_route_names_to_process)));
     }
   }
 
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php
index 03ba59b..023687c 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php
@@ -80,12 +80,6 @@ public function setUp() {
     // Create and log in user.
     $this->adminUser = $this->drupalCreateUser($permissions);
     $this->drupalLogin($this->adminUser);
-
-    // Enable import of translations. By default this is disabled for automated
-    // tests.
-    \Drupal::config('locale.settings')
-      ->set('translation.import_enabled', TRUE)
-      ->save();
   }
 
   /**
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
index 83f4a14..dfda109 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
@@ -566,12 +566,6 @@ public function testViewsTranslationUI() {
    * Test translation storage in locale storage.
    */
   public function testLocaleDBStorage() {
-    // Enable import of translations. By default this is disabled for automated
-    // tests.
-    \Drupal::config('locale.settings')
-      ->set('translation.import_enabled', TRUE)
-      ->save();
-
     $this->drupalLogin($this->admin_user);
 
     $langcode = 'xx';
diff --git a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
index b7ed1f5..46911d2 100644
--- a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
+++ b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigEntityMapperTest.php
@@ -65,12 +65,6 @@ public function setUp() {
 
     $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
 
-    $this->routeProvider
-      ->expects($this->once())
-      ->method('getRouteByName')
-      ->with('language.edit')
-      ->will($this->returnValue(new Route('/admin/config/regional/language/edit/{language_entity}')));
-
     $definition = array(
       'class' => '\Drupal\config_translation\ConfigEntityMapper',
       'base_route_name' => 'language.edit',
diff --git a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
index 3df6ac0..b1e35b4 100644
--- a/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
+++ b/core/modules/config_translation/tests/Drupal/config_translation/Tests/ConfigNamesMapperTest.php
@@ -96,12 +96,6 @@ public function setUp() {
 
     $this->baseRoute = new Route('/admin/config/system/site-information');
 
-    $this->routeProvider
-      ->expects($this->once())
-      ->method('getRouteByName')
-      ->with('system.site_information_settings')
-      ->will($this->returnValue($this->baseRoute));
-
     $this->configNamesMapper = new TestConfigNamesMapper(
       'system.site_information_settings',
       $this->pluginDefinition,
@@ -138,9 +132,25 @@ public function testGetBaseRouteParameters() {
   }
 
   /**
-   * Tests ConfigNamesMapper::getBaseRoute().
+   * Tests ConfigNamesMapper::getBaseRoute() and setBaseRoute().
    */
-  public function testGetBaseRoute() {
+  public function testBaseRoute() {
+    // Test that the route can be set manually.
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
+    $result = $this->configNamesMapper->getBaseRoute();
+    $this->assertSame($this->baseRoute, $result);
+
+    // Test that the route is fetched from the route provider if it is not set.
+    $this->configNamesMapper->unsetBaseRoute();
+    $this->routeProvider
+      ->expects($this->once())
+      ->method('getRouteByName')
+      ->with('system.site_information_settings')
+      ->will($this->returnValue($this->baseRoute));
+    $result = $this->configNamesMapper->getBaseRoute();
+    $this->assertSame($this->baseRoute, $result);
+
+    // Test that the base route is stored on the mapper.
     $result = $this->configNamesMapper->getBaseRoute();
     $this->assertSame($this->baseRoute, $result);
   }
@@ -149,6 +159,7 @@ public function testGetBaseRoute() {
    * Tests ConfigNamesMapper::getBasePath().
    */
   public function testGetBasePath() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $result = $this->configNamesMapper->getBasePath();
     $this->assertSame('/admin/config/system/site-information', $result);
   }
@@ -174,6 +185,7 @@ public function testGetOverviewRouteParameters() {
    * Tests ConfigNamesMapper::getOverviewRoute().
    */
   public function testGetOverviewRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate',
       array(
         '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemPage',
@@ -191,6 +203,7 @@ public function testGetOverviewRoute() {
    * Tests ConfigNamesMapper::getOverviewPath().
    */
   public function testGetOverviewPath() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $result = $this->configNamesMapper->getOverviewPath();
     $this->assertSame('/admin/config/system/site-information/translate', $result);
   }
@@ -221,6 +234,7 @@ public function testGetAddRouteParameters() {
    * Tests ConfigNamesMapper::getAddRoute().
    */
   public function testGetAddRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/add',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationAddForm',
@@ -260,6 +274,7 @@ public function testGetEditRouteParameters() {
    * Tests ConfigNamesMapper::getEditRoute().
    */
   public function testGetEditRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/edit',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationEditForm',
@@ -298,6 +313,7 @@ public function testGetDeleteRouteParameters() {
    * Tests ConfigNamesMapper::getRoute().
    */
   public function testGetDeleteRoute() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = new Route('/admin/config/system/site-information/translate/{langcode}/delete',
       array(
         '_form' => '\Drupal\config_translation\Form\ConfigTranslationDeleteForm',
@@ -604,6 +620,7 @@ public function testGetTypeName() {
    * Tests ConfigNamesMapper::hasTranslation().
    */
   public function testGetOperations() {
+    $this->configNamesMapper->setBaseRoute($this->baseRoute);
     $expected = array(
       'translate' => array(
         'title' => 'Translate',
@@ -653,4 +670,11 @@ public function setConfigFactory(ConfigFactory $config_factory) {
     $this->configFactory = $config_factory;
   }
 
+  /**
+   * Unsets the base route that is stored in the mapper.
+   */
+  public function unsetBaseRoute() {
+    unset($this->baseRoute);
+  }
+
 }
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 70d20dc..7618840 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -75,30 +75,6 @@ function content_translation_language_types_info_alter(array &$language_types) {
 
 /**
  * Implements hook_entity_info_alter().
- *
- * The content translation UI relies on the entity info to provide its features.
- * See the documentation of hook_entity_info() in the Entity API documentation
- * for more details on all the entity info keys that may be defined.
- *
- * To make Content Translation automatically support an entity type some keys
- * may need to be defined, but none of them is required unless the entity path
- * is different from the usual /ENTITY_TYPE/{ENTITY_TYPE} pattern (for instance
- * "/taxonomy/term/{taxonomy_term}"), in which case at least the 'canonical' key
- * in the 'links' entity info property must be defined.
- *
- * Every entity type needs a translation controller to be translated. This can
- * be specified through the 'translation' key in the 'controllers' entity info
- * property. If an entity type is translatable and no translation controller is
- * defined, \Drupal\content_translation\ContentTranslationController will be
- * assumed. Every translation controller class must implement
- * \Drupal\content_translation\ContentTranslationControllerInterface.
- *
- * If the entity paths match the default pattern above and there is no need for
- * an entity-specific translation controller class, Content Translation will
- * provide built-in support for the entity. However enabling translation for
- * each translatable bundle will be required.
- *
- * @see \Drupal\Core\Entity\Annotation\EntityType
  */
 function content_translation_entity_info_alter(array &$entity_info) {
   // Provide defaults for translation info.
@@ -119,8 +95,6 @@ function content_translation_entity_info_alter(array &$entity_info) {
         if (!$info->hasLinkTemplate('drupal:content-translation-overview')) {
           $info->setLinkTemplate('drupal:content-translation-overview', "content_translation.translation_overview_$entity_type");
         }
-        // @todo Remove this as soon as menu access checks rely on the
-        //   controller. See https://drupal.org/node/2155787.
         $translation['content_translation'] += array(
           'access_callback' => 'content_translation_translate_access',
         );
diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc
index 43e5331..390063d 100644
--- a/core/modules/content_translation/content_translation.pages.inc
+++ b/core/modules/content_translation/content_translation.pages.inc
@@ -134,7 +134,7 @@ function content_translation_overview(EntityInterface $entity) {
     }
   }
 
-  $build['#title'] = t('Translations of %label', array('%label' => $entity->label()));
+  drupal_set_title(t('Translations of %label', array('%label' => $entity->label())), PASS_THROUGH);
 
   // Add metadata to the build render array to let other modules know about
   // which entity this is.
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerInterface.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerInterface.php
index 39e307b..ed68e8f 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerInterface.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerInterface.php
@@ -14,6 +14,31 @@
  *
  * Defines a set of methods to allow any entity to be processed by the entity
  * translation UI.
+ *
+ * The content translation UI relies on the entity info to provide its features.
+ * See the documentation of hook_entity_info() in the Entity API documentation
+ * for more details on all the entity info keys that may be defined.
+ *
+ * To make Content Translation automatically support an entity type some keys
+ * may need to be defined, but none of them is required unless the entity path
+ * is different from ENTITY_TYPE/%ENTITY_TYPE (e.g. taxonomy/term/1), in which
+ * case at least the 'canonical' key in the 'links' entity info property must be
+ * defined.
+ *
+ * Every entity type needs a translation controller to be translated. This can
+ * be specified through the "controllers['translation']" key in the entity
+ * info. If an entity type is enabled for translation and no translation
+ * controller is defined,
+ * \Drupal\content_translation\ContentTranslationController will be assumed.
+ * Every translation controller class must implement
+ * \Drupal\content_translation\ContentTranslationControllerInterface.
+ *
+ * If the entity paths match the default patterns above and there is no need for
+ * an entity-specific translation controller class, Content Translation will
+ * provide built-in support for the entity. It will still be required to enable
+ * translation for each translatable bundle.
+ *
+ * @see \Drupal\Core\Entity\EntityManagerInterface
  */
 interface ContentTranslationControllerInterface {
 
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
index 105489b..2b18a13 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
@@ -50,6 +50,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
        $path,
         array(
           '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
+          '_title' => 'Translate',
           'account' => 'NULL',
           '_entity_type' => $entity_type,
         ),
diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js
index 4616411..ab404a2 100644
--- a/core/modules/contextual/js/contextual.js
+++ b/core/modules/contextual/js/contextual.js
@@ -269,7 +269,7 @@ Drupal.contextual = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change', this.render);
+      this.model.on('change', this.render, this);
     },
 
     /**
@@ -308,9 +308,7 @@ Drupal.contextual = {
      * {@inheritdoc}
      */
     initialize: function (options) {
-      this.options = options;
-
-      this.listenTo(this.model, 'change', this.render);
+      this.model.on('change', this.render, this);
 
       // Use aria-role form so that the number of items in the list is spoken.
       this.$el.attr('role', 'form');
@@ -401,7 +399,7 @@ Drupal.contextual = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change:hasFocus', this.render);
+      this.model.on('change:hasFocus', this.render, this);
     },
 
     /**
diff --git a/core/modules/contextual/js/contextual.toolbar.js b/core/modules/contextual/js/contextual.toolbar.js
index 0c6a8b8..e1a01dd 100644
--- a/core/modules/contextual/js/contextual.toolbar.js
+++ b/core/modules/contextual/js/contextual.toolbar.js
@@ -20,19 +20,8 @@ var strings = {
  *   A contextual links DOM element as rendered by the server.
  */
 function initContextualToolbar (context) {
-  if (!Drupal.contextual || !Drupal.contextual.collection) {
-    return;
-  }
-
   var contextualToolbar = Drupal.contextualToolbar;
-  var model = contextualToolbar.model = new contextualToolbar.Model({
-    // Checks whether localStorage indicates we should start in edit mode
-    // rather than view mode.
-    // @see Drupal.contextualToolbar.VisualView.persist()
-    isViewing: localStorage.getItem('Drupal.contextualToolbar.isViewing') !== 'false'
-  }, {
-    contextualCollection: Drupal.contextual.collection,
-  });
+  var model = contextualToolbar.model = new contextualToolbar.Model();
 
   var viewOptions = {
     el: $('.toolbar .toolbar-bar .contextual-toolbar-tab'),
@@ -41,6 +30,36 @@ function initContextualToolbar (context) {
   };
   new contextualToolbar.VisualView(viewOptions);
   new contextualToolbar.AuralView(viewOptions);
+
+  // Show the edit tab while there's >=1 contextual link.
+  if (Drupal.contextual && Drupal.contextual.collection) {
+    var contextualCollection = Drupal.contextual.collection;
+    var trackContextualCount = function () {
+      model.set('contextualCount', contextualCollection.length);
+    };
+    contextualCollection.on('reset remove add', trackContextualCount);
+    trackContextualCount();
+
+    // Whenever edit mode is toggled, lock all contextual links.
+    model.on('change:isViewing', function() {
+      contextualCollection.each(function (contextualModel) {
+        contextualModel.set('isLocked', !model.get('isViewing'));
+      });
+    });
+    // When a new contextual link is added and edit mode is enabled, lock it.
+    contextualCollection.on('add', function (contextualModel) {
+      if (!model.get('isViewing')) {
+        contextualModel.set('isLocked', true);
+      }
+    });
+  }
+
+  // Checks whether localStorage indicates we should start in edit mode
+  // rather than view mode.
+  // @see Drupal.contextualToolbar.VisualView.persist()
+  if (localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false') {
+    model.set('isViewing', false);
+  }
 }
 
 /**
@@ -77,67 +96,10 @@ Drupal.contextualToolbar = {
       // of tabbable elements when edit mode is enabled.
       tabbingContext: null
     },
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param Object attrs
-     * @param Object options
-     *   An object with the following option:
-     *     - Backbone.collection contextualCollection: the collection of
-     *       Drupal.contextual.Model models that represent the contextual links
-     *       on the page.
-     */
-    initialize: function (attrs, options) {
-      // Respond to new/removed contextual links.
-      this.listenTo(options.contextualCollection, {
-        'reset remove add': this.countCountextualLinks,
-        'add': this.lockNewContextualLinks
-      });
-
-      this.listenTo(this, {
-        // Automatically determine visibility.
-        'change:contextualCount': this.updateVisibility,
-        // Whenever edit mode is toggled, lock all contextual links.
-        'change:isViewing': function (model, isViewing) {
-          options.contextualCollection.each(function (contextualModel) {
-            contextualModel.set('isLocked', !isViewing);
-          });
-        }
+    initialize: function () {
+      this.on('change:contextualCount', function (model) {
+        model.set('isVisible', model.get('contextualCount') > 0);
       });
-    },
-
-    /**
-     * Tracks the number of contextual link models in the collection.
-     *
-     * @param Drupal.contextual.Model affectedModel
-     *   The contextual links model that was added or removed.
-     * @param Backbone.Collection contextualCollection
-     *    The collection of contextual link models.
-     */
-    countCountextualLinks: function (contextualModel, contextualCollection) {
-      this.set('contextualCount', contextualCollection.length);
-    },
-
-    /**
-     * Lock newly added contextual links if edit mode is enabled.
-     *
-     * @param Drupal.contextual.Model addedContextualModel
-     *   The contextual links model that was added.
-     * @param Backbone.Collection contextualCollection
-     *    The collection of contextual link models.
-     */
-    lockNewContextualLinks: function (contextualModel, contextualCollection) {
-      if (!this.get('isViewing')) {
-        contextualModel.set('isLocked', true);
-      }
-    },
-
-    /**
-     * Automatically updates visibility of the view/edit mode toggle.
-     */
-    updateVisibility: function () {
-      this.set('isVisible', this.get('contextualCount') > 0);
     }
   }),
 
@@ -166,8 +128,8 @@ Drupal.contextualToolbar = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change', this.render);
-      this.listenTo(this.model, 'change:isViewing', this.persist);
+      this.model.on('change', this.render, this);
+      this.model.on('change:isViewing', this.persist, this);
     },
 
     /**
@@ -213,11 +175,9 @@ Drupal.contextualToolbar = {
     /*
      * {@inheritdoc}
      */
-    initialize: function (options) {
-      this.options = options;
-
-      this.listenTo(this.model, 'change', this.render);
-      this.listenTo(this.model, 'change:isViewing', this.manageTabbing);
+    initialize: function () {
+      this.model.on('change', this.render, this);
+      this.model.on('change:isViewing', this.manageTabbing, this);
 
       $(document).on('keyup', _.bind(this.onKeypress, this));
     },
diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module
index 3eaabcc..f425a69 100644
--- a/core/modules/edit/edit.module
+++ b/core/modules/edit/edit.module
@@ -61,7 +61,6 @@ function edit_library_info() {
       $path . '/js/edit.js' => $options,
       $path . '/js/util.js' => $options,
       // Models.
-      $path . '/js/models/BaseModel.js' => $options,
       $path . '/js/models/AppModel.js' => $options,
       $path . '/js/models/EntityModel.js' => $options,
       $path . '/js/models/FieldModel.js' => $options,
diff --git a/core/modules/edit/js/edit.js b/core/modules/edit/js/edit.js
index fe36fd1..429e7b2 100644
--- a/core/modules/edit/js/edit.js
+++ b/core/modules/edit/js/edit.js
@@ -275,7 +275,7 @@ function processField (fieldElement) {
 
   // If an EntityModel for this field already exists (and hence also a "Quick
   // edit" contextual link), then initialize it immediately.
-  if (Drupal.edit.collections.entities.findWhere({ entityID: entityID, entityInstanceID: entityInstanceID })) {
+  if (Drupal.edit.collections.entities.where({ entityID: entityID, entityInstanceID: entityInstanceID }).length > 0) {
     initializeField(fieldElement, fieldID, entityID, entityInstanceID);
   }
   // Otherwise: queue the field. It is now available to be set up when its
@@ -298,10 +298,10 @@ function processField (fieldElement) {
  *   The field's entity's instance ID.
  */
 function initializeField (fieldElement, fieldID, entityID, entityInstanceID) {
-  var entity = Drupal.edit.collections.entities.findWhere({
+  var entity = Drupal.edit.collections.entities.where({
     entityID: entityID,
     entityInstanceID: entityInstanceID
-  });
+  })[0];
 
   $(fieldElement).addClass('edit-field');
 
@@ -528,15 +528,17 @@ function initializeEntityContextualLink (contextualLink) {
 function deleteContainedModelsAndQueues($context) {
   $context.find('[data-edit-entity-id]').addBack('[data-edit-entity-id]').each(function (index, entityElement) {
     // Delete entity model.
-    var entityModel = Drupal.edit.collections.entities.findWhere({el: entityElement});
-    if (entityModel) {
-      var contextualLinkView = entityModel.get('contextualLinkView');
+    // @todo change to findWhere() as soon as we have Backbone 1.0 in Drupal
+    // core. @see https://drupal.org/node/1800022
+    var entityModels = Drupal.edit.collections.entities.where({el: entityElement});
+    if (entityModels.length) {
+      var contextualLinkView = entityModels[0].get('contextualLinkView');
       contextualLinkView.undelegateEvents();
       contextualLinkView.remove();
       // Remove the EntityDecorationView.
-      entityModel.get('entityDecorationView').remove();
+      entityModels[0].get('entityDecorationView').remove();
       // Destroy the EntityModel; this will also destroy its FieldModels.
-      entityModel.destroy();
+      entityModels[0].destroy();
     }
 
     // Filter queue.
diff --git a/core/modules/edit/js/models/BaseModel.js b/core/modules/edit/js/models/BaseModel.js
deleted file mode 100644
index d7870b6..0000000
--- a/core/modules/edit/js/models/BaseModel.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file
- * A Backbone Model subclass that enforces validation when calling set().
- */
-
-(function (Backbone) {
-
-"use strict";
-
-Drupal.edit.BaseModel = Backbone.Model.extend({
-
-  /**
-   * {@inheritdoc}
-   */
-  initialize: function (options) {
-    this.__initialized = true;
-    return Backbone.Model.prototype.initialize.call(this, options);
-  },
-
-  /**
-   * {@inheritdoc}
-   */
-  set: function (key, val, options) {
-    if (this.__initialized) {
-      // Deal with both the "key", value and {key:value}-style arguments.
-      if (typeof key === 'object') {
-        key.validate = true;
-      }
-      else {
-        if (!options) {
-          options = {};
-        }
-        options.validate = true;
-      }
-    }
-    return Backbone.Model.prototype.set.call(this, key, val, options);
-  }
-
-});
-
-}(Backbone));
diff --git a/core/modules/edit/js/models/EntityModel.js b/core/modules/edit/js/models/EntityModel.js
index 2e592e3..7358bcb 100644
--- a/core/modules/edit/js/models/EntityModel.js
+++ b/core/modules/edit/js/models/EntityModel.js
@@ -7,7 +7,7 @@
 
 "use strict";
 
-Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({
+Drupal.edit.EntityModel = Backbone.Model.extend({
 
   defaults: {
     // The DOM element that represents this entity. It may seem bizarre to
@@ -62,14 +62,11 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({
     this.set('fields', new Drupal.edit.FieldCollection());
 
     // Respond to entity state changes.
-    this.listenTo(this, 'change:state', this.stateChange);
+    this.on('change:state', this.stateChange, this);
 
     // The state of the entity is largely dependent on the state of its
     // fields.
-    this.listenTo(this.get('fields'), 'change:state', this.fieldStateChange);
-
-    // Call Drupal.edit.BaseModel's initialize() method.
-    Drupal.edit.BaseModel.prototype.initialize.call(this);
+    this.get('fields').on('change:state', this.fieldStateChange, this);
   },
 
   /**
@@ -514,9 +511,9 @@ Drupal.edit.EntityModel = Drupal.edit.BaseModel.extend({
    * @inheritdoc
    */
   destroy: function (options) {
-    Drupal.edit.BaseModel.prototype.destroy.call(this, options);
+    Backbone.Model.prototype.destroy.apply(this, options);
 
-    this.stopListening();
+    this.off(null, null, this);
 
     // Destroy all fields of this entity.
     this.get('fields').each(function (fieldModel) {
diff --git a/core/modules/edit/js/models/FieldModel.js b/core/modules/edit/js/models/FieldModel.js
index ea537a0..a9d3021 100644
--- a/core/modules/edit/js/models/FieldModel.js
+++ b/core/modules/edit/js/models/FieldModel.js
@@ -10,7 +10,7 @@
 /**
  * State of an in-place editable field in the DOM.
  */
-Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({
+Drupal.edit.FieldModel = Backbone.Model.extend({
 
   defaults: {
     // The DOM element that represents this field. It may seem bizarre to have
@@ -73,9 +73,6 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({
 
     // Automatically generate the logical field ID.
     this.set('logicalFieldID', this.get('fieldID').split('/').slice(0, 4).join('/'));
-
-    // Call Drupal.edit.BaseModel's initialize() method.
-    Drupal.edit.BaseModel.prototype.initialize.call(this, options);
   },
 
   /**
@@ -85,7 +82,7 @@ Drupal.edit.FieldModel = Drupal.edit.BaseModel.extend({
     if (this.get('state') !== 'inactive') {
       throw new Error("FieldModel cannot be destroyed if it is not inactive state.");
     }
-    Drupal.edit.BaseModel.prototype.destroy.call(this, options);
+    Backbone.Model.prototype.destroy.call(this, options);
   },
 
   /**
diff --git a/core/modules/edit/js/views/AppView.js b/core/modules/edit/js/views/AppView.js
index 93caf5c..3c842f2 100644
--- a/core/modules/edit/js/views/AppView.js
+++ b/core/modules/edit/js/views/AppView.js
@@ -36,21 +36,21 @@ Drupal.edit.AppView = Backbone.View.extend({
     this.changedFieldStates = ['changed', 'saving', 'saved', 'invalid'];
     this.readyFieldStates = ['candidate', 'highlighted'];
 
-    this.listenTo(options.entitiesCollection, {
+    options.entitiesCollection
       // Track app state.
-      'change:state': this.appStateChange,
-      'change:isActive': this.enforceSingleActiveEntity
-    });
+      .on('change:state', this.appStateChange, this)
+      .on('change:isActive', this.enforceSingleActiveEntity, this);
 
-    // Track app state.
-    this.listenTo(options.fieldsCollection, 'change:state', this.editorStateChange);
-    // Respond to field model HTML representation change events.
-    this.listenTo(options.fieldsCollection, 'change:html', this.renderUpdatedField);
-    this.listenTo(options.fieldsCollection, 'change:html', this.propagateUpdatedField);
-    // Respond to addition.
-    this.listenTo(options.fieldsCollection, 'add', this.rerenderedFieldToCandidate);
-    // Respond to destruction.
-    this.listenTo(options.fieldsCollection, 'destroy', this.teardownEditor);
+    options.fieldsCollection
+      // Track app state.
+      .on('change:state', this.editorStateChange, this)
+      // Respond to field model HTML representation change events.
+      .on('change:html', this.propagateUpdatedField, this)
+      .on('change:html', this.renderUpdatedField, this)
+      // Respond to addition.
+      .on('add', this.rerenderedFieldToCandidate, this)
+      // Respond to destruction.
+      .on('destroy', this.teardownEditor, this);
   },
 
   /**
@@ -540,10 +540,10 @@ Drupal.edit.AppView = Backbone.View.extend({
    *   A field that was just added to the collection of fields.
    */
   rerenderedFieldToCandidate: function (fieldModel) {
-    var activeEntity = Drupal.edit.collections.entities.findWhere({isActive: true});
+    var activeEntity = Drupal.edit.collections.entities.where({isActive: true})[0];
 
     // Early-return if there is no active entity.
-    if (!activeEntity) {
+    if (activeEntity === null) {
       return;
     }
 
diff --git a/core/modules/edit/js/views/ContextualLinkView.js b/core/modules/edit/js/views/ContextualLinkView.js
index 65a6077..3e9dee6 100644
--- a/core/modules/edit/js/views/ContextualLinkView.js
+++ b/core/modules/edit/js/views/ContextualLinkView.js
@@ -39,7 +39,7 @@ Drupal.edit.ContextualLinkView = Backbone.View.extend({
     // Initial render.
     this.render();
     // Re-render whenever this entity's isActive attribute changes.
-    this.listenTo(this.model, 'change:isActive', this.render);
+    this.model.on('change:isActive', this.render, this);
   },
 
   /**
diff --git a/core/modules/edit/js/views/EditorView.js b/core/modules/edit/js/views/EditorView.js
index a00432d..ce57d6f 100644
--- a/core/modules/edit/js/views/EditorView.js
+++ b/core/modules/edit/js/views/EditorView.js
@@ -40,7 +40,7 @@ Drupal.edit.EditorView = Backbone.View.extend({
    */
   initialize: function (options) {
     this.fieldModel = options.fieldModel;
-    this.listenTo(this.fieldModel, 'change:state', this.stateChange);
+    this.fieldModel.on('change:state', this.stateChange, this);
   },
 
   /**
@@ -50,6 +50,7 @@ Drupal.edit.EditorView = Backbone.View.extend({
     // The el property is the field, which should not be removed. Remove the
     // pointer to it, then call Backbone.View.prototype.remove().
     this.setElement();
+    this.fieldModel.off(null, null, this);
     Backbone.View.prototype.remove.call(this);
   },
 
diff --git a/core/modules/edit/js/views/EntityDecorationView.js b/core/modules/edit/js/views/EntityDecorationView.js
index ad107f9..f6fcb75 100644
--- a/core/modules/edit/js/views/EntityDecorationView.js
+++ b/core/modules/edit/js/views/EntityDecorationView.js
@@ -15,7 +15,7 @@ Drupal.edit.EntityDecorationView = Backbone.View.extend({
    * Associated with the DOM root node of an editable entity.
    */
   initialize: function () {
-    this.listenTo(this.model, 'change', this.render);
+    this.model.on('change', this.render, this);
   },
 
   /**
diff --git a/core/modules/edit/js/views/EntityToolbarView.js b/core/modules/edit/js/views/EntityToolbarView.js
index 889335a..a2906aa 100644
--- a/core/modules/edit/js/views/EntityToolbarView.js
+++ b/core/modules/edit/js/views/EntityToolbarView.js
@@ -29,11 +29,11 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({
     this.$entity = $(this.model.get('el'));
 
     // Rerender whenever the entity state changes.
-    this.listenTo(this.model, 'change:isActive change:isDirty change:state', this.render);
+    this.model.on('change:isActive change:isDirty change:state', this.render, this);
     // Also rerender whenever a different field is highlighted or activated.
-    this.listenTo(this.appModel, 'change:highlightedField change:activeField', this.render);
+    this.appModel.on('change:highlightedField change:activeField', this.render, this);
     // Rerender when a field of the entity changes state.
-    this.listenTo(this.model.get('fields'), 'change:state', this.fieldStateChange);
+    this.model.get('fields').on('change:state', this.fieldStateChange, this);
 
     // Reposition the entity toolbar as the viewport and the position within the
     // viewport changes.
@@ -121,6 +121,8 @@ Drupal.edit.EntityToolbarView = Backbone.View.extend({
     this.$fence.remove();
 
     // Stop listening to additional events.
+    this.appModel.off(null, null, this);
+    this.model.get('fields').off(null, null, this);
     $(window).off('resize.edit scroll.edit');
     $(document).off('drupalViewportOffsetChange.edit');
 
diff --git a/core/modules/edit/js/views/FieldDecorationView.js b/core/modules/edit/js/views/FieldDecorationView.js
index 4172840..4dfc403 100644
--- a/core/modules/edit/js/views/FieldDecorationView.js
+++ b/core/modules/edit/js/views/FieldDecorationView.js
@@ -29,8 +29,8 @@ Drupal.edit.FieldDecorationView = Backbone.View.extend({
   initialize: function (options) {
     this.editorView = options.editorView;
 
-    this.listenTo(this.model, 'change:state', this.stateChange);
-    this.listenTo(this.model, 'change:isChanged change:inTempStore', this.renderChanged);
+    this.model.on('change:state', this.stateChange, this);
+    this.model.on('change:isChanged change:inTempStore', this.renderChanged, this);
   },
 
   /**
diff --git a/core/modules/edit/js/views/FieldToolbarView.js b/core/modules/edit/js/views/FieldToolbarView.js
index 8aee09f..49e5b27 100644
--- a/core/modules/edit/js/views/FieldToolbarView.js
+++ b/core/modules/edit/js/views/FieldToolbarView.js
@@ -28,7 +28,7 @@ Drupal.edit.FieldToolbarView = Backbone.View.extend({
     // Generate a DOM-compatible ID for the form container DOM element.
     this._id = 'edit-toolbar-for-' + this.model.id.replace(/[\/\[\]]/g, '_');
 
-    this.listenTo(this.model, 'change:state', this.stateChange)
+    this.model.on('change:state', this.stateChange, this);
   },
 
   /**
diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php
index 4621f94..2c14041 100644
--- a/core/modules/edit/lib/Drupal/edit/EditController.php
+++ b/core/modules/edit/lib/Drupal/edit/EditController.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\edit;
 
+use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
@@ -17,19 +18,21 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\field\FieldInfo;
+use Drupal\edit\MetadataGeneratorInterface;
+use Drupal\edit\EditorSelectorInterface;
 use Drupal\edit\Ajax\FieldFormCommand;
 use Drupal\edit\Ajax\FieldFormSavedCommand;
 use Drupal\edit\Ajax\FieldFormValidationErrorsCommand;
 use Drupal\edit\Ajax\EntitySavedCommand;
 use Drupal\edit\Ajax\MetadataCommand;
+use Drupal\edit\Form\EditFieldForm;
 use Drupal\user\TempStoreFactory;
 
 /**
  * Returns responses for Edit module routes.
  */
-class EditController implements ContainerInjectionInterface {
+class EditController extends ContainerAware implements ContainerInjectionInterface {
 
   /**
    * The TempStore factory.
@@ -67,13 +70,6 @@ class EditController implements ContainerInjectionInterface {
   protected $fieldInfo;
 
   /**
-   * The form builder.
-   *
-   * @var \Drupal\Core\Form\FormBuilderInterface
-   */
-  protected $formBuilder;
-
-  /**
    * The module handler.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -93,18 +89,15 @@ class EditController implements ContainerInjectionInterface {
    *   The entity manager.
    * @param \Drupal\field\FieldInfo $field_info
    *   The field info service.
-   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
-   *   The form builder.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
    */
-  public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector, EntityManagerInterface $entity_manager, FieldInfo $field_info, FormBuilderInterface $form_builder, ModuleHandlerInterface $module_handler) {
+  public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector, EntityManagerInterface $entity_manager, FieldInfo $field_info, ModuleHandlerInterface $module_handler) {
     $this->tempStoreFactory = $temp_store_factory;
     $this->metadataGenerator = $metadata_generator;
     $this->editorSelector = $editor_selector;
     $this->entityManager = $entity_manager;
     $this->fieldInfo = $field_info;
-    $this->formBuilder = $form_builder;
     $this->moduleHandler = $module_handler;
   }
 
@@ -118,7 +111,6 @@ public static function create(ContainerInterface $container) {
       $container->get('edit.editor.selector'),
       $container->get('entity.manager'),
       $container->get('field.info'),
-      $container->get('form_builder'),
       $container->get('module_handler')
     );
   }
@@ -226,14 +218,16 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
       $this->tempStoreFactory->get('edit')->set($entity->uuid(), $entity);
     }
 
+    $form_object = EditFieldForm::create($this->container);
     $form_state = array(
       'langcode' => $langcode,
       'no_redirect' => TRUE,
       'build_info' => array(
         'args' => array($entity, $field_name),
+        'callback_object' => $form_object,
       ),
     );
-    $form = $this->formBuilder->buildForm('Drupal\edit\Form\EditFieldForm', $form_state);
+    $form = drupal_build_form($form_object->getFormId(), $form_state);
 
     if (!empty($form_state['executed'])) {
       // The form submission saved the entity in TempStore. Return the
@@ -264,7 +258,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
     else {
       $response->addCommand(new FieldFormCommand(drupal_render($form)));
 
-      $errors = $this->formBuilder->getErrors($form_state);
+      $errors = form_get_errors($form_state);
       if (count($errors)) {
         $status_messages = array(
           '#theme' => 'status_messages'
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 3f59be4..6d34707 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -358,6 +358,24 @@ function hook_field_attach_extract_form_values(\Drupal\Core\Entity\EntityInterfa
 }
 
 /**
+ * Alter field_attach_preprocess() variables.
+ *
+ * This hook is invoked while preprocessing field templates in
+ * field_attach_preprocess().
+ *
+ * @param $variables
+ *   The variables array is passed by reference and will be populated with field
+ *   values.
+ * @param $context
+ *   An associative array containing:
+ *   - entity: The entity with fields to render.
+ *   - element: The structured array containing the values ready for rendering.
+ */
+function hook_field_attach_preprocess_alter(&$variables, $context) {
+  // @todo Needs function body.
+}
+
+/**
  * Perform alterations on field_attach_view() or field_view_field().
  *
  * This hook is invoked after the field module has performed the operation.
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index f800519..75ee6a2 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -266,5 +266,37 @@ function _field_invoke_widget_target($form_display) {
 }
 
 /**
+ * Populates the template variables with the available field values.
+ *
+ * The $variables array will be populated with all the field instance values
+ * associated with the given entity type, keyed by field name; in case of
+ * translatable fields the language currently chosen for display will be
+ * selected.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity with fields to render.
+ * @param $element
+ *   The structured array containing the values ready for rendering.
+ * @param $variables
+ *   The variables array is passed by reference and will be populated with field
+ *   values.
+ */
+function field_attach_preprocess(EntityInterface $entity, $element, &$variables) {
+  foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $field_name => $instance) {
+    if (isset($element[$field_name]['#language'])) {
+      $langcode = $element[$field_name]['#language'];
+      $variables[$field_name] = $entity->getTranslation($langcode)->{$field_name}->getValue();
+    }
+  }
+
+  // Let other modules make changes to the $variables array.
+  $context = array(
+    'entity' => $entity,
+    'element' => $element,
+  );
+  drupal_alter('field_attach_preprocess', $variables, $context);
+}
+
+/**
  * @} End of "defgroup field_attach".
  */
diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc
index 02f60e3..31c6758 100644
--- a/core/modules/field/field.deprecated.inc
+++ b/core/modules/field/field.deprecated.inc
@@ -7,11 +7,157 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\field\Field;
 
 /**
+ * Returns information about field types.
+ *
+ * @param $field_type
+ *   (optional) A field type name. If omitted, all field types will be returned.
+ *
+ * @return
+ *   Either a field type definition, or an array of all existing field types,
+ *   keyed by field type name.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefinition()
+ *   or
+ *   \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions().
+ */
+function field_info_field_types($field_type = NULL) {
+  if ($field_type) {
+    return \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_type);
+  }
+  else {
+    return \Drupal::service('plugin.manager.field.field_type')->getConfigurableDefinitions();
+  }
+}
+
+/**
+ * Returns a field type's default settings.
+ *
+ * @param $type
+ *   A field type name.
+ *
+ * @return
+ *   The field type's default settings, or an empty array if type or settings
+ *   are not defined.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefaultSettings()
+ */
+function field_info_field_settings($type) {
+  return \Drupal::service('plugin.manager.field.field_type')->getDefaultSettings($type);
+}
+
+/**
+ * Returns a field type's default instance settings.
+ *
+ * @param $type
+ *   A field type name.
+ *
+ * @return
+ *   The field type's default instance settings, or an empty array if type or
+ *   settings are not defined.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.field_type')->getDefaultInstanceSettings()
+ */
+function field_info_instance_settings($type) {
+  return \Drupal::service('plugin.manager.field.field_type')->getDefaultInstanceSettings($type);
+}
+
+/**
+ * Returns information about field widgets from AnnotatedClassDiscovery.
+ *
+ * @param string $widget_type
+ *   (optional) A widget type name. If omitted, all widget types will be
+ *   returned.
+ *
+ * @return array
+ *   Either a single widget type description, as provided by class annotations,
+ *   or an array of all existing widget types, keyed by widget type name.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.widget')->getDefinition()
+ *   or
+ *   \Drupal::service('plugin.manager.field.widget')->getDefinitions()
+ */
+function field_info_widget_types($widget_type = NULL) {
+  if ($widget_type) {
+    return \Drupal::service('plugin.manager.field.widget')->getDefinition($widget_type);
+  }
+  else {
+    return \Drupal::service('plugin.manager.field.widget')->getDefinitions();
+  }
+}
+
+/**
+ * Returns a field widget's default settings.
+ *
+ * @param $type
+ *   A widget type name.
+ *
+ * @return
+ *   The widget type's default settings, as provided by
+ *   hook_field_widget_info(), or an empty array if type or settings are
+ *   undefined.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.widget')->getDefaultSettings()
+ */
+function field_info_widget_settings($type) {
+  return \Drupal::service('plugin.manager.field.widget')->getDefaultSettings($type);
+}
+
+/**
+ * Returns information about field formatters from hook_field_formatter_info().
+ *
+ * @param string $formatter_type
+ *   (optional) A formatter type name. If omitted, all formatter types will be
+ *   returned.
+ *
+ * @return array
+ *   Either a single formatter type description, as provided by class
+ *   annotations, or an array of all existing formatter types, keyed by
+ *   formatter type name.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.formatter')->getDefinition()
+ *   or
+ *   \Drupal::service('plugin.manager.field.formatter')->getDefinitions()
+ */
+function field_info_formatter_types($formatter_type = NULL) {
+  if ($formatter_type) {
+    return \Drupal::service('plugin.manager.field.formatter')->getDefinition($formatter_type);
+  }
+  else {
+    return \Drupal::service('plugin.manager.field.formatter')->getDefinitions();
+  }
+}
+
+/**
+ * Returns a field formatter's default settings.
+ *
+ * @param $type
+ *   A field formatter type name.
+ *
+ * @return
+ *   The formatter type's default settings, as provided by
+ *   hook_field_formatter_info(), or an empty array if type or settings are
+ *   undefined.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings()
+ */
+function field_info_formatter_settings($type) {
+  return \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings($type);
+}
+
+/**
  * Returns a lightweight map of fields across bundles.
  *
  * The function only returns non-deleted fields.
@@ -176,6 +322,120 @@ function field_info_instance($entity_type, $field_name, $bundle_name) {
 }
 
 /**
+ * Reads a single field record directly from the database.
+ *
+ * Generally, you should use the field_info_field() instead.
+ *
+ * This function will not return deleted fields. Use field_read_fields() instead
+ * for this purpose.
+ *
+ * @param $entity_type
+ *   The entity type.
+ * @param $field_name
+ *   The field name to read.
+ * @param array $include_additional
+ *   Additional properties to match.
+ *
+ * @return
+ *   A field definition array, or FALSE.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   entity_load('field_entity', 'field_name').
+ */
+function field_read_field($entity_type, $field_name, $include_additional = array()) {
+  $fields = field_read_fields(array('entity_type' => $entity_type, 'name' => $field_name), $include_additional);
+  return $fields ? current($fields) : FALSE;
+}
+
+/**
+ * Reads in fields that match an array of conditions.
+ *
+ * @param array $conditions
+ *   An array of conditions to match against. Keys are names of properties
+ *   found in field configuration files, and values are conditions to match.
+ * @param array $include_additional
+ *   The default behavior of this function is to not return fields that have
+ *   been deleted. Setting $include_additional['include_deleted'] to TRUE will
+ *   override this behavior.
+ *
+ * @return
+ *   An array of fields matching $params. If
+ *   $include_additional['include_deleted'] is TRUE, the array is keyed by
+ *   field ID, otherwise it is keyed by field name.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   entity_load_multiple_by_properties('field_entity', $conditions).
+ */
+function field_read_fields($conditions = array(), $include_additional = array()) {
+  // Include deleted fields if specified either in the $include_additional or
+  // the $conditions parameters.
+  $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']);
+
+  // Pass include_deleted to the $conditions array.
+  $conditions['include_deleted'] = $include_deleted;
+
+  return entity_load_multiple_by_properties('field_entity', $conditions);
+}
+
+/**
+ * Reads a single instance record from the database.
+ *
+ * Generally, you should use field_info_instance() instead, as it provides
+ * caching and allows other modules the opportunity to append additional
+ * formatters, widgets, and other information.
+ *
+ * @param $entity_type
+ *   The type of entity to which the field is bound.
+ * @param $field_name
+ *   The field name to read.
+ * @param $bundle
+ *   The bundle to which the field is bound.
+ * @param array $include_additional
+ *   The default behavior of this function is to not return an instance that has
+ *   been deleted. Setting $include_additional['include_deleted'] to TRUE will
+ *   override this behavior.
+ *
+ * @return
+ *   An instance structure, or FALSE.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   entity_load('field_instance', 'field_name').
+ */
+function field_read_instance($entity_type, $field_name, $bundle, $include_additional = array()) {
+  $instances = field_read_instances(array('entity_type' => $entity_type, 'field_name' => $field_name, 'bundle' => $bundle), $include_additional);
+  return $instances ? current($instances) : FALSE;
+}
+
+/**
+ * Reads in field instances that match an array of conditions.
+ *
+ * @param $param
+ *   An array of properties to use in selecting a field instance. Keys are names
+ *   of properties found in field instance configuration files, and values are
+ *   conditions to match.
+ * @param $include_additional
+ *   The default behavior of this function is to not return field instances that
+ *   have been marked deleted. Setting
+ *   $include_additional['include_deleted'] to TRUE will override this behavior.
+ *
+ * @return
+ *   An array of instances matching the arguments.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   entity_load_multiple_by_properties('field_instance', $conditions).
+ */
+function field_read_instances($conditions = array(), $include_additional = array()) {
+  // Include deleted instances if specified either in the $include_additional
+  // or the $conditions parameters.
+  $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']);
+
+  // Pass include_deleted to the $conditions array.
+  $conditions['include_deleted'] = $include_deleted;
+
+  return entity_load_multiple_by_properties('field_instance', $conditions);
+}
+
+/**
  * Adds form elements for all fields for an entity to a form structure.
  *
  * The form elements for the entity's fields are added by reference as direct
@@ -495,3 +755,75 @@ function field_attach_view(EntityInterface $entity, EntityViewDisplayInterface $
 
   return $output;
 }
+
+/**
+ * Returns the field items in the language they currently would be displayed.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity containing the data to be displayed.
+ * @param $field_name
+ *   The field to be displayed.
+ * @param $langcode
+ *   (optional) The language code $entity->{$field_name} has to be displayed in.
+ *   Defaults to the current language.
+ *
+ * @return
+ *   An array with available field items keyed by delta.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   $entity->getTranslation($langcode)->{$field_name}
+ */
+function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) {
+  return \Drupal::entityManager()->getTranslationFromContext($entity, $langcode)->{$field_name};
+}
+
+/**
+ * Helper function to get the default value for a field on an entity.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity for the operation.
+ * @param $field
+ *   The field structure.
+ * @param $instance
+ *   The instance structure.
+ * @param $langcode
+ *   The field language to fill-in with the default value.
+ *
+ * @return array
+ *   The default value for the field.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   $instance->getDefaultValue($entity)
+ */
+function field_get_default_value(EntityInterface $entity, $field, $instance, $langcode = NULL) {
+  return $instance->getDefaultValue($entity);
+}
+
+/**
+ * Determines whether the user has access to a given field.
+ *
+ * @param string $op
+ *   The operation to be performed. Possible values:
+ *   - edit
+ *   - view
+ * @param \Drupal\field\FieldInterface $field
+ *   The field on which the operation is to be performed.
+ * @param $entity_type
+ *   The type of $entity; for example, 'node' or 'user'.
+ * @param $entity
+ *   (optional) The entity for the operation.
+ * @param $account
+ *   (optional) The account to check, if not given use currently logged in user.
+ *
+ * @return
+ *   TRUE if the operation is allowed; FALSE if the operation is denied.
+ *
+ * @deprecated as of Drupal 8.0. Use
+ *   Drupal\Core\Entity\EntityAccessControllerInterface::fieldAccess()
+ */
+function field_access($op, FieldInterface $field, $entity_type, $entity = NULL, $account = NULL) {
+  $access_controller = \Drupal::entityManager()->getAccessController($entity_type);
+
+  $items = $entity ? $entity->get($field->id()) : NULL;
+  return $access_controller->fieldAccess($op, $field, $account, $items);
+}
diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php
index b127979..098d83f 100644
--- a/core/modules/field/lib/Drupal/field/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Entity/Field.php
@@ -515,10 +515,10 @@ public function getType() {
    * {@inheritdoc}
    */
   public function getSettings() {
-    // @todo FieldTypePluginManager maintains its own static cache. However, do
-    //   some CPU and memory profiling to see if it's worth statically caching
-    //   $field_type_info, or the default field and instance settings, within
-    //   $this.
+    // @todo field_info_field_types() calls _field_info_collate_types() which
+    //   maintains its own static cache. However, do some CPU and memory
+    //   profiling to see if it's worth statically caching $field_type_info, or
+    //   the default field and instance settings, within $this.
     $field_type_info = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->type);
 
     $settings = $this->settings + $field_type_info['settings'] + $field_type_info['instance_settings'];
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
index ccd6cd1..8f77373 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -160,6 +160,18 @@ function testFieldAttachView() {
 
     // TODO:
     // - check display order with several fields
+
+    // Preprocess template.
+    $variables = array();
+    field_attach_preprocess($entity, $entity->content, $variables);
+    $result = TRUE;
+    foreach ($values as $delta => $item) {
+      if ($variables[$this->field_name][$delta]['value'] !== $item['value']) {
+        $result = FALSE;
+        break;
+      }
+    }
+    $this->assertTrue($result, format_string('Variable $@field_name correctly populated.', array('@field_name' => $this->field_name)));
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
index b2a0b15..7509fbd 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
@@ -81,7 +81,7 @@ function setUp() {
 
     $this->installConfig(array('language'));
 
-    $this->field_name = drupal_strtolower($this->randomName());
+    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
 
     $this->entity_type = 'entity_test';
 
@@ -92,16 +92,16 @@ function setUp() {
       'cardinality' => 4,
       'translatable' => TRUE,
     );
-    $this->field = entity_create('field_entity', $this->field_definition);
-    $this->field->save();
+    entity_create('field_entity', $this->field_definition)->save();
+    $this->field = entity_load('field_entity', $this->entity_type . '.' . $this->field_name);
 
     $this->instance_definition = array(
       'field_name' => $this->field_name,
       'entity_type' => $this->entity_type,
       'bundle' => 'entity_test',
     );
-    $this->instance = entity_create('field_instance', $this->instance_definition);
-    $this->instance->save();
+    entity_create('field_instance', $this->instance_definition)->save();
+    $this->instance = entity_load('field_instance', 'entity_test.' . $this->instance_definition['bundle'] . '.' . $this->field_name);
 
     for ($i = 0; $i < 3; ++$i) {
       $language = new Language(array(
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
index b78a88f..5355f56 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
@@ -39,6 +39,9 @@ public function __construct(EntityManagerInterface $manager) {
    * {@inheritdoc}
    */
   protected function alterRoutes(RouteCollection $collection, $provider) {
+    // Create an additional route collection for the field UI routes.
+    $additional_collection = new RouteCollection();
+
     foreach ($this->manager->getDefinitions() as $entity_type => $entity_info) {
       $defaults = array();
       if ($entity_info->isFieldable() && $entity_info->hasLinkTemplate('admin-form')) {
@@ -56,21 +59,21 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ),
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.instance_edit_$entity_type", $route);
+        $additional_collection->add("field_ui.instance_edit_$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/field",
           array('_form' => '\Drupal\field_ui\Form\FieldEditForm'),
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.field_edit_$entity_type", $route);
+        $additional_collection->add("field_ui.field_edit_$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/delete",
           array('_entity_form' => 'field_instance.delete'),
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.delete_$entity_type", $route);
+        $additional_collection->add("field_ui.delete_$entity_type", $route);
 
         // If the entity type has no bundles, use the entity type.
         $defaults['entity_type'] = $entity_type;
@@ -85,7 +88,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_permission' => 'administer ' . $entity_type . ' fields')
         );
-        $collection->add("field_ui.overview_$entity_type", $route);
+        $additional_collection->add("field_ui.overview_$entity_type", $route);
 
         $route = new Route(
           "$path/form-display",
@@ -95,7 +98,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display')
         );
-        $collection->add("field_ui.form_display_overview_$entity_type", $route);
+        $additional_collection->add("field_ui.form_display_overview_$entity_type", $route);
 
         $route = new Route(
           "$path/form-display/{form_mode_name}",
@@ -105,7 +108,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display')
         );
-        $collection->add("field_ui.form_display_overview_form_mode_$entity_type", $route);
+        $additional_collection->add("field_ui.form_display_overview_form_mode_$entity_type", $route);
 
         $route = new Route(
           "$path/display",
@@ -115,7 +118,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display')
         );
-        $collection->add("field_ui.display_overview_$entity_type", $route);
+        $additional_collection->add("field_ui.display_overview_$entity_type", $route);
 
         $route = new Route(
           "$path/display/{view_mode_name}",
@@ -125,9 +128,16 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
           ) + $defaults,
           array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display')
         );
-        $collection->add("field_ui.display_overview_view_mode_$entity_type", $route);
+        $additional_collection->add("field_ui.display_overview_view_mode_$entity_type", $route);
       }
     }
+
+    if ($additional_collection->count()) {
+      // Allow the new routes to be altered before adding them to the given
+      // collection.
+      $this->invokeAdditionalAlter($additional_collection);
+      $collection->addCollection($additional_collection);
+    }
   }
 
   /**
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 1c13188..10830d1 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -860,7 +860,7 @@ function file_save_upload($form_field_name, array &$form_state, $validators = ar
     // evaluates to TRUE.
     if (!\Drupal::config('system.file')->get('allow_insecure_uploads') && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->getFilename()) && (substr($file->getFilename(), -4) != '.txt')) {
       $file->setMimeType('text/plain');
-      // The destination filename will also later be used to create the URI.
+      $file->setFileUri($file->getFileUri() . '.txt');
       $file->setFilename($file->getFilename() . '.txt');
       // The .txt extension may not be in the allowed list of extensions. We have
       // to add it here or else the file upload will fail.
diff --git a/core/modules/image/image.install b/core/modules/image/image.install
index 6a59953..c48a834 100644
--- a/core/modules/image/image.install
+++ b/core/modules/image/image.install
@@ -29,35 +29,30 @@ function image_uninstall() {
  * @param $phase
  */
 function image_requirements($phase) {
-  if ($phase != 'runtime') {
-    return array();
-  }
+  $requirements = array();
 
-  $toolkit = \Drupal::service('image.toolkit.manager')->getDefaultToolkit();
-  if ($toolkit) {
-    $plugin_definition = $toolkit->getPluginDefinition();
-    $requirements = array(
-      'image.toolkit' => array(
-        'title' => t('Image toolkit'),
-        'value' => $toolkit->getPluginId(),
-        'description' => $plugin_definition['title'],
-      ),
-    );
+  if ($phase == 'runtime') {
+    // Check for the PHP GD library.
+    if (function_exists('imagegd2')) {
+      $info = gd_info();
+      $requirements['image_gd'] = array(
+        'value' => $info['GD Version'],
+      );
 
-    foreach ($toolkit->getRequirements() as $key => $requirement) {
-      $namespaced_key = 'image.toolkit.' . $toolkit->getPluginId() . '.' . $key;
-      $requirements[$namespaced_key] = $requirement;
+      // Check for filter and rotate support.
+      if (!function_exists('imagefilter') || !function_exists('imagerotate')) {
+        $requirements['image_gd']['severity'] = REQUIREMENT_WARNING;
+        $requirements['image_gd']['description'] = t('The GD Library for PHP is enabled, but was compiled without support for functions used by the rotate and desaturate effects. It was probably compiled using the official GD libraries from http://www.libgd.org instead of the GD library bundled with PHP. You should recompile PHP --with-gd using the bundled GD library. See <a href="@url">the PHP manual</a>.', array('@url' => 'http://www.php.net/manual/book.image.php'));
+      }
     }
-  }
-  else {
-    $requirements = array(
-      'image.toolkit' => array(
-        'title' => t('Image toolkit'),
-        'value' => t('None'),
-        'description' => t("No image toolkit is configured on the site. Check PHP installed extensions or add a contributed toolkit that doesn't require a PHP extension. Make sure that at least one valid image toolkit is enabled."),
+    else {
+      $requirements['image_gd'] = array(
+        'value' => t('Not installed'),
         'severity' => REQUIREMENT_ERROR,
-      ),
-    );
+        'description' => t('The GD library for PHP is missing or outdated. Check the <a href="@url">PHP image documentation</a> for information on how to correct this.', array('@url' => 'http://www.php.net/manual/book.image.php')),
+      );
+    }
+    $requirements['image_gd']['title'] = t('GD library rotate and desaturate effects');
   }
 
   return $requirements;
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index c8f205f..aa54d89 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -113,7 +113,7 @@ function _testImageFieldFormatters($scheme) {
       '#width' => 40,
       '#height' => 20,
     );
-    $default_output = l($image, 'node/' . $nid, array('html' => TRUE));
+    $default_output = l($image, 'node/' . $nid, array('html' => TRUE, 'attributes' => array('class' => 'active')));
     $this->drupalGet('node/' . $nid);
     $this->assertRaw($default_output, 'Image linked to content formatter displaying correctly on full node view.');
 
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 79dc5d1..2c8e7af 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -25,6 +25,146 @@ function language_admin_predefined_list() {
 }
 
 /**
+ * Builds the configuration form for language negotiation.
+ *
+ * @deprecated Use \Drupal\language\Form\LanguageForm::negotiation()
+ */
+function language_negotiation_configure_form() {
+  language_negotiation_include();
+
+  $form = array(
+    '#submit' => array('language_negotiation_configure_form_submit'),
+    '#theme' => 'language_negotiation_configure_form',
+    '#language_types_info' => language_types_info(),
+    '#language_negotiation_info' => language_negotiation_info(),
+  );
+  $form['#language_types'] = array();
+  $configurable = \Drupal::config('system.language.types')->get('configurable');
+  foreach ($form['#language_types_info'] as $type => $info) {
+    // Show locked language types only if they are configurable.
+    if (empty($info['locked']) || in_array($type, $configurable)) {
+      $form['#language_types'][] = $type;
+    }
+  }
+  foreach ($form['#language_types'] as $type) {
+    language_negotiation_configure_form_table($form, $type);
+  }
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save settings'),
+  );
+
+  return $form;
+}
+
+/**
+ * Builds a language negotiation method configuration table.
+ */
+function language_negotiation_configure_form_table(&$form, $type) {
+  $info = $form['#language_types_info'][$type];
+
+  $table_form = array(
+    '#title' => t('@type language detection', array('@type' => $info['name'])),
+    '#tree' => TRUE,
+    '#description' => $info['description'],
+    '#language_negotiation_info' => array(),
+    '#show_operations' => FALSE,
+    'weight' => array('#tree' => TRUE),
+  );
+  // Only show configurability checkbox for the unlocked language types.
+  if (empty($info['locked'])) {
+    $configurable = \Drupal::config('system.language.types')->get('configurable');
+    $table_form['configurable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Customize %language_name language detection to differ from User interface text language detection settings.', array('%language_name' => $info['name'])),
+      '#default_value' => in_array($type, $configurable),
+      '#attributes' => array('class' => array('language-customization-checkbox')),
+      '#attached' => array(
+        'library' => array(
+          array('language', 'language.admin')
+        ),
+      ),
+    );
+  }
+
+  $negotiation_info = $form['#language_negotiation_info'];
+  $enabled_methods = variable_get("language_negotiation_$type", array());
+  $methods_weight = variable_get("language_negotiation_methods_weight_$type", array());
+
+  // Add missing data to the methods lists.
+  foreach ($negotiation_info as $method_id => $method) {
+    if (!isset($methods_weight[$method_id])) {
+      $methods_weight[$method_id] = isset($method['weight']) ? $method['weight'] : 0;
+    }
+  }
+
+  // Order methods list by weight.
+  asort($methods_weight);
+
+  foreach ($methods_weight as $method_id => $weight) {
+    // A language method might be no more available if the defining module has
+    // been disabled after the last configuration saving.
+    if (!isset($negotiation_info[$method_id])) {
+      continue;
+    }
+
+    $enabled = isset($enabled_methods[$method_id]);
+    $method = $negotiation_info[$method_id];
+
+    // List the method only if the current type is defined in its 'types' key.
+    // If it is not defined default to all the configurable language types.
+    $types = array_flip(isset($method['types']) ? $method['types'] : $form['#language_types']);
+
+    if (isset($types[$type])) {
+      $table_form['#language_negotiation_info'][$method_id] = $method;
+      $method_name = check_plain($method['name']);
+
+      $table_form['weight'][$method_id] = array(
+        '#type' => 'weight',
+        '#title' => t('Weight for !title language detection method', array('!title' => drupal_strtolower($method_name))),
+        '#title_display' => 'invisible',
+        '#default_value' => $weight,
+        '#attributes' => array('class' => array("language-method-weight-$type")),
+        '#delta' => 20,
+      );
+
+      $table_form['title'][$method_id] = array('#markup' => $method_name);
+
+      $table_form['enabled'][$method_id] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Enable !title language detection method', array('!title' => drupal_strtolower($method_name))),
+        '#title_display' => 'invisible',
+        '#default_value' => $enabled,
+      );
+      if ($method_id === LANGUAGE_NEGOTIATION_SELECTED) {
+        $table_form['enabled'][$method_id]['#default_value'] = TRUE;
+        $table_form['enabled'][$method_id]['#attributes'] = array('disabled' => 'disabled');
+      }
+
+      $table_form['description'][$method_id] = array('#markup' => filter_xss_admin($method['description']));
+
+      $config_op = array();
+      if (isset($method['config'])) {
+        $config_op['configure'] = array(
+          'title' => t('Configure'),
+          'href' => $method['config'],
+        );
+        // If there is at least one operation enabled show the operation column.
+        $table_form['#show_operations'] = TRUE;
+      }
+      $table_form['operation'][$method_id] = array(
+       '#type' => 'operations',
+       '#links' => $config_op,
+      );
+    }
+  }
+
+  $form[$type] = $table_form;
+}
+
+/**
  * Returns HTML for the language negotiation configuration form.
  *
  * @param $variables
@@ -99,6 +239,59 @@ function theme_language_negotiation_configure_form($variables) {
 }
 
 /**
+ * Submit handler for language negotiation settings.
+ */
+function language_negotiation_configure_form_submit($form, &$form_state) {
+  $configurable_types = $form['#language_types'];
+
+  $stored_values = \Drupal::config('system.language.types')->get('configurable');
+  $customized = array();
+  $method_weights_type = array();
+
+  foreach ($configurable_types as $type) {
+    $customized[$type] = in_array($type, $stored_values);
+    $method_weights = array();
+    $enabled_methods = $form_state['values'][$type]['enabled'];
+    $enabled_methods[LANGUAGE_NEGOTIATION_SELECTED] = TRUE;
+    $method_weights_input = $form_state['values'][$type]['weight'];
+    if (isset($form_state['values'][$type]['configurable'])) {
+      $customized[$type] = !empty($form_state['values'][$type]['configurable']);
+    }
+
+    foreach ($method_weights_input as $method_id => $weight) {
+      if ($enabled_methods[$method_id]) {
+        $method_weights[$method_id] = $weight;
+      }
+    }
+
+    $method_weights_type[$type] = $method_weights;
+    variable_set("language_negotiation_methods_weight_$type", $method_weights_input);
+  }
+
+  // Update non-configurable language types and the related language negotiation
+  // configuration.
+  language_types_set(array_keys(array_filter($customized)));
+
+  // Update the language negotiations after setting the configurability.
+  foreach ($method_weights_type as $type => $method_weights) {
+    language_negotiation_set($type, $method_weights);
+  }
+
+  // Clear block definitions cache since the available blocks and their names
+  // may have been changed based on the configurable types.
+  if (\Drupal::moduleHandler()->moduleExists('block')) {
+    // If there is an active language switcher for a language type that has been
+    // made not configurable, deactivate it first.
+    $non_configurable = array_keys(array_diff($customized, array_filter($customized)));
+    _language_disable_language_switcher($non_configurable);
+    \Drupal::service('plugin.manager.block')->clearCachedDefinitions();
+  }
+
+  $form_state['redirect_route']['route_name'] = 'language.negotiation';
+  drupal_set_message(t('Language negotiation configuration saved.'));
+}
+
+/**
  * Theme browser configuration form as table.
  *
  * @param $variables
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 07a4aad..ddd0cd2 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -112,7 +112,6 @@ function language_theme() {
   return array(
     'language_negotiation_configure_form' => array(
       'render element' => 'form',
-      'file' => 'language.admin.inc',
     ),
     'language_negotiation_configure_browser_form_table' => array(
       'render element' => 'form',
diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc
index f59a94e..f87284d 100644
--- a/core/modules/language/language.negotiation.inc
+++ b/core/modules/language/language.negotiation.inc
@@ -399,7 +399,6 @@ function language_switcher_url($type, $path) {
       'title'      => $language->name,
       'language'   => $language,
       'attributes' => array('class' => array('language-link')),
-      'set_active_class' => TRUE,
     );
   }
 
diff --git a/core/modules/language/language.routing.yml b/core/modules/language/language.routing.yml
index cda5754..4308ae0 100644
--- a/core/modules/language/language.routing.yml
+++ b/core/modules/language/language.routing.yml
@@ -54,7 +54,7 @@ language.delete:
 language.negotiation:
   path: '/admin/config/regional/language/detection'
   defaults:
-    _form: '\Drupal\language\Form\NegotiationConfigureForm'
+    _content: '\Drupal\language\Form\LanguageForm::negotiation'
     _title: 'Detection and selection'
   requirements:
     _permission: 'administer languages'
diff --git a/core/modules/language/lib/Drupal/language/Form/LanguageForm.php b/core/modules/language/lib/Drupal/language/Form/LanguageForm.php
new file mode 100644
index 0000000..9194c6b
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Form/LanguageForm.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\language\Form\LanguageForm.
+ */
+
+namespace Drupal\language\Form;
+
+/**
+ * Temporary form controller for language module.
+ */
+class LanguageForm {
+
+  /**
+   * Wraps language_negotiation_configure_form().
+   *
+   * @todo Remove language_negotiation_configure_form().
+   */
+  public function negotiation() {
+    module_load_include('admin.inc', 'language');
+    return drupal_get_form('language_negotiation_configure_form');
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php
deleted file mode 100644
index 01dec5b..0000000
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Language\Form\NegotiationConfigureForm.
- */
-
-namespace Drupal\language\Form;
-
-use Drupal\block\Plugin\Type\BlockManager;
-use Drupal\Component\Utility\String;
-use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\Xss;
-use Drupal\Core\Config\ConfigFactory;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Configure the selected language negotiation method for this site.
- */
-class NegotiationConfigureForm extends FormBase {
-
-  /**
-   * Stores the configuration object for system.language.types.
-   *
-   * @var \Drupal\Core\Config\Config
-   */
-  protected $languageTypesConfig;
-
-  /**
-   * The block manager.
-   *
-   * @var \Drupal\block\Plugin\Type\BlockManager
-   */
-  protected $blockManager;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a NegotiationConfigureForm object.
-   *
-   * @param \Drupal\Core\Config\ConfigFactory $config_factory
-   *   The factory for configuration objects.
-   * @param \Drupal\block\Plugin\Type\BlockManager $block_manager
-   *   The block manager, or NULL if not available.
-   */
-  public function __construct(ConfigFactory $config_factory, BlockManager $block_manager = NULL) {
-    $this->languageTypesConfig = $config_factory->get('system.language.types');
-    $this->blockManager = $block_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('config.factory'),
-      $container->has('plugin.manager.block') ? $container->get('plugin.manager.block') : NULL
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'language_negotiation_configure_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    language_negotiation_include();
-
-    $configurable = $this->languageTypesConfig->get('configurable');
-
-    $form = array(
-      '#theme' => 'language_negotiation_configure_form',
-      '#language_types_info' => language_types_info(),
-      '#language_negotiation_info' => language_negotiation_info(),
-    );
-    $form['#language_types'] = array();
-
-    foreach ($form['#language_types_info'] as $type => $info) {
-      // Show locked language types only if they are configurable.
-      if (empty($info['locked']) || in_array($type, $configurable)) {
-        $form['#language_types'][] = $type;
-      }
-    }
-
-    foreach ($form['#language_types'] as $type) {
-      $this->configureFormTable($form, $type);
-    }
-
-    $form['actions'] = array('#type' => 'actions');
-    $form['actions']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => $this->t('Save settings'),
-    );
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    language_negotiation_include();
-    $configurable_types = $form['#language_types'];
-
-    $stored_values = $this->languageTypesConfig->get('configurable');
-    $customized = array();
-    $method_weights_type = array();
-
-    foreach ($configurable_types as $type) {
-      $customized[$type] = in_array($type, $stored_values);
-      $method_weights = array();
-      $enabled_methods = $form_state['values'][$type]['enabled'];
-      $enabled_methods[LANGUAGE_NEGOTIATION_SELECTED] = TRUE;
-      $method_weights_input = $form_state['values'][$type]['weight'];
-      if (isset($form_state['values'][$type]['configurable'])) {
-        $customized[$type] = !empty($form_state['values'][$type]['configurable']);
-      }
-
-      foreach ($method_weights_input as $method_id => $weight) {
-        if ($enabled_methods[$method_id]) {
-          $method_weights[$method_id] = $weight;
-        }
-      }
-
-      $method_weights_type[$type] = $method_weights;
-      // @todo convert this to config.
-      variable_set("language_negotiation_methods_weight_$type", $method_weights_input);
-    }
-
-    // Update non-configurable language types and the related language
-    // negotiation configuration.
-    language_types_set(array_keys(array_filter($customized)));
-
-    // Update the language negotiations after setting the configurability.
-    foreach ($method_weights_type as $type => $method_weights) {
-      language_negotiation_set($type, $method_weights);
-    }
-
-    // Clear block definitions cache since the available blocks and their names
-    // may have been changed based on the configurable types.
-    if ($this->blockManager) {
-      // If there is an active language switcher for a language type that has
-      // been made not configurable, deactivate it first.
-      $non_configurable = array_keys(array_diff($customized, array_filter($customized)));
-      $this->disableLanguageSwitcher($non_configurable);
-      $this->blockManager->clearCachedDefinitions();
-    }
-
-    $form_state['redirect_route']['route_name'] = 'language.negotiation';
-    drupal_set_message($this->t('Language negotiation configuration saved.'));
-  }
-
-  /**
-   * Builds a language negotiation method configuration table.
-   *
-   * @param array $form
-   *   The language negotiation configuration form.
-   * @param string $type
-   *   The language type to generate the table for.
-   */
-  protected function configureFormTable(array &$form, $type)  {
-    $info = $form['#language_types_info'][$type];
-
-    $table_form = array(
-      '#title' => $this->t('@type language detection', array('@type' => $info['name'])),
-      '#tree' => TRUE,
-      '#description' => $info['description'],
-      '#language_negotiation_info' => array(),
-      '#show_operations' => FALSE,
-      'weight' => array('#tree' => TRUE),
-    );
-    // Only show configurability checkbox for the unlocked language types.
-    if (empty($info['locked'])) {
-      $configurable = $this->languageTypesConfig->get('configurable');
-      $table_form['configurable'] = array(
-        '#type' => 'checkbox',
-        '#title' => $this->t('Customize %language_name language detection to differ from User interface text language detection settings.', array('%language_name' => $info['name'])),
-        '#default_value' => in_array($type, $configurable),
-        '#attributes' => array('class' => array('language-customization-checkbox')),
-        '#attached' => array(
-          'library' => array(
-            array('language', 'language.admin')
-          ),
-        ),
-      );
-    }
-
-    $negotiation_info = $form['#language_negotiation_info'];
-    $enabled_methods = variable_get("language_negotiation_$type", array());
-    $methods_weight = variable_get("language_negotiation_methods_weight_$type", array());
-
-    // Add missing data to the methods lists.
-    foreach ($negotiation_info as $method_id => $method) {
-      if (!isset($methods_weight[$method_id])) {
-        $methods_weight[$method_id] = isset($method['weight']) ? $method['weight'] : 0;
-      }
-    }
-
-    // Order methods list by weight.
-    asort($methods_weight);
-
-    foreach ($methods_weight as $method_id => $weight) {
-      // A language method might be no more available if the defining module has
-      // been disabled after the last configuration saving.
-      if (!isset($negotiation_info[$method_id])) {
-        continue;
-      }
-
-      $enabled = isset($enabled_methods[$method_id]);
-      $method = $negotiation_info[$method_id];
-
-      // List the method only if the current type is defined in its 'types' key.
-      // If it is not defined default to all the configurable language types.
-      $types = array_flip(isset($method['types']) ? $method['types'] : $form['#language_types']);
-
-      if (isset($types[$type])) {
-        $table_form['#language_negotiation_info'][$method_id] = $method;
-        $method_name = String::checkPlain($method['name']);
-
-        $table_form['weight'][$method_id] = array(
-          '#type' => 'weight',
-          '#title' => $this->t('Weight for !title language detection method', array('!title' => Unicode::strtolower($method_name))),
-          '#title_display' => 'invisible',
-          '#default_value' => $weight,
-          '#attributes' => array('class' => array("language-method-weight-$type")),
-          '#delta' => 20,
-        );
-
-        $table_form['title'][$method_id] = array('#markup' => $method_name);
-
-        $table_form['enabled'][$method_id] = array(
-          '#type' => 'checkbox',
-          '#title' => $this->t('Enable !title language detection method', array('!title' => Unicode::strtolower($method_name))),
-          '#title_display' => 'invisible',
-          '#default_value' => $enabled,
-        );
-        if ($method_id === LANGUAGE_NEGOTIATION_SELECTED) {
-          $table_form['enabled'][$method_id]['#default_value'] = TRUE;
-          $table_form['enabled'][$method_id]['#attributes'] = array('disabled' => 'disabled');
-        }
-
-        $table_form['description'][$method_id] = array('#markup' => Xss::filterAdmin($method['description']));
-
-        $config_op = array();
-        if (isset($method['config'])) {
-          $config_op['configure'] = array(
-            'title' => $this->t('Configure'),
-            'href' => $method['config'],
-          );
-          // If there is at least one operation enabled show the operation
-          // column.
-          $table_form['#show_operations'] = TRUE;
-        }
-        $table_form['operation'][$method_id] = array(
-         '#type' => 'operations',
-         '#links' => $config_op,
-        );
-      }
-    }
-    $form[$type] = $table_form;
-  }
-
-  /**
-   * Disables the language switcher blocks.
-   *
-   * @param array $language_types
-   *   An array containing all language types whose language switchers need to
-   *   be disabled.
-   */
-  protected function disableLanguageSwitcher(array $language_types) {
-    $blocks = _block_rehash();
-    foreach ($language_types as $language_type) {
-      foreach ($blocks as $block) {
-        if (strpos($block->id, 'language_switcher_' . substr($language_type, 9)) !== FALSE) {
-          $block->delete();
-        }
-      }
-    }
-  }
-
-}
diff --git a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
index d97d49f..f53c81b 100644
--- a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
+++ b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
@@ -47,7 +47,6 @@ public function build() {
             "language-switcher-{$links->method_id}",
           ),
         ),
-        '#set_active_class' => TRUE,
       );
     }
     return $build;
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
index 826fcf9..4613f43 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageSwitchingTest.php
@@ -55,70 +55,9 @@ function testLanguageBlock() {
     $edit = array('language_interface[enabled][language-url]' => '1');
     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
 
-    $this->doTestLanguageBlockAuthenticated($block->label());
-    $this->doTestLanguageBlockAnonymous($block->label());
-  }
-
-  /**
-   * For authenticated users, the "active" class is set by JavaScript.
-   *
-   * @param string $block_label
-   *   The label of the language switching block.
-   *
-   * @see testLanguageBlock()
-   */
-  protected function doTestLanguageBlockAuthenticated($block_label) {
-    // Assert that the language switching block is displayed on the frontpage.
-    $this->drupalGet('');
-    $this->assertText($block_label, 'Language switcher block found.');
-
-    // Assert that each list item and anchor element has the appropriate data-
-    // attributes.
-    list($language_switcher) = $this->xpath('//div[@id=:id]/div[contains(@class, "content")]', array(':id' => 'block-test-language-block'));
-    $list_items = array();
-    $anchors = array();
-    foreach ($language_switcher->ul->li as $list_item) {
-      $classes = explode(" ", (string) $list_item['class']);
-      list($langcode) = array_intersect($classes, array('en', 'fr'));
-      $list_items[] = array(
-        'langcode_class' => $langcode,
-        'data-drupal-link-system-path' => (string) $list_item['data-drupal-link-system-path'],
-      );
-      $anchors[] = array(
-        'hreflang' => (string) $list_item->a['hreflang'],
-        'data-drupal-link-system-path' => (string) $list_item->a['data-drupal-link-system-path'],
-      );
-    }
-    $expected_list_items = array(
-      0 => array('langcode_class' => 'en', 'data-drupal-link-system-path' => 'user/2'),
-      1 => array('langcode_class' => 'fr', 'data-drupal-link-system-path' => 'user/2'),
-    );
-    $this->assertIdentical($list_items, $expected_list_items, 'The list items have the correct attributes that will allow the drupal.active-link library to mark them as active.');
-    $expected_anchors = array(
-      0 => array('hreflang' => 'en', 'data-drupal-link-system-path' => 'user/2'),
-      1 => array('hreflang' => 'fr', 'data-drupal-link-system-path' => 'user/2'),
-    );
-    $this->assertIdentical($anchors, $expected_anchors, 'The anchors have the correct attributes that will allow the drupal.active-link library to mark them as active.');
-    $settings = $this->drupalGetSettings();
-    $this->assertIdentical($settings['path']['currentPath'], 'user/2', 'drupalSettings.path.currentPath is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['isFront'], FALSE, 'drupalSettings.path.isFront is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['currentLanguage'], 'en', 'drupalSettings.path.currentLanguage is set correctly to allow drupal.active-link to mark the correct links as active.');
-  }
-
-  /**
-   * For anonymous users, the "active" class is set by PHP.
-   *
-   * @param string $block_label
-   *   The label of the language switching block.
-   *
-   * @see testLanguageBlock()
-   */
-  protected function doTestLanguageBlockAnonymous($block_label) {
-    $this->drupalLogout();
-
     // Assert that the language switching block is displayed on the frontpage.
     $this->drupalGet('');
-    $this->assertText($block_label, 'Language switcher block found.');
+    $this->assertText($block->label(), 'Language switcher block found.');
 
     // Assert that only the current language is marked as active.
     list($language_switcher) = $this->xpath('//div[@id=:id]/div[contains(@class, "content")]', array(':id' => 'block-test-language-block'));
@@ -165,80 +104,7 @@ function testLanguageLinkActiveClass() {
     $edit = array('language_interface[enabled][language-url]' => '1');
     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
 
-    $this->doTestLanguageLinkActiveClassAuthenticated();
-    $this->doTestLanguageLinkActiveClassAnonymous();
-  }
-
-  /**
-   * For authenticated users, the "active" class is set by JavaScript.
-   *
-   * @see testLanguageLinkActiveClass()
-   */
-  protected function doTestLanguageLinkActiveClassAuthenticated() {
-    $function_name = '#type link';
-    $path = 'language_test/type-link-active-class';
-
-    // Test links generated by l() on an English page.
-    $current_language = 'English';
-    $this->drupalGet($path);
-
-    // Language code 'none' link should be active.
-    $langcode = 'none';
-    $links = $this->xpath('//a[@id = :id and @data-drupal-link-system-path = :path]', array(':id' => 'no_lang_link', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Language code 'en' link should be active.
-    $langcode = 'en';
-    $links = $this->xpath('//a[@id = :id and @hreflang = :lang and @data-drupal-link-system-path = :path]', array(':id' => 'en_link', ':lang' => 'en', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Language code 'fr' link should not be active.
-    $langcode = 'fr';
-    $links = $this->xpath('//a[@id = :id and @hreflang = :lang and @data-drupal-link-system-path = :path]', array(':id' => 'fr_link', ':lang' => 'fr', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to NOT mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Verify that drupalSettings contains the correct values.
-    $settings = $this->drupalGetSettings();
-    $this->assertIdentical($settings['path']['currentPath'], $path, 'drupalSettings.path.currentPath is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['isFront'], FALSE, 'drupalSettings.path.isFront is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['currentLanguage'], 'en', 'drupalSettings.path.currentLanguage is set correctly to allow drupal.active-link to mark the correct links as active.');
-
-    // Test links generated by l() on a French page.
-    $current_language = 'French';
-    $this->drupalGet('fr/language_test/type-link-active-class');
-
-    // Language code 'none' link should be active.
-    $langcode = 'none';
-    $links = $this->xpath('//a[@id = :id and @data-drupal-link-system-path = :path]', array(':id' => 'no_lang_link', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Language code 'en' link should not be active.
-    $langcode = 'en';
-    $links = $this->xpath('//a[@id = :id and @hreflang = :lang and @data-drupal-link-system-path = :path]', array(':id' => 'en_link', ':lang' => 'en', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to NOT mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Language code 'fr' link should be active.
-    $langcode = 'fr';
-    $links = $this->xpath('//a[@id = :id and @hreflang = :lang and @data-drupal-link-system-path = :path]', array(':id' => 'fr_link', ':lang' => 'fr', ':path' => $path));
-    $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode has the correct attributes that will allow the drupal.active-link library to mark it as active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode)));
-
-    // Verify that drupalSettings contains the correct values.
-    $settings = $this->drupalGetSettings();
-    $this->assertIdentical($settings['path']['currentPath'], $path, 'drupalSettings.path.currentPath is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['isFront'], FALSE, 'drupalSettings.path.isFront is set correctly to allow drupal.active-link to mark the correct links as active.');
-    $this->assertIdentical($settings['path']['currentLanguage'], 'fr', 'drupalSettings.path.currentLanguage is set correctly to allow drupal.active-link to mark the correct links as active.');
-  }
-
-  /**
-   * For anonymous users, the "active" class is set by PHP.
-   *
-   * @see testLanguageLinkActiveClass()
-   */
-  protected function doTestLanguageLinkActiveClassAnonymous() {
     $function_name = '#type link';
-    $path = 'language_test/type-link-active-class';
-
-    $this->drupalLogout();
 
     // Test links generated by l() on an English page.
     $current_language = 'English';
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 19744c2..7c037b5 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -411,11 +411,6 @@ function testUrlLanguageFallback() {
     // Enable the language switcher block.
     $this->drupalPlaceBlock('language_block:' . Language::TYPE_INTERFACE, array('id' => 'test_language_block'));
 
-    // Log out, because for anonymous users, the "active" class is set by PHP
-    // (which means we can easily test it here), whereas for authenticated users
-    // it is set by JavaScript.
-    $this->drupalLogout();
-
     // Access the front page without specifying any valid URL language prefix
     // and having as browser language preference a non-default language.
     $http_header = array("Accept-Language: $langcode_browser_fallback;q=1");
@@ -469,7 +464,7 @@ function testLanguageDomain() {
     $italian_url = url('admin', array('language' => $languages['it'], 'script' => ''));
     $url_scheme = $this->request->isSecure() ? 'https://' : 'http://';
     $correct_link = $url_scheme . $link;
-    $this->assertEqual($italian_url, $correct_link, format_string('The url() function returns the right URL (@url) in accordance with the chosen language', array('@url' => $italian_url)));
+    $this->assertTrue($italian_url == $correct_link, format_string('The url() function returns the right URL (@url) in accordance with the chosen language', array('@url' => $italian_url)));
 
     // Test HTTPS via options.
     $this->settingsSet('mixed_mode_sessions', TRUE);
diff --git a/core/modules/language/tests/language_test/lib/Drupal/language_test/Controller/LanguageTestController.php b/core/modules/language/tests/language_test/lib/Drupal/language_test/Controller/LanguageTestController.php
index 781af06..001fe39 100644
--- a/core/modules/language/tests/language_test/lib/Drupal/language_test/Controller/LanguageTestController.php
+++ b/core/modules/language/tests/language_test/lib/Drupal/language_test/Controller/LanguageTestController.php
@@ -58,7 +58,6 @@ public function typeLinkActiveClass() {
           'attributes' => array(
             'id' => 'no_lang_link',
           ),
-          'set_active_class' => TRUE,
         ),
       ),
       'fr' => array(
@@ -70,7 +69,6 @@ public function typeLinkActiveClass() {
           'attributes' => array(
             'id' => 'fr_link',
           ),
-          'set_active_class' => TRUE,
         ),
       ),
       'en' => array(
@@ -82,7 +80,6 @@ public function typeLinkActiveClass() {
           'attributes' => array(
             'id' => 'en_link',
           ),
-          'set_active_class' => TRUE,
         ),
       ),
     );
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
index 9284444..e146936 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\locale;
 
-use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Config\TypedConfigManager;
 use Drupal\Core\Config\StorageInterface;
@@ -48,12 +47,10 @@ class LocaleConfigManager extends TypedConfigManager {
    *   data.
    * @param \Drupal\locale\StringStorageInterface $localeStorage
    *   The locale storage to use for reading string translations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
-   *   The cache backend to use for caching the definitions.
    */
-  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage, CacheBackendInterface $cache) {
+  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage) {
     // Note we use the install storage for the parent constructor.
-    parent::__construct($configStorage, $schemaStorage, $cache);
+    parent::__construct($configStorage, $schemaStorage);
     $this->installStorage = $installStorage;
     $this->localeStorage = $localeStorage;
   }
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
index af87dc9..f6f2900 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
@@ -46,8 +46,7 @@ public function testHasTranslation() {
       $this->container->get('config.storage.installer'),
       $this->container->get('config.storage.schema'),
       $this->container->get('config.storage.installer'),
-      $this->container->get('locale.storage'),
-      $this->container->get('cache.config')
+      $this->container->get('locale.storage')
     );
 
     $language = new Language(array('id' => 'de'));
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
index 0970b9c..20c023f 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php
@@ -35,12 +35,6 @@ public function setUp() {
     parent::setUp();
     // Add a default locale storage for all these tests.
     $this->storage = $this->container->get('locale.storage');
-
-    // Enable import of translations. By default this is disabled for automated
-    // tests.
-    \Drupal::config('locale.settings')
-      ->set('translation.import_enabled', TRUE)
-      ->save();
   }
 
   /**
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
index d822f10..5d746f3 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
@@ -43,12 +43,6 @@ function setUp() {
 
     $this->admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
     $this->drupalLogin($this->admin_user);
-
-    // Enable import of translations. By default this is disabled for automated
-    // tests.
-    \Drupal::config('locale.settings')
-      ->set('translation.import_enabled', TRUE)
-      ->save();
   }
 
   /**
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateBase.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateBase.php
index 64e9333..1d88e2b 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateBase.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateBase.php
@@ -51,12 +51,6 @@ function setUp() {
     $this->timestamp_medium = REQUEST_TIME - 200;
     $this->timestamp_new = REQUEST_TIME - 100;
     $this->timestamp_now = REQUEST_TIME;
-
-    // Enable import of translations. By default this is disabled for automated
-    // tests.
-    \Drupal::config('locale.settings')
-      ->set('translation.import_enabled', TRUE)
-      ->save();
   }
 
   /**
diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml
index 568f21d..f831989 100644
--- a/core/modules/locale/locale.services.yml
+++ b/core/modules/locale/locale.services.yml
@@ -11,7 +11,7 @@ services:
     arguments: ['@entity.manager']
   locale.config.typed:
     class: Drupal\locale\LocaleConfigManager
-    arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage', '@cache.config']
+    arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage']
   locale.storage:
     class: Drupal\locale\StringDatabaseStorage
     arguments: ['@database']
diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php
index 4948dab..e4ccc75 100644
--- a/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php
+++ b/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php
@@ -10,12 +10,8 @@
 use Drupal\migrate\Plugin\migrate\process\DedupeEntity;
 
 /**
- * Test the deduplication entity process plugin.
- *
  * @group migrate
  * @group Drupal
- *
- * @see \Drupal\migrate\Plugin\migrate\process\DedupeEntity
  */
 class DedupeEntityTest extends MigrateProcessTestCase {
 
@@ -48,43 +44,65 @@ public function setUp() {
   }
 
   /**
-   * Tests entity based deduplication based on providerTestDedupe() values.
-   *
-   * @dataProvider providerTestDedupe
+   * Tests the entity deduplication plugin when there is no duplication.
    */
-  public function testDedupe($count, $postfix = '') {
+  public function testDedupeEntityNoDuplication() {
     $configuration = array(
       'entity_type' => 'test_entity_type',
       'field' => 'test_field',
     );
-    if ($postfix) {
-      $configuration['postfix'] = $postfix;
-    }
     $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
-    $this->entityQueryExpects($count);
+    $this->entityQueryExpects(0);
     $plugin->setEntityQuery($this->entityQuery);
     $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
-    $this->assertSame($return, 'test' . ($count ? $postfix . $count : ''));
+    $this->assertSame($return, 'test');
   }
 
   /**
-   * Data provider for testDedupe().
+   * Tests the entity deduplication plugin when there is duplication.
    */
-  public function providerTestDedupe() {
-    return array(
-      // Tests the entity deduplication plugin when there is no duplication
-      // and no postfix.
-      array(0),
-      // Tests the entity deduplication plugin when there is duplication but
-      // no postfix.
-      array(3),
-      // Tests the entity deduplication plugin when there is no duplication
-      // but there is a postfix.
-      array(0, '_'),
-      // Tests the entity deduplication plugin when there is duplication and
-      // there is a postfix.
-      array(2, '_'),
+  public function testDedupeEntityDuplication() {
+    $configuration = array(
+      'entity_type' => 'test_entity_type',
+      'field' => 'test_field',
+    );
+    $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
+    $this->entityQueryExpects(3);
+    $plugin->setEntityQuery($this->entityQuery);
+    $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
+    $this->assertSame($return, 'test3');
+  }
+
+  /**
+   * Tests the entity deduplication plugin when there is no duplication.
+   */
+  public function testDedupeEntityNoDuplicationWithPostfix() {
+    $configuration = array(
+      'entity_type' => 'test_entity_type',
+      'field' => 'test_field',
+      'postfix' => '_',
     );
+    $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
+    $this->entityQueryExpects(0);
+    $plugin->setEntityQuery($this->entityQuery);
+    $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
+    $this->assertSame($return, 'test');
+  }
+
+  /**
+   * Tests the entity deduplication plugin when there is duplication.
+   */
+  public function testDedupeEntityDuplicationWithPostfix() {
+    $configuration = array(
+      'entity_type' => 'test_entity_type',
+      'field' => 'test_field',
+      'postfix' => '_',
+    );
+    $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
+    $this->entityQueryExpects(2);
+    $plugin->setEntityQuery($this->entityQuery);
+    $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
+    $this->assertSame($return, 'test_2');
   }
 
   /**
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_action_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_action_settings.yml
deleted file mode 100644
index 2da277f..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_action_settings.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_action_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - actions_max_stack
-process:
-  recursion_limit: actions_max_stack
-destination:
-  plugin: d8_config
-  config_name: action.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_aggregator_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_aggregator_settings.yml
deleted file mode 100644
index a6ec30c..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_aggregator_settings.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-id: d6_aggregator_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - aggregator_fetcher
-    - aggregator_parser
-    - aggregator_processors
-    - aggregator_allowed_html_tags
-    - aggregator_teaser_length
-    - aggregator_clear
-    - aggregator_summary_items
-    - aggregator_category_selector
-process:
-  fetcher: aggregator_fetcher
-  parser: aggregator_parser
-  processors: aggregator_processors
-  'items:allowed_html': aggregator_allowed_html_tags
-  'items:teaser_length': aggregator_teaser_length
-  'items:expire': aggregator_clear
-  'source:list_max': aggregator_summary_items
-  'source:category_selector': aggregator_category_selector
-destination:
-  plugin: d8_config
-  config_name: aggregator.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_book_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_book_settings.yml
deleted file mode 100644
index 77da0ce..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_book_settings.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: d6_book_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - book_child_type
-    - book_block_mode
-    - book_allowed_types
-process:
-  child_type: book_child_type
-  'block:navigation:mode': book_block_mode
-  allowed_types: book_allowed_types
-destination:
-  plugin: d8_config
-  config_name: book.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_contact_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_contact_settings.yml
deleted file mode 100644
index 46470f8..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_contact_settings.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_contact_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - contact_default_status
-    - contact_hourly_threshold
-process:
-  user_default_enabled: contact_default_status
-  'flood:limit': contact_hourly_threshold
-destination:
-  plugin: d8_config
-  config_name: contact.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_dblog_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_dblog_settings.yml
deleted file mode 100644
index cea039f..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_dblog_settings.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_dblog_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - dblog_row_limit
-process:
-  row_limit: dblog_row_limit
-destination:
-  plugin: d8_config
-  config_name: dblog.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_field_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_field_settings.yml
deleted file mode 100644
index 45d6c34..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_field_settings.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_field_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - field_language_fallback
-process:
-  language_fallback: field_language_fallback
-destination:
-  plugin: d8_config
-  config_name: field.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_file_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_file_settings.yml
deleted file mode 100644
index 35e077b..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_file_settings.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: d6_file_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - file_description_type
-    - file_description_length
-    - file_icon_directory
-process:
-  'description:type': file_description_type
-  'description:length': file_description_length
-  'icon:directory': file_icon_directory
-destination:
-  plugin: d8_config
-  config_name: file.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_forum_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_forum_settings.yml
deleted file mode 100644
index 5bb0a1f..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_forum_settings.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-id: d6_forum_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - forum_hot_topic
-    - forum_per_page
-    - forum_order
-    - forum_block_num_0
-    - forum_block_num_1
-process:
-  'block:active:limit': forum_block_num_0
-  'block:new:limit': forum_block_num_1
-  'topics:hot_threshold': forum_hot_topic
-  'topics:page_limit': forum_per_page
-  'topics:order': forum_order
-destination:
-  plugin: d8_config
-  config_name: forum.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_locale_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_locale_settings.yml
deleted file mode 100644
index 1183b5e..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_locale_settings.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_locale_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - locale_cache_strings
-    - locale_js_directory
-process:
-  cache_string: locale_cache_strings
-  'javascript:directory': locale_js_directory
-destination:
-  plugin: d8_config
-  config_name: locale.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_menu_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_menu_settings.yml
deleted file mode 100644
index b57bd3e..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_menu_settings.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: d6_menu_settings
-source:
-    plugin: drupal6_variable
-    variables:
-        - menu_primary_links_source
-        - menu_secondary_links_source
-        - menu_override_parent_selector
-process:
-    main_links: menu_primary_links_source
-    secondary_links: menu_secondary_links_source
-    override_parent_selector: menu_override_parent_selector
-destination:
-    plugin: d8_config
-    config_name: menu.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_node_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_node_settings.yml
deleted file mode 100644
index ab37378..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_node_settings.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_node_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - node_admin_theme
-process:
-  use_admin_theme: node_admin_theme
-destination:
-  plugin: d8_config
-  config_name: node.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_search_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_search_settings.yml
deleted file mode 100644
index 7ea5c20..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_search_settings.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: d6_search_settings
-source:
-    plugin: drupal6_variable
-    variables:
-        - minimum_word_size
-        - overlap_cjk
-        - search_cron_limit
-        - search_tag_weights
-        - search_and_or_limit
-process:
-    'index:minimum_word_size': minimum_word_size
-    'index:overlap_cjk': overlap_cjk
-    'index:cron_limit': search_cron_limit
-destination:
-    plugin: d8_config
-    config_name: search.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_simpletest_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_simpletest_settings.yml
deleted file mode 100644
index 8a6f06c..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_simpletest_settings.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-id: d6_simpletest_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - simpletest_clear_results
-    - simpletest_httpauth_method
-    - simpletest_httpauth_password
-    - simpletest_httpauth_username
-    - simpletest_verbose
-process:
-  clear_results: simpletest_clear_results
-  'httpauth:method': simpletest_httpauth_method
-  'httpauth:password': simpletest_httpauth_password
-  'httpauth:username': simpletest_httpauth_username
-  verbose: simpletest_verbose
-destination:
-  plugin: d8_config
-  config_name: simpletest.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_statistics_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_statistics_settings.yml
deleted file mode 100644
index 24a1baf..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_statistics_settings.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-id: d6_statistics_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - statistics_enable_access_log
-    - statistics_flush_accesslog_timer
-    - statistics_count_content_views
-    - statistics_block_top_day_num
-    - statistics_block_top_all_num
-    - statistics_block_top_last_num
-process:
-  'access_log:enable': statistics_enable_access_log
-  'access_log:max_lifetime': statistics_flush_accesslog_timer
-  'count_content_views': statistics_count_content_views
-  'block:popular:top_day_limit': statistics_block_top_day_num
-  'block:popular:top_all_limit': statistics_block_top_all_num
-  'block:popular:top_recent_limit': statistics_block_top_last_num
-destination:
-  plugin: d8_config
-  config_name: statistics.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_syslog_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_syslog_settings.yml
deleted file mode 100644
index 8be7bf2..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_syslog_settings.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_syslog_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - syslog_identity
-    - syslog_facility
-process:
-  identity: syslog_identity
-  facility: syslog_facility
-destination:
-  plugin: d8_config
-  config_name: syslog.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_cron.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_cron.yml
index 1e0e452..736af9b 100644
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_cron.yml
+++ b/core/modules/migrate_drupal/config/migrate.migration.d6_system_cron.yml
@@ -1,13 +1,13 @@
 id: d6_system_cron
 source:
-  plugin: drupal6_variable
-  variables:
-    - cron_threshold_warning
-    - cron_threshold_error
-    - cron_last
+    plugin: drupal6_variable
+    variables:
+        - cron_threshold_warning
+        - cron_threshold_error
+        - cron_last
 process:
-  'threshold:warning': cron_threshold_warning
-  'threshold:error': cron_threshold_error
+    'threshold:warning': cron_threshold_warning
+    'threshold:error': cron_threshold_error
 destination:
-  plugin: d8_config
-  config_name: system.cron
+    plugin: d8_config
+    config_name: system.cron
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_file.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_file.yml
deleted file mode 100644
index df0797d..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_file.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_system_file
-source:
-  plugin: drupal6_variable
-  variables:
-    - file_directory_path
-    - file_directory_temp
-process:
-  'path:private': file_directory_path
-  'path:temporary': file_directory_temp
-destination:
-  plugin: d8_config
-  config_name: system.file
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_filter.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_filter.yml
deleted file mode 100644
index 0a2690e..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_filter.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_system_filter
-source:
-  plugin: drupal6_variable
-  variables:
-    - filter_allowed_protocols
-process:
-  protocols: filter_allowed_protocols
-destination:
-  plugin: d8_config
-  config_name: system.filter
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_image.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_image.yml
deleted file mode 100644
index 6d98bfc..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_image.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_system_image
-source:
-  plugin: drupal6_variable
-  variables:
-    - image_toolkit
-process:
-  toolkit: image_toolkit
-destination:
-  plugin: d8_config
-  config_name: system.image
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_image_gd.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_image_gd.yml
deleted file mode 100644
index 29aacba..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_image_gd.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_system_image_gd
-source:
-  plugin: drupal6_variable
-  variables:
-    - image_jpeg_quality
-process:
-  jpeg_quality: image_jpeg_quality
-destination:
-  plugin: d8_config
-  config_name: system.image.gd
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_maintenance.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_maintenance.yml
deleted file mode 100644
index a711614..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_maintenance.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_system_maintenance
-source:
-  plugin: drupal6_variable
-  variables:
-    - site_offline
-    - site_offline_message
-process:
-  enable: site_offline
-  message: site_offline_message
-destination:
-  plugin: d8_config
-  config_name: system.maintenance
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_performance.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_performance.yml
index 6498d9e..cde5d17 100644
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_performance.yml
+++ b/core/modules/migrate_drupal/config/migrate.migration.d6_system_performance.yml
@@ -1,14 +1,14 @@
 id: d6_system_performance
 source:
-  plugin: drupal6_variable
-  variables:
-    - preprocess_css
-    - preprocess_js
-    - cache_lifetime
+    plugin: drupal6_variable
+    variables:
+        - preprocess_css
+        - preprocess_js
+        - cache_lifetime
 process:
-  'css:preprocess': preprocess_css
-  'js:preprocess': preprocess_js
-  'cache:page:max_age': cache_lifetime
+    'css:preprocess': preprocess_css
+    'js:preprocess': preprocess_js
+    'cache:page:max_age': cache_lifetime
 destination:
-  plugin: d8_config
-  config_name: system.performance
+    plugin: d8_config
+    config_name: system.performance
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_rss.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_rss.yml
index ca8498f..acce5e2 100644
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_rss.yml
+++ b/core/modules/migrate_drupal/config/migrate.migration.d6_system_rss.yml
@@ -1,10 +1,10 @@
 id: d6_system_rss
 source:
-  plugin: drupal6_variable
-  variables:
-    - feed_default_items
+    plugin: drupal6_variable
+    variables:
+        - feed_default_items
 process:
-  'items:limit': feed_default_items
+    'items:limit': feed_default_items
 destination:
-  plugin: d8_config
-  config_name: system.rss
+    plugin: d8_config
+    config_name: system.rss
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_site.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_site.yml
index de88ed4..bcfb712 100644
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_site.yml
+++ b/core/modules/migrate_drupal/config/migrate.migration.d6_system_site.yml
@@ -1,24 +1,24 @@
 id: d6_system_site
 source:
-  plugin: drupal6_variable
-  variables:
-    - site_name
-    - site_mail
-    - site_slogan
-    - site_frontpage
-    - site_403
-    - site_404
-    - drupal_weight_select_max
-    - admin_compact_mode
+    plugin: drupal6_variable
+    variables:
+        - site_name
+        - site_mail
+        - site_slogan
+        - site_frontpage
+        - site_403
+        - site_404
+        - drupal_weight_select_max
+        - admin_compact_mode
 process:
-  name: site_name
-  mail: site_mail
-  slogan: site_slogan
-  'page:front': site_frontpage
-  'page:403': site_403
-  'page:404': site_404
-  weight_select_max: drupal_weight_select_max
-  admin_compact_mode: admin_compact_mode
+    name: site_name
+    mail: site_mail
+    slogan: site_slogan
+    'page:front': site_frontpage
+    'page:403': site_403
+    'page:404': site_404
+    weight_select_max: drupal_weight_select_max
+    admin_compact_mode: admin_compact_mode
 destination:
-  plugin: d8_config
-  config_name: system.site
+    plugin: d8_config
+    config_name: system.site
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_system_theme.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_system_theme.yml
deleted file mode 100644
index ba78e8c..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_system_theme.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_system_theme
-source:
-  plugin: drupal6_variable
-  variables:
-    - admin_theme
-    - theme_default
-process:
-  admin: admin_theme
-  default: theme_default
-destination:
-  plugin: d8_config
-  config_name: system.theme
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_taxonomy_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_taxonomy_settings.yml
deleted file mode 100644
index a6bbaf7..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_taxonomy_settings.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: d6_taxonomy_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - taxonomy_override_selector
-    - taxonomy_terms_per_page_admin
-process:
-  override_selector: taxonomy_override_selector
-  terms_per_page_admin: taxonomy_terms_per_page_admin
-destination:
-  plugin: d8_config
-  config_name: taxonomy.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_text_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_text_settings.yml
deleted file mode 100644
index fb5dea5..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_text_settings.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-id: d6_text_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - teaser_length
-process:
-  default_summary_length: teaser_length
-destination:
-  plugin: d8_config
-  config_name: text.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_update_settings.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_update_settings.yml
deleted file mode 100644
index a3ab12a..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_update_settings.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: d6_update_settings
-source:
-  plugin: drupal6_variable
-  variables:
-    - update_max_fetch_attempts
-    - update_fetch_url
-    - update_notification_threshold
-    - update_notify_emails
-process:
-  'fetch:max_attempts': update_max_fetch_attempts
-  'fetch:url': update_fetch_url
-  'notification:threshold': update_notification_threshold
-  'notification:mails': update_notify_emails
-destination:
-  plugin: d8_config
-  config_name: update.settings
diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_user_mail.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_user_mail.yml
deleted file mode 100644
index 1450402..0000000
--- a/core/modules/migrate_drupal/config/migrate.migration.d6_user_mail.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-id: d6_user_mail
-source:
-  plugin: drupal6_variable
-  variables:
-    - user_mail_status_activated_subject
-    - user_mail_status_activated_body
-    - user_mail_password_reset_subject
-    - user_mail_password_reset_body
-    - user_mail_status_deleted_subject
-    - user_mail_status_deleted_body
-    - user_mail_register_admin_created_subject
-    - user_mail_register_admin_created_body
-    - user_mail_register_no_approval_required_subject
-    - user_mail_register_no_approval_required_body
-    - user_mail_user_mail_register_pending_approval_subject
-    - user_mail_user_mail_register_pending_approval_body
-    - user_mail_status_blocked_subject
-    - user_mail_status_blocked_body
-process:
-  'status_activated:subject': user_mail_status_activated_subject
-  'status_activated:body': user_mail_status_activated_body
-  'password_reset:subject': user_mail_password_reset_subject
-  'password_reset:body': user_mail_password_reset_body
-  'cancel_confirm:subject': user_mail_status_deleted_subject
-  'cancel_confirm:body': user_mail_status_deleted_body
-  'register_admin_created:subject': user_mail_register_admin_created_subject
-  'register_admin_created:body': user_mail_register_admin_created_body
-  'register_no_approval_required:subject': user_mail_register_no_approval_required_subject
-  'register_no_approval_required:body': user_mail_register_no_approval_required_body
-  'register_pending_approval:subject': user_mail_user_mail_register_pending_approval_subject
-  'register_pending_approval:body': user_mail_user_mail_register_pending_approval_body
-  'status_blocked:subject': user_mail_status_blocked_subject
-  'status_blocked:body': user_mail_status_blocked_body
-destination:
-  plugin: d8_config
-  config_name: user.mail
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ActionSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ActionSettings.php
deleted file mode 100644
index 245d19e..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ActionSettings.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6ActionSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing action.settings.yml migration.
- */
-class Drupal6ActionSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'actions_max_stack',
-      'value' => 'i:35;',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6AggregatorSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6AggregatorSettings.php
deleted file mode 100644
index 7d0de49..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6AggregatorSettings.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6AggregatorSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing aggregator.settings.yml migration.
- */
-class Drupal6AggregatorSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'aggregator_fetcher',
-      'value' => 's:10:"aggregator";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_parser',
-      'value' => 's:10:"aggregator";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_processors',
-      'value' => 'a:1:{i:0;s:10:"aggregator";}',
-    ))
-    ->values(array(
-      'name' => 'aggregator_allowed_html_tags',
-      'value' => 's:70:"<a> <b> <br /> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_teaser_length',
-      'value' => 's:3:"600";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_clear',
-      'value' => 's:7:"9676800";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_summary_items',
-      'value' => 's:1:"3";',
-    ))
-    ->values(array(
-      'name' => 'aggregator_category_selector',
-      'value' => 's:10:"checkboxes";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6BookSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6BookSettings.php
deleted file mode 100644
index 104fb7b..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6BookSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6BookSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing book.settings.yml migration.
- */
-class Drupal6BookSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'book_allowed_types',
-      'value' => 'a:1:{i:0;s:4:"book";}',
-    ))
-    ->values(array(
-      'name' => 'book_block_mode',
-      'value' => 's:9:"all pages";',
-    ))
-    ->values(array(
-      'name' => 'book_child_type',
-      'value' => 's:4:"book";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ContactSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ContactSettings.php
deleted file mode 100644
index 4c16b44..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ContactSettings.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6ContactSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing contact.settings.yml migration.
- */
-class Drupal6ContactSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'contact_default_status',
-      'value' => 'i:1;',
-    ))
-    ->values(array(
-      'name' => 'contact_hourly_threshold',
-      'value' => 'i:3;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DblogSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DblogSettings.php
deleted file mode 100644
index 676dab9..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DblogSettings.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6DblogSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing dblog.settings.yml migration.
- */
-class Drupal6DblogSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'dblog_row_limit',
-      'value' => 'i:1000;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DumpCommon.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DumpCommon.php
deleted file mode 100644
index f56f3d0..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DumpCommon.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6DumpBase.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-class Drupal6DumpCommon {
-
-  public static function createVariable(Connection $database) {
-    $database->schema()->createTable('variable', array(
-      'fields' => array(
-        'name' => array(
-          'type' => 'varchar',
-          'length' => 128,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'value' => array(
-          'type' => 'blob',
-          'not null' => TRUE,
-          'size' => 'big',
-          'translatable' => TRUE,
-        ),
-      ),
-      'primary key' => array(
-        'name',
-      ),
-      'module' => 'book',
-      'name' => 'variable',
-    ));
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FieldSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FieldSettings.php
deleted file mode 100644
index 4425d5c..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FieldSettings.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6FieldSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing field.settings.yml migration.
- */
-class Drupal6FieldSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'field_language_fallback',
-        'value' => 'b:1;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FileSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FileSettings.php
deleted file mode 100644
index 61a1209..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FileSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6FileSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing file.settings.yml migration.
- */
-class Drupal6FileSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'file_description_type',
-        'value' => 's:9:"textfield";',
-    ))
-    ->values(array(
-      'name' => 'file_description_length',
-        'value' => 'i:128;',
-    ))
-    ->values(array(
-      'name' => 'file_icon_directory',
-      'value' => 's:25:"sites/default/files/icons";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ForumSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ForumSettings.php
deleted file mode 100644
index d75700e..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ForumSettings.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6ForumSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing forum.site.yml migration.
- */
-class Drupal6ForumSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'forum_hot_topic',
-      'value' => 's:2:"15";',
-    ))
-    ->values(array(
-      'name' => 'forum_per_page',
-      'value' => 's:2:"25";',
-    ))
-    ->values(array(
-      'name' => 'forum_order',
-      'value' => 's:1:"1";',
-    ))
-    ->values(array(
-      'name' => 'forum_nav_vocabulary',
-      'value' => 's:1:"1";',
-    ))
-    // 'forum_block_num_active' in D8.
-    ->values(array(
-      'name' => 'forum_block_num_0',
-      'value' => 's:1:"5";',
-    ))
-    // 'forum_block_num_new' in D8.
-    ->values(array(
-      'name' => 'forum_block_num_1',
-      'value' => 's:1:"5";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6LocaleSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6LocaleSettings.php
deleted file mode 100644
index c32dedb..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6LocaleSettings.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6LocaleSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing locale.settings.yml migration.
- */
-class Drupal6LocaleSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'locale_cache_strings',
-      'value' => 'i:1;',
-    ))
-    ->values(array(
-      'name' => 'locale_js_directory',
-      'value' => 's:9:"languages";',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php
deleted file mode 100644
index dc6fe2d..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6MenuSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing menu.settings.yml migration.
- */
-class Drupal6MenuSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'menu_primary_links_source',
-      'value' => 's:13:"primary-links";',
-    ))
-    ->values(array(
-      'name' => 'menu_secondary_links_source',
-      'value' => 's:15:"secondary-links";',
-    ))
-    ->values(array(
-      'name' => 'menu_override_parent_selector',
-      'value' => 'b:0;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6NodeSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6NodeSettings.php
deleted file mode 100644
index d0af31a..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6NodeSettings.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6NodeSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing node.settings.yml migration.
- */
-class Drupal6NodeSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'node_admin_theme',
-      'value' => 'i:0;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SearchSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SearchSettings.php
deleted file mode 100644
index 0b9d5af..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SearchSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate\Tests\Drupal6SearchSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing forum.site.yml migration.
- */
-class Drupal6SearchSettings {
-
-  /**
-   * Mock the database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The mocked database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'minimum_word_size',
-      'value' => 's:1:"3";',
-    ))
-    ->values(array(
-      'name' => 'overlap_cjk',
-      'value' => 'i:1;',
-    ))
-    ->values(array(
-      'name' => 'search_cron_limit',
-      'value' => 's:3:"100";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SimpletestSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SimpletestSettings.php
deleted file mode 100644
index 77f7c51..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SimpletestSettings.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SimpletestSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing simpletest.settings.yml migration.
- */
-class Drupal6SimpletestSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'simpletest_clear_results',
-      'value' => 'b:1;',
-    ))
-    ->values(array(
-      'name' => 'simpletest_httpauth_method',
-      'value' => 'i:1;',
-    ))
-    ->values(array(
-      'name' => 'simpletest_httpauth_password',
-      'value' => 'N;',
-    ))
-    ->values(array(
-      'name' => 'simpletest_httpauth_username',
-      'value' => 'N;',
-    ))
-    ->values(array(
-      'name' => 'simpletest_verbose',
-      'value' => 'b:1;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6StatisticsSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6StatisticsSettings.php
deleted file mode 100644
index 573a5b4..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6StatisticsSettings.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6StatisticsSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing statistics.settings.yml migration.
- */
-class Drupal6StatisticsSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'statistics_enable_access_log',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'statistics_flush_accesslog_timer',
-      'value' => 'i:259200;',
-    ))
-    ->values(array(
-      'name' => 'statistics_count_content_view',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'statistics_block_top_day_num',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'statistics_block_top_all_num',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'statistics_block_top_last_num',
-      'value' => 'i:0;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SyslogSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SyslogSettings.php
deleted file mode 100644
index ac0016b..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SyslogSettings.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SyslogSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing syslog.settings.yml migration.
- */
-class Drupal6SyslogSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'syslog_facility',
-      'value' => 'i:128;',
-    ))
-    ->values(array(
-      'name' => 'syslog_identity',
-      'value' => 's:6:"drupal";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php
index b08e904..6c68424 100644
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemCron.
+ * Contains \Drupal\migrate\Tests\Drupal6SystemCron.
  */
 
 namespace Drupal\migrate_drupal\Tests\Dump;
@@ -21,7 +21,27 @@ class Drupal6SystemCron {
    *   The database connection.
    */
   public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
+    $database->schema()->createTable('variable', array(
+      'fields' => array(
+        'name' => array(
+          'type' => 'varchar',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ),
+        'value' => array(
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+          'translatable' => TRUE,
+        ),
+      ),
+      'primary key' => array(
+        'name',
+      ),
+      'module' => 'system',
+      'name' => 'variable',
+    ));
     $database->insert('variable')->fields(array(
       'name',
       'value',
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFile.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFile.php
deleted file mode 100644
index 14b8ee0..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFile.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemFile.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.file.yml migration.
- */
-class Drupal6SystemFile {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'file_directory_path',
-      'value' => 's:10:"files/test";',
-    ))
-    ->values(array(
-      'name' => 'file_directory_temp',
-      'value' => 's:10:"files/temp";',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFilter.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFilter.php
deleted file mode 100644
index 22f0813..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFilter.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemFilter.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.filter.yml migration.
- */
-class Drupal6SystemFilter {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'filter_allowed_protocols',
-      'value' => 'a:13:{i:0;s:4:"http";i:1;s:5:"https";i:2;s:3:"ftp";i:3;s:4:"news";i:4;s:4:"nntp";i:5;s:3:"tel";i:6;s:6:"telnet";i:7;s:6:"mailto";i:8;s:3:"irc";i:9;s:3:"ssh";i:10;s:4:"sftp";i:11;s:6:"webcal";i:12;s:4:"rtsp";}',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImage.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImage.php
deleted file mode 100644
index 90fd2f8..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImage.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemImage.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.image.yml migration.
- */
-class Drupal6SystemImage {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'image_toolkit',
-      'value' => 's:2:"gd";',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImageGd.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImageGd.php
deleted file mode 100644
index a5b0875..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImageGd.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemImageGd.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.image.gd.yml migration.
- */
-class Drupal6SystemImageGd {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'image_jpeg_quality',
-      'value' => 'i:75;',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemMaintenance.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemMaintenance.php
deleted file mode 100644
index 8521f39..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemMaintenance.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemMaintenance.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.maintenance.yml migration.
- */
-class Drupal6SystemMaintenance {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'site_offline',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'site_offline_message',
-      'value' => 's:94:"Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.";',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php
index 0fd8153..91f1a23 100644
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemPerformance.
+ * Contains \Drupal\migrate\Tests\Drupal6SystemPerformance.
  */
 
 namespace Drupal\migrate_drupal\Tests\Dump;
@@ -21,7 +21,27 @@ class Drupal6SystemPerformance {
    *   The database connection.
    */
   public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
+    $database->schema()->createTable('variable', array(
+      'fields' => array(
+        'name' => array(
+          'type' => 'varchar',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ),
+        'value' => array(
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+          'translatable' => TRUE,
+        ),
+      ),
+      'primary key' => array(
+        'name',
+      ),
+      'module' => 'system',
+      'name' => 'variable',
+    ));
     $database->insert('variable')->fields(array(
       'name',
       'value',
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php
index 2090030..f6f1cf8 100644
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemRss.
+ * Contains \Drupal\migrate\Tests\Drupal6SystemRss.
  */
 
 namespace Drupal\migrate_drupal\Tests\Dump;
@@ -21,7 +21,27 @@ class Drupal6SystemRss {
    *   The database connection.
    */
   public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
+    $database->schema()->createTable('variable', array(
+      'fields' => array(
+        'name' => array(
+          'type' => 'varchar',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ),
+        'value' => array(
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+          'translatable' => TRUE,
+        ),
+      ),
+      'primary key' => array(
+        'name',
+      ),
+      'module' => 'system',
+      'name' => 'variable',
+    ));
     $database->insert('variable')->fields(array(
       'name',
       'value',
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php
index 2310fb5..e320417 100644
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php
@@ -1,10 +1,5 @@
 <?php
 
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemSite.
- */
-
 namespace Drupal\migrate_drupal\Tests\Dump;
 
 use Drupal\Core\Database\Connection;
@@ -15,24 +10,41 @@
 class Drupal6SystemSite {
 
   /**
-   * Sample database schema and values.
-   *
    * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
    */
   public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
+    $database->schema()->createTable('variable', array(
+      'fields' => array(
+        'name' => array(
+          'type' => 'varchar',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ),
+        'value' => array(
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+          'translatable' => TRUE,
+        ),
+      ),
+      'primary key' => array(
+        'name',
+      ),
+      'module' => 'system',
+      'name' => 'variable',
+    ));
     $database->insert('variable')->fields(array(
       'name',
       'value',
     ))
     ->values(array(
       'name' => 'site_name',
-      'value' => 's:9:"site_name";',
+      'value' => 's:6:"drupal";',
     ))
     ->values(array(
       'name' => 'site_mail',
-      'value' => 's:21:"site_mail@example.com";',
+      'value' => 's:17:"admin@example.com";',
     ))
     ->values(array(
       'name' => 'site_slogan',
@@ -40,7 +52,7 @@ public static function load(Connection $database) {
     ))
     ->values(array(
       'name' => 'site_frontpage',
-      'value' => 's:4:"node";',
+      'value' => 's:12:"anonymous-hp";',
     ))
     ->values(array(
       'name' => 'site_403',
@@ -51,6 +63,10 @@ public static function load(Connection $database) {
       'value' => 's:14:"page-not-found";',
     ))
     ->values(array(
+      'name' => 'drupal_weight_select_max',
+      'value' => 'i:99;',
+    ))
+    ->values(array(
       'name' => 'admin_compact_mode',
       'value' => 'b:0;',
     ))
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemTheme.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemTheme.php
deleted file mode 100644
index 4b015b5..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemTheme.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6SystemTheme.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing system.theme.yml migration.
- */
-class Drupal6SystemTheme {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'admin_theme',
-      'value' => 'i:0;',
-    ))
-    ->values(array(
-      'name' => 'theme_default',
-      'value' => 's:7:"garland";',
-    ))
-    ->execute();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TaxonomySettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TaxonomySettings.php
deleted file mode 100644
index 9fc9d1a..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TaxonomySettings.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6TaxonomySettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing taxonomy.settings.yml migration.
- */
-class Drupal6TaxonomySettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'taxonomy_override_selector',
-      'value' => 'b:0;',
-    ))
-    ->values(array(
-      'name' => 'taxonomy_terms_per_page_admin',
-      'value' => 'i:100;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TextSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TextSettings.php
deleted file mode 100644
index 02ba13a..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TextSettings.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6TextSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing text.settings.yml migration.
- */
-class Drupal6TextSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'teaser_length',
-      'value' => 'i:600;',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UpdateSettings.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UpdateSettings.php
deleted file mode 100644
index 8198802..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UpdateSettings.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6UpdateSettings.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing update.settings.yml migration.
- */
-class Drupal6UpdateSettings {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'update_max_fetch_attempts',
-      'value' => 'i:2;',
-    ))
-    ->values(array(
-      'name' => 'update_fetch_url',
-      'value' => 's:41:"http://updates.drupal.org/release-history";',
-    ))
-    ->values(array(
-      'name' => 'update_notification_threshold',
-      'value' => 's:3:"all";',
-    ))
-    ->values(array(
-      'name' => 'update_notify_emails',
-      'value' => 'a:0:{}',
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserMail.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserMail.php
deleted file mode 100644
index 7784e74..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserMail.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6UserMail.
- */
-
-namespace Drupal\migrate_drupal\Tests\Dump;
-
-use Drupal\Core\Database\Connection;
-
-/**
- * Database dump for testing user.mail.yml migration.
- */
-class Drupal6UserMail {
-
-  /**
-   * Sample database schema and values.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   */
-  public static function load(Connection $database) {
-    Drupal6DumpCommon::createVariable($database);
-    $database->insert('variable')->fields(array(
-      'name',
-      'value',
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_activated_subject',
-      'value' => 's:49:"Account details for !username at !site (approved)";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_activated_body',
-      'value' => "s:419:\"!username,\n\nYour account at !site has been activated.\n\nYou may now log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\nOnce you have set your own password, you will be able to log in to !login_uri in the future using:\n\nusername: !username\n\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_password_reset_subject',
-      'value' => 's:52:"Replacement login information for !username at !site";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_password_reset_body',
-      'value' => "s:409:\"!username,\n\nA request to reset the password for your account has been made at !site.\n\nYou may now log in to !uri_brief by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_deleted_subject',
-      'value' => 's:48:"Account details for !username at !site (deleted)";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_deleted_body',
-      'value' => "s:51:\"!username,\n\nYour account on !site has been deleted.\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_register_admin_created_subject',
-      'value' => 's:52:"An administrator created an account for you at !site";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_register_admin_created_body',
-      'value' => "s:452:\"!username,\n\nA site administrator at !site has created an account for you. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n--  !site team\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_register_no_approval_required_subject',
-      'value' => 's:38:"Account details for !username at !site";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_register_no_approval_required_body',
-      'value' => "s:426:\"!username,\n\nThank you for registering at !site. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n--  !site team\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_user_mail_register_pending_approval_subject',
-      'value' => 's:63:"Account details for !username at !site (pending admin approval)";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_user_mail_register_pending_approval_body',
-      'value' => "s:268:\"!username,\n\nThank you for registering at !site. Your application for an account is currently pending approval. Once it has been approved, you will receive another e-mail containing information about how to log in, set your password, and other details.\n\n\n--  !site team\";",
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_blocked_subject',
-      'value' => 's:48:"Account details for !username at !site (blocked)";',
-    ))
-    ->values(array(
-      'name' => 'user_mail_status_blocked_body',
-      'value' => "s:51:\"!username,\n\nYour account on !site has been blocked.\";",
-    ))
-    ->execute();
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/MigrateSystemConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/MigrateSystemConfigsTest.php
new file mode 100644
index 0000000..a878076
--- /dev/null
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/MigrateSystemConfigsTest.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Upgrade\MigrateSystemSiteTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests;
+
+use Drupal\migrate\MigrateMessage;
+use Drupal\migrate\MigrateExecutable;
+
+class MigrateSystemConfigsTest extends MigrateDrupalTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name'  => 'Migrate variables to system.*.yml',
+      'description'  => 'Upgrade variables to system.*.yml',
+      'group' => 'Migrate Drupal',
+    );
+  }
+
+  function testSystemSite() {
+    $migration = entity_load('migration', 'd6_system_site');
+    $dumps = array(
+      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, new MigrateMessage);
+    $executable->import();
+    $config = \Drupal::config('system.site');
+    $this->assertIdentical($config->get('name'), 'drupal');
+    $this->assertIdentical($config->get('mail'), 'admin@example.com');
+    $this->assertIdentical($config->get('slogan'), 'Migrate rocks');
+    $this->assertIdentical($config->get('page.front'), 'anonymous-hp');
+    $this->assertIdentical($config->get('page.403'), 'user');
+    $this->assertIdentical($config->get('page.404'), 'page-not-found');
+    $this->assertIdentical($config->get('weight_select_max'), 99);
+    $this->assertIdentical($config->get('admin_compact_mode'), FALSE);
+  }
+
+  /**
+   * Tests migration of system (cron) variables to system.cron.yml.
+   */
+  public function testSystemCron() {
+    $migration = entity_load('migration', 'd6_system_cron');
+    $dumps = array(
+      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, new MigrateMessage());
+    $executable->import();
+    $config = \Drupal::config('system.cron');
+    $this->assertIdentical($config->get('threshold.warning'), 172800);
+    $this->assertIdentical($config->get('threshold.error'), 1209600);
+  }
+
+  /**
+   * Tests migration of system (rss) variables to system.rss.yml.
+   */
+  public function testSystemRss() {
+    $migration = entity_load('migration', 'd6_system_rss');
+    $dumps = array(
+      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, new MigrateMessage());
+    $executable->import();
+    $config = \Drupal::config('system.rss');
+    $this->assertIdentical($config->get('items.limit'), 10);
+  }
+
+  /**
+   * Tests migration of system (Performance) variables to system.performance.yml.
+   */
+  public function testSystemPerformance() {
+    $migration = entity_load('migration', 'd6_system_performance');
+    $dumps = array(
+      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, new MigrateMessage());
+    $executable->import();
+    $config = \Drupal::config('system.performance');
+    $this->assertIdentical($config->get('css.preprocess'), FALSE);
+    $this->assertIdentical($config->get('js.preprocess'), FALSE);
+    $this->assertIdentical($config->get('cache.page.max_age'), 0);
+  }
+}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateActionConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateActionConfigsTest.php
deleted file mode 100644
index 3c9c833..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateActionConfigsTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateActionConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Action module.
- */
-class MigrateActionConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to action.settings.yml',
-      'description'  => 'Upgrade variables to action.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of action variables to action.settings.yml.
-   */
-  public function testActionSettings() {
-    $migration = entity_load('migration', 'd6_action_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ActionSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('action.settings');
-    $this->assertIdentical($config->get('recursion_limit'), 35);
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateAggregatorConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateAggregatorConfigsTest.php
deleted file mode 100644
index d3cc6a5..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateAggregatorConfigsTest.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateAggregatorConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Aggregator module.
- */
-class MigrateAggregatorConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to aggregator.settings.yml',
-      'description'  => 'Upgrade variables to aggregator.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of aggregator variables to aggregator.settings.yml.
-   */
-  public function testAggregatorSettings() {
-    $migration = entity_load('migration', 'd6_aggregator_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6AggregatorSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('aggregator.settings');
-    $this->assertIdentical($config->get('fetcher'), 'aggregator');
-    $this->assertIdentical($config->get('parser'), 'aggregator');
-    $this->assertIdentical($config->get('processors'), array('aggregator'));
-    $this->assertIdentical($config->get('items.teaser_length'), 600);
-    $this->assertIdentical($config->get('items.allowed_html'), '<a> <b> <br /> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>');
-    $this->assertIdentical($config->get('items.expire'), 9676800);
-    $this->assertIdentical($config->get('source.list_max'), 3);
-    $this->assertIdentical($config->get('source.category_selector'), 'checkboxes');
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateBookConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateBookConfigsTest.php
deleted file mode 100644
index 8e52d10..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateBookConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateBookConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Book module.
- */
-class MigrateBookConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to book.settings.yml',
-      'description'  => 'Upgrade variables to book.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of book variables to book.settings.yml.
-   */
-  public function testBookSettings() {
-    $migration = entity_load('migration', 'd6_book_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6BookSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('book.settings');
-    $this->assertIdentical($config->get('child_type'), 'book');
-    $this->assertIdentical($config->get('block.navigation.mode'), 'all pages');
-    $this->assertIdentical($config->get('allowed_types'), array('book'));
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateContactConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateContactConfigsTest.php
deleted file mode 100644
index 7eb7788..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateContactConfigsTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateContactConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Contact module.
- */
-class MigrateContactConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to contact.settings',
-      'description'  => 'Upgrade variables to contact.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of aggregator variables to aggregator.settings.yml.
-   */
-  public function testContactSettings() {
-    $migration = entity_load('migration', 'd6_contact_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ContactSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('contact.settings');
-    $this->assertIdentical($config->get('user_default_enabled'), true);
-    $this->assertIdentical($config->get('flood.limit'), 3);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateDblogConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateDblogConfigsTest.php
deleted file mode 100644
index c761b21..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateDblogConfigsTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateDblogConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the dblog module.
- */
-class MigrateDblogConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to dblog.settings.yml',
-      'description'  => 'Upgrade variables to dblog.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of dblog variables to dblog.settings.yml.
-   */
-  public function testBookSettings() {
-    $migration = entity_load('migration', 'd6_dblog_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6DblogSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('dblog.settings');
-    $this->assertIdentical($config->get('row_limit'), 1000);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFieldConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFieldConfigsTest.php
deleted file mode 100644
index 0192130..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFieldConfigsTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateFieldConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Field module.
- */
-class MigrateFieldConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to field.settings.yml',
-      'description'  => 'Upgrade variables to field.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of field variables to field.settings.yml.
-   */
-  public function testFieldSettings() {
-    $migration = entity_load('migration', 'd6_field_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FieldSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('field.settings');
-    $this->assertIdentical($config->get('language_fallback'), TRUE);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFileConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFileConfigsTest.php
deleted file mode 100644
index 2422c4e..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateFileConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateFileConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the File module.
- */
-class MigrateFileConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to file.settings.yml',
-      'description'  => 'Upgrade variables to file.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of file variables to file.settings.yml.
-   */
-  public function testFileSettings() {
-    $migration = entity_load('migration', 'd6_file_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6FileSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('file.settings');
-    $this->assertIdentical($config->get('description.type'), 'textfield');
-    $this->assertIdentical($config->get('description.length'), 128);
-    $this->assertIdentical($config->get('icon.directory'), 'sites/default/files/icons');
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateForumConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateForumConfigsTest.php
deleted file mode 100644
index c492a09..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateForumConfigsTest.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateForumConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables for the Forum module.
- */
-class MigrateForumConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to forum.settings.yml',
-      'description'  => 'Upgrade variables to forum.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of forum variables to forum.settings.yml.
-   */
-  public function testForumSettings() {
-    $migration = entity_load('migration', 'd6_forum_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ForumSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('forum.settings');
-    $this->assertIdentical($config->get('topics.hot_threshold'), 15);
-    $this->assertIdentical($config->get('topics.page_limit'), 25);
-    $this->assertIdentical($config->get('topics.order'), 1);
-    // The vocabulary vid depends on existing vids when the Forum module was enabled. This would have to be user-selectable based on a query to the D6 vocabulary table.
-    //$this->assertIdentical($config->get('forum_nav_vocabulary'), '1');
-    // This is 'forum_block_num_0' in D6, but block:active:limit' in D8.
-    $this->assertIdentical($config->get('block.active.limit'), 5);
-    // This is 'forum_block_num_1' in D6, but 'block:new:limit' in D8.
-    $this->assertIdentical($config->get('block.new.limit'), 5);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateLocaleConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateLocaleConfigsTest.php
deleted file mode 100644
index ff058db..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateLocaleConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateLocaleConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Locale module.
- */
-class MigrateLocaleConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to locale.settings.yml',
-      'description'  => 'Upgrade variables to locale.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of locale variables to locale.settings.yml.
-   */
-  public function testLocaleSettings() {
-    $migration = entity_load('migration', 'd6_locale_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6LocaleSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('locale.settings');
-    $this->assertIdentical($config->get('cache_string'), 1);
-    $this->assertIdentical($config->get('javascript.directory'), 'languages');
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateMenuConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateMenuConfigsTest.php
deleted file mode 100644
index ebd83e5..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateMenuConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateMenuConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables for the Menu module.
- */
-class MigrateMenuConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to menu.settings.yml',
-      'description'  => 'Upgrade variables to menu.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of forum variables to forum.settings.yml.
-   */
-  public function testMenuSettings() {
-    $migration = entity_load('migration', 'd6_menu_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('menu.settings');
-    $this->assertIdentical($config->get('main_links'), 'primary-links');
-    $this->assertIdentical($config->get('secondary_links'), 'secondary-links');
-    $this->assertIdentical($config->get('override_parent_selector'), FALSE);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateNodeConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateNodeConfigsTest.php
deleted file mode 100644
index a44b229..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateNodeConfigsTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateSystemSiteTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-class MigrateNodeConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to node.settings.yml',
-      'description'  => 'Upgrade variables to node.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  function testNodeSettings() {
-    $migration = entity_load('migration', 'd6_node_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6NodeSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage);
-    $executable->import();
-    $config = \Drupal::config('node.settings');
-    $this->assertIdentical($config->get('use_admin_theme'), false);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSearchConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSearchConfigsTest.php
deleted file mode 100644
index 414296f..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSearchConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateSearchConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables for the Search module.
- */
-class MigrateSearchConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to search.settings.yml',
-      'description'  => 'Upgrade variables to search.settings.yml',
-      'group' => 'Migrate',
-    );
-  }
-
-  /**
-   * Tests migration of search variables to search.settings.yml.
-   */
-  public function testSearchSettings() {
-    $migration = entity_load('migration', 'd6_search_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SearchSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('search.settings');
-    $this->assertIdentical($config->get('index.minimum_word_size'), 3);
-    $this->assertIdentical($config->get('index.overlap_cjk'), TRUE);
-    $this->assertIdentical($config->get('index.cron_limit'), 100);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSimpletestConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSimpletestConfigsTest.php
deleted file mode 100644
index 8a6fd1e..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSimpletestConfigsTest.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateSimpletestConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Simpletest module.
- */
-class MigrateSimpletestConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to simpletest.settings.yml',
-      'description'  => 'Upgrade variables to simpletest.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of simpletest variables to simpletest.settings.yml.
-   */
-  public function testSimpletestSettings() {
-    $migration = entity_load('migration', 'd6_simpletest_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SimpletestSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('simpletest.settings');
-    $this->assertIdentical($config->get('clear_results'), TRUE);
-    $this->assertIdentical($config->get('httpauth.method'), CURLAUTH_BASIC);
-    $this->assertIdentical($config->get('httpauth.password'), NULL);
-    $this->assertIdentical($config->get('httpauth.username'), NULL);
-    $this->assertIdentical($config->get('verbose'), TRUE);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateStatisticsConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateStatisticsConfigsTest.php
deleted file mode 100644
index 15da7f1..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateStatisticsConfigsTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateStatisticsConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Statistics module.
- */
-class MigrateStatisticsConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to statistics.settings.yml',
-      'description'  => 'Upgrade variables to statistics.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of statistics variables to statistics.settings.yml.
-   */
-  public function testStatisticsSettings() {
-    $migration = entity_load('migration', 'd6_statistics_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6StatisticsSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('statistics.settings');
-    $this->assertIdentical($config->get('access_log.enable'), 0);
-    $this->assertIdentical($config->get('access_log.max_lifetime'), 259200);
-    $this->assertIdentical($config->get('count_content_views'), NULL);
-    $this->assertIdentical($config->get('block.popular.top_day_limit'), 0);
-    $this->assertIdentical($config->get('block.popular.top_all_limit'), 0);
-    $this->assertIdentical($config->get('block.popular.top_recent_limit'), 0);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSyslogConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSyslogConfigsTest.php
deleted file mode 100644
index 1f29060..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSyslogConfigsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateSyslogConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Syslog module.
- */
-class MigrateSyslogConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to syslog.settings.yml',
-      'description'  => 'Upgrade variables to syslog.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of syslog variables to syslog.settings.yml.
-   */
-  public function testSyslogSettings() {
-    $migration = entity_load('migration', 'd6_syslog_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SyslogSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('syslog.settings');
-    $this->assertIdentical($config->get('identity'), 'drupal');
-    // @TODO: change this to integer once there's schema of this config.
-    $this->assertIdentical($config->get('facility'), '128');
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSystemConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSystemConfigsTest.php
deleted file mode 100644
index 0367775..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSystemConfigsTest.php
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateSystemSiteTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-class MigrateSystemConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to system.*.yml',
-      'description'  => 'Upgrade variables to system.*.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of system (cron) variables to system.cron.yml.
-   */
-  public function testSystemCron() {
-    $migration = entity_load('migration', 'd6_system_cron');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemCron.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.cron');
-    $this->assertIdentical($config->get('threshold.warning'), 172800);
-    $this->assertIdentical($config->get('threshold.error'), 1209600);
-  }
-
-  /**
-   * Tests migration of system (rss) variables to system.rss.yml.
-   */
-  public function testSystemRss() {
-    $migration = entity_load('migration', 'd6_system_rss');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemRss.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.rss');
-    $this->assertIdentical($config->get('items.limit'), 10);
-  }
-
-  /**
-   * Tests migration of system (Performance) variables to system.performance.yml.
-   */
-  public function testSystemPerformance() {
-    $migration = entity_load('migration', 'd6_system_performance');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemPerformance.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.performance');
-    $this->assertIdentical($config->get('css.preprocess'), false);
-    $this->assertIdentical($config->get('js.preprocess'), false);
-    $this->assertIdentical($config->get('cache.page.max_age'), 0);
-  }
-
-  /**
-   * Tests migration of system (theme) variables to system.theme.yml.
-   */
-  public function testSystemTheme() {
-    $migration = entity_load('migration', 'd6_system_theme');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemTheme.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.theme');
-    $this->assertIdentical($config->get('admin'), '0');
-    $this->assertIdentical($config->get('default'), 'garland');
-  }
-
-  /**
-   * Tests migration of system (maintenance) variables to system.maintenance.yml.
-   */
-  public function testSystemMaintenance() {
-    $migration = entity_load('migration', 'd6_system_maintenance');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemMaintenance.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.maintenance');
-    $this->assertIdentical($config->get('enable'), 0);
-    $this->assertIdentical($config->get('message'), 'Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.');
-  }
-
-  /**
-   * Tests migration of system (site) variables to system.site.yml.
-   */
-  public function testSystemSite() {
-    $migration = entity_load('migration', 'd6_system_site');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.site');
-    $this->assertIdentical($config->get('name'), 'site_name');
-    $this->assertIdentical($config->get('mail'), 'site_mail@example.com');
-    $this->assertIdentical($config->get('slogan'), 'Migrate rocks');
-    $this->assertIdentical($config->get('page.403'), 'user');
-    $this->assertIdentical($config->get('page.404'), 'page-not-found');
-    $this->assertIdentical($config->get('page.front'), 'node');
-    $this->assertIdentical($config->get('admin_compact_mode'), FALSE);
-  }
-
-  /**
-   * Tests migration of system (filter) variables to system.filter.yml.
-   */
-  public function testSystemFilter() {
-    $migration = entity_load('migration', 'd6_system_filter');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFilter.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.filter');
-    $this->assertIdentical($config->get('protocols'), array('http', 'https', 'ftp', 'news', 'nntp', 'tel', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal', 'rtsp'));
-  }
-
-  /**
-   * Tests migration of system (image) variables to system.image.yml.
-   */
-  public function testSystemImage() {
-    $migration = entity_load('migration', 'd6_system_image');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImage.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.image');
-    $this->assertIdentical($config->get('toolkit'), 'gd');
-  }
-
-  /**
-   * Tests migration of system (image GD) variables to system.image.gd.yml.
-   */
-  public function testSystemImageGd() {
-    $migration = entity_load('migration', 'd6_system_image_gd');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemImageGd.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('system.image.gd');
-    $this->assertIdentical($config->get('jpeg_quality'), 75);
-  }
-
-  /**
-   * Tests migration of system (file) variables to system.file.yml.
-   */
-  public function testSystemFile() {
-    $migration = entity_load('migration', 'd6_system_file');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemFile.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    config_context_enter('config.context.free');
-    $config = \Drupal::config('system.file');
-    $this->assertIdentical($config->get('path.private'), 'files/test');
-    $this->assertIdentical($config->get('path.temporary'), 'files/temp');
-    config_context_leave();
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTaxonomyConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTaxonomyConfigsTest.php
deleted file mode 100644
index e21e8c4..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTaxonomyConfigsTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateTaxonomyConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Taxonomy module.
- */
-class MigrateTaxonomyConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to taxonomy.settings.yml',
-      'description'  => 'Upgrade variables to taxonomy.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of taxonomy variables to taxonomy.settings.yml.
-   */
-  public function testTaxonomySettings() {
-    $migration = entity_load('migration', 'd6_taxonomy_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TaxonomySettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('taxonomy.settings');
-    $this->assertIdentical($config->get('terms_per_page_admin'), 100);
-    $this->assertIdentical($config->get('override_selector'), FALSE);
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTextConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTextConfigsTest.php
deleted file mode 100644
index ad96394..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateTextConfigsTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateTextConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Text module.
- */
-class MigrateTextConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to text.settings.yml',
-      'description'  => 'Upgrade variables to text.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of text variables to text.settings.yml.
-   */
-  public function testTextSettings() {
-    $migration = entity_load('migration', 'd6_text_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6TextSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('text.settings');
-    $this->assertIdentical($config->get('default_summary_length'), 600);
-  }
-
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUpdateConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUpdateConfigsTest.php
deleted file mode 100644
index d35ba9a..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUpdateConfigsTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateUpdateConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the Update module.
- */
-class MigrateUpdateConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to update.settings.yml',
-      'description'  => 'Upgrade variables to update.settings.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of update variables to update.settings.yml.
-   */
-  public function testUpdateSettings() {
-    $migration = entity_load('migration', 'd6_update_settings');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UpdateSettings.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('update.settings');
-    $this->assertIdentical($config->get('fetch.max_attempts'), 2);
-    $this->assertIdentical($config->get('fetch.url'), 'http://updates.drupal.org/release-history');
-    $this->assertIdentical($config->get('notification.threshold'), 'all');
-    $this->assertIdentical($config->get('notification.mails'), array());
-  }
-}
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserConfigsTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserConfigsTest.php
deleted file mode 100644
index 3d35256..0000000
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserConfigsTest.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Tests\d6\MigrateUserConfigsTest.
- */
-
-namespace Drupal\migrate_drupal\Tests\d6;
-
-use Drupal\migrate\MigrateMessage;
-use Drupal\migrate\MigrateExecutable;
-use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
-
-/**
- * Tests migration of variables from the User module.
- */
-class MigrateUserConfigsTest extends MigrateDrupalTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name'  => 'Migrate variables to user.*.yml',
-      'description'  => 'Upgrade variables to user.*.yml',
-      'group' => 'Migrate Drupal',
-    );
-  }
-
-  /**
-   * Tests migration of user variables to user.mail.yml.
-   */
-  public function testUserMail() {
-    $migration = entity_load('migration', 'd6_user_mail');
-    $dumps = array(
-      drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserMail.php',
-    );
-    $this->prepare($migration, $dumps);
-    $executable = new MigrateExecutable($migration, new MigrateMessage());
-    $executable->import();
-    $config = \Drupal::config('user.mail');
-    $this->assertIdentical($config->get('status_activated.subject'), 'Account details for !username at !site (approved)');
-    $this->assertIdentical($config->get('status_activated.body'), "!username,\n\nYour account at !site has been activated.\n\nYou may now log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\nOnce you have set your own password, you will be able to log in to !login_uri in the future using:\n\nusername: !username\n");
-    $this->assertIdentical($config->get('password_reset.subject'), 'Replacement login information for !username at !site');
-    $this->assertIdentical($config->get('password_reset.body'), "!username,\n\nA request to reset the password for your account has been made at !site.\n\nYou may now log in to !uri_brief by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.");
-    $this->assertIdentical($config->get('cancel_confirm.subject'), 'Account details for !username at !site (deleted)');
-    $this->assertIdentical($config->get('cancel_confirm.body'), "!username,\n\nYour account on !site has been deleted.");
-    $this->assertIdentical($config->get('register_admin_created.subject'), 'An administrator created an account for you at !site');
-    $this->assertIdentical($config->get('register_admin_created.body'), "!username,\n\nA site administrator at !site has created an account for you. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n--  !site team");
-    $this->assertIdentical($config->get('register_no_approval_required.subject'), 'Account details for !username at !site');
-    $this->assertIdentical($config->get('register_no_approval_required.body'), "!username,\n\nThank you for registering at !site. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n--  !site team");
-    $this->assertIdentical($config->get('register_pending_approval.subject'), 'Account details for !username at !site (pending admin approval)');
-    $this->assertIdentical($config->get('register_pending_approval.body'), "!username,\n\nThank you for registering at !site. Your application for an account is currently pending approval. Once it has been approved, you will receive another e-mail containing information about how to log in, set your password, and other details.\n\n\n--  !site team");
-    $this->assertIdentical($config->get('status_blocked.subject'), 'Account details for !username at !site (blocked)');
-    $this->assertIdentical($config->get('status_blocked.body'), "!username,\n\nYour account on !site has been blocked.");
-  }
-}
diff --git a/core/modules/migrate_drupal/migrate_drupal.info.yml b/core/modules/migrate_drupal/migrate_drupal.info.yml
index 59fb9ae..ccd4a50 100644
--- a/core/modules/migrate_drupal/migrate_drupal.info.yml
+++ b/core/modules/migrate_drupal/migrate_drupal.info.yml
@@ -1,6 +1,6 @@
 name: Migrate Drupal
 type: module
-description: 'Contains migrations from older Drupal versions.'
+description: 'Contains migrations from olders Drupal versions.'
 package: Core
 version: VERSION
 core: 8.x
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
index 573447d..7a3b0dc 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
@@ -524,7 +524,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
     );
     $form['content_ranking']['#theme'] = 'node_search_admin';
     $form['content_ranking']['info'] = array(
-      '#value' => '<em>' . t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em>'
+      '#value' => '<em>' . t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em>'
     );
 
     // Note: reversed to reflect that higher number = higher ranking.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 8becc7f..893b8dd 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -688,6 +688,9 @@ function template_preprocess_node(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 
+  // Make the field variables available with the appropriate language.
+  field_attach_preprocess($node, $variables['content'], $variables);
+
   // Display post information only on certain node types.
   // Avoid loading the entire node type config entity here that may not exist.
   $node_type_config = \Drupal::config('node.type.' . $node->bundle());
@@ -908,7 +911,7 @@ function theme_node_search_admin($variables) {
 
   $output = drupal_render($form['info']);
 
-  $header = array(t('Factor'), t('Influence'));
+  $header = array(t('Factor'), t('Weight'));
   foreach (element_children($form['factors']) as $key) {
     $row = array();
     $row[] = $form['factors'][$key]['#title'];
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 20657c8..018aff6 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -244,7 +244,6 @@ function rdf_theme() {
   return array(
     'rdf_metadata' => array(
       'variables' => array('metadata' => array()),
-      'template' => 'rdf-metadata',
     ),
   );
 }
@@ -544,24 +543,27 @@ function rdf_preprocess_image(&$variables) {
 }
 
 /**
- * Prepares variables for RDF metadata templates.
- *
- * Default template: rdf-metadata.html.twig.
+ * Returns HTML for a series of empty spans for exporting RDF metadata in RDFa.
  *
  * Sometimes it is useful to export data which is not semantically present in
  * the HTML output. For example, a hierarchy of comments is visible for a human
- * but not for machines because this hierarchy is not present in the DOM tree.
+ * but not for machines because this hiearchy is not present in the DOM tree.
  * We can express it in RDFa via empty <span> tags. These aren't visible and
  * give machines extra information about the content and its structure.
  *
- * @param array $variables
+ * @param $variables
  *   An associative array containing:
  *   - metadata: An array of attribute arrays. Each item in the array
  *     corresponds to its own set of attributes, and therefore, needs its own
  *     element.
+ *
+ * @see rdf_process()
+ * @ingroup themeable
+ * @ingroup rdf
  */
-function template_preprocess_rdf_metadata(&$variables) {
-  foreach ($variables['metadata'] as $key => $attributes) {
+function theme_rdf_metadata($variables) {
+  $output = '';
+  foreach ($variables['metadata'] as $attributes) {
     // Add a class so that developers viewing the HTML source can see why there
     // are empty <span> tags in the document. The class can also be used to set
     // a CSS display:none rule in a theme where empty spans affect display.
@@ -570,6 +572,7 @@ function template_preprocess_rdf_metadata(&$variables) {
     // be used, but for maximum browser compatibility, W3C recommends the
     // former when serving pages using the text/html media type, see
     // http://www.w3.org/TR/xhtml1/#C_3.
-    $variables['metadata'][$key] = new Attribute($attributes);
+    $output .= '<span' . new Attribute($attributes) . '></span>';
   }
+  return $output;
 }
diff --git a/core/modules/rdf/templates/rdf-metadata.html.twig b/core/modules/rdf/templates/rdf-metadata.html.twig
deleted file mode 100644
index 81a2f3c..0000000
--- a/core/modules/rdf/templates/rdf-metadata.html.twig
+++ /dev/null
@@ -1,17 +0,0 @@
-{#
-/**
- * @file
- * Default theme implementation for empty spans with RDF attributes.
- *
- * Available variables:
- * - metadata: Each item within corresponds to its own set of attributes,
- *   and therefore, needs its own 'attributes' element.
- *
- * @see template_preprocess_rdf_metadata()
- *
- * @ingroup themeable
- */
-#}
-{% for attributes in metadata %}
-  <span{{ attributes }}></span>
-{% endfor %}
diff --git a/core/modules/simpletest/simpletest.theme.inc b/core/modules/simpletest/simpletest.theme.inc
index 1743b74..4ee0261 100644
--- a/core/modules/simpletest/simpletest.theme.inc
+++ b/core/modules/simpletest/simpletest.theme.inc
@@ -132,12 +132,7 @@ function theme_simpletest_test_table($variables) {
   }
 
   // Add js array of settings.
-  $attached = array();
-  $attached['#attached']['js'][] = array(
-    'data' => array('simpleTest' => $js),
-    'type' => 'setting',
-  );
-  drupal_render($attached);
+  drupal_add_js(array('simpleTest' => $js), 'setting');
 
   if (empty($rows)) {
     return '<strong>' . t('No tests to display.') . '</strong>';
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index 9d585f0..0dabf5e 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -4,9 +4,6 @@ system.site:
   type: mapping
   label: 'Site information'
   mapping:
-    uuid:
-      type: string
-      label: 'Site UUID'
     name:
       type: label
       label: 'Site name'
diff --git a/core/modules/system/config/system.site.yml b/core/modules/system/config/system.site.yml
index 4be7ae6..b1c5df5 100644
--- a/core/modules/system/config/system.site.yml
+++ b/core/modules/system/config/system.site.yml
@@ -1,4 +1,3 @@
-uuid: ''
 name: Drupal
 mail: ''
 slogan: ''
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index 3eb29dd..5ed89cc 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -96,14 +96,14 @@ function hook_ENTITY_TYPE_create_access(\Drupal\Core\Session\AccountInterface $a
 /**
  * Add to entity type definitions.
  *
- * Modules may implement this hook to add information to defined entity types,
- * as defined in \Drupal\Core\Entity\EntityTypeInterface.
+ * Modules may implement this hook to add information to defined entity types.
  *
  * @param \Drupal\Core\Entity\EntityTypeInterface $entity_info
  *   An associative array of all entity type definitions, keyed by the entity
  *   type name. Passed by reference.
  *
  * @see \Drupal\Core\Entity\Entity
+ * @see \Drupal\Core\Entity\EntityManagerInterface
  * @see \Drupal\Core\Entity\EntityTypeInterface
  */
 function hook_entity_info(&$entity_info) {
@@ -114,31 +114,6 @@ function hook_entity_info(&$entity_info) {
 }
 
 /**
- * Alter the entity type definitions.
- *
- * Modules may implement this hook to alter the information that defines an
- * entity type. All properties that are available in
- * \Drupal\Core\Entity\Annotation\EntityType and all the ones additionally
- * provided by modules can be altered here.
- *
- * Do not use this hook to add information to entity types, unless you are just
- * filling-in default values. Use hook_entity_info() instead.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_info
- *   An associative array of all entity type definitions, keyed by the entity
- *   type name. Passed by reference.
- *
- * @see \Drupal\Core\Entity\Entity
- * @see \Drupal\Core\Entity\EntityTypeInterface
- */
-function hook_entity_info_alter(&$entity_info) {
-  /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */
-  // Set the controller class for nodes to an alternate implementation of the
-  // Drupal\Core\Entity\EntityStorageControllerInterface interface.
-  $entity_info['node']->setController('storage', 'Drupal\mymodule\MyCustomNodeStorageController');
-}
-
-/**
  * Alter the view modes for entity types.
  *
  * @param array $view_modes
@@ -246,6 +221,31 @@ function hook_entity_bundle_delete($entity_type, $bundle) {
 }
 
 /**
+ * Alter the entity type definitions.
+ *
+ * Modules may implement this hook to alter the information that defines an
+ * entity type. All properties that are available in
+ * \Drupal\Core\Entity\EntityManagerInterface can be altered here.
+ *
+ * Do not use this hook to add information to entity types. Use
+ * hook_entity_info() for that instead.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_info
+ *   An associative array of all entity type definitions, keyed by the entity
+ *   type name. Passed by reference.
+ *
+ * @see \Drupal\Core\Entity\Entity
+ * @see \Drupal\Core\Entity\EntityManagerInterface
+ * @see \Drupal\Core\Entity\EntityTypeInterface
+ */
+function hook_entity_info_alter(&$entity_info) {
+  /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */
+  // Set the controller class for nodes to an alternate implementation of the
+  // Drupal\Core\Entity\EntityStorageControllerInterface interface.
+  $entity_info['node']->setController('storage', 'Drupal\mymodule\MyCustomNodeStorageController');
+}
+
+/**
  * Act on a newly created entity.
  *
  * This hook runs after a new entity object has just been instantiated. It can
diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemController.php b/core/modules/system/lib/Drupal/system/Controller/SystemController.php
index a51ae40..6145a11 100644
--- a/core/modules/system/lib/Drupal/system/Controller/SystemController.php
+++ b/core/modules/system/lib/Drupal/system/Controller/SystemController.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\system\Controller;
 
-use Drupal\Component\Utility\Json;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\Query\QueryFactory;
@@ -162,69 +161,4 @@ public function themeSetDefault() {
     return system_theme_default();
   }
 
-  /**
-   * #post_render_cache callback; sets the "active" class on relevant links.
-   *
-   * This is a PHP implementation of the drupal.active-link JavaScript library.
-   *
-   * @param array $element
-   *  A renderable array with the following keys:
-   *    - #markup
-   *    - #attached
-   * @param array $context
-   *   An array with the following keys:
-   *   - path: the system path of the currently active page
-   *   - front: whether the current page is the front page (which implies the
-   *     current path might also be <front>)
-   *   - language: the language code of the currently active page
-   *   - query: the query string for the currently active page
-   *
-   * @return array
-   *   The updated renderable array.
-   */
-  public static function setLinkActiveClass(array $element, array $context) {
-    // If none of the HTML in the current page contains even just the current
-    // page's attribute, return early.
-    if (strpos($element['#markup'], 'data-drupal-link-system-path="' . $context['path'] . '"') === FALSE && (!$context['front'] || strpos($element['#markup'], 'data-drupal-link-system-path="&lt;front&gt;"') === FALSE)) {
-      return $element;
-    }
-
-    // Build XPath query to find links that should get the "active" class.
-    $query = "//*[";
-    // An active link's path is equal to the current path.
-    $query .= "@data-drupal-link-system-path='" . $context['path'] . "'";
-    if ($context['front']) {
-      $query .= " or @data-drupal-link-system-path='<front>'";
-    }
-    // The language of an active link is equal to the current language.
-    if ($context['language']) {
-      $query .= " and (not(@hreflang) or @hreflang='" . $context['language'] . "')";
-    }
-    // The query parameters of an active link are equal to the current
-    // parameters.
-    if ($context['query']) {
-      $query .= " and @data-drupal-link-query='" . Json::encode($context['query']) . "'";
-    }
-    else {
-      $query .= " and not(@data-drupal-link-query)";
-    }
-    $query .= "]";
-
-    // Set the "active" class on all matching HTML elements.
-    $dom = new \DOMDocument();
-    @$dom->loadHTML($element['#markup']);
-    $xpath = new \DOMXPath($dom);
-    foreach ($xpath->query($query) as $node) {
-      $class = $node->getAttribute('class');
-      if (strlen($class) > 0) {
-        $class .= ' ';
-      }
-      $class .= 'active';
-      $node->setAttribute('class', $class);
-    }
-    $element['#markup'] = $dom->saveHTML();
-
-    return $element;
-  }
-
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
index 1600b58..6e3ebeb 100644
--- a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
@@ -69,26 +69,22 @@ public function buildForm(array $form, array &$form_state) {
 
     $form['image_toolkit'] = array(
       '#type' => 'radios',
-      '#title' => $this->t('Select an image processing toolkit'),
+      '#title' => t('Select an image processing toolkit'),
       '#default_value' => $current_toolkit,
       '#options' => array(),
     );
 
-    // If we have more than one image toolkit, allow the user to select the one
-    // to use, and load each of the toolkits' settings form.
+    // If we have available toolkits, allow the user to select the image toolkit
+    // to use and load the settings forms.
     foreach ($this->availableToolkits as $id => $toolkit) {
       $definition = $toolkit->getPluginDefinition();
       $form['image_toolkit']['#options'][$id] = $definition['title'];
       $form['image_toolkit_settings'][$id] = array(
-        '#type' => 'details',
-        '#title' => $this->t('@toolkit settings', array('@toolkit' => $definition['title'])),
-        '#collapsed' => FALSE,
+        '#type' => 'fieldset',
+        '#title' => t('@toolkit settings', array('@toolkit' => $definition['title'])),
+        '#collapsible' => TRUE,
+        '#collapsed' => ($id == $current_toolkit) ? FALSE : TRUE,
         '#tree' => TRUE,
-        '#states' => array(
-          'visible' => array(
-            ':radio[name="image_toolkit"]' => array('value' => $id),
-          ),
-        ),
       );
       $form['image_toolkit_settings'][$id] += $toolkit->settingsForm();
     }
@@ -105,6 +101,7 @@ public function submitForm(array &$form, array &$form_state) {
       ->save();
 
     // Call the form submit handler for each of the toolkits.
+    // Get the toolkit settings forms.
     foreach ($this->availableToolkits as $toolkit) {
       $toolkit->settingsFormSubmit($form, $form_state);
     }
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
index e5c5528..5499c94 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
@@ -7,8 +7,9 @@
 
 namespace Drupal\system\Plugin\ImageToolkit;
 
+use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Image\ImageInterface;
-use Drupal\Core\ImageToolkit\ImageToolkitBase;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 use Drupal\Component\Utility\Image as ImageUtility;
 
 /**
@@ -19,7 +20,7 @@
  *   title = @Translation("GD2 image manipulation toolkit")
  * )
  */
-class GDToolkit extends ImageToolkitBase {
+class GDToolkit extends PluginBase implements ImageToolkitInterface {
 
   /**
    * {@inheritdoc}
@@ -324,27 +325,6 @@ public function createTmp(ImageInterface $image, $width, $height) {
   /**
    * {@inheritdoc}
    */
-  public function getRequirements() {
-    $requirements = array();
-
-    $info = gd_info();
-    $requirements['version'] = array(
-      'title' => t('GD library'),
-      'value' => $info['GD Version'],
-    );
-
-    // Check for filter and rotate support.
-    if (!function_exists('imagefilter') || !function_exists('imagerotate')) {
-      $requirements['version']['severity'] = REQUIREMENT_WARNING;
-      $requirements['version']['description'] = t('The GD Library for PHP is enabled, but was compiled without support for functions used by the rotate and desaturate effects. It was probably compiled using the official GD libraries from http://www.libgd.org instead of the GD library bundled with PHP. You should recompile PHP --with-gd using the bundled GD library. See <a href="@url">the PHP manual</a>.', array('@url' => 'http://www.php.net/manual/book.image.php'));
-    }
-
-    return $requirements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function isAvailable() {
     // GD2 support is available.
     return function_exists('imagegd2');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php b/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
index 8450b9c..11204fe 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
@@ -250,28 +250,28 @@ function _resultMessages($id) {
 
     switch ($id) {
       case 'batch_0':
-        $messages[] = 'results for batch 0<br>none';
+        $messages[] = 'results for batch 0<br />none';
         break;
 
       case 'batch_1':
-        $messages[] = 'results for batch 1<br>op 1: processed 10 elements';
+        $messages[] = 'results for batch 1<br />op 1: processed 10 elements';
         break;
 
       case 'batch_2':
-        $messages[] = 'results for batch 2<br>op 2: processed 10 elements';
+        $messages[] = 'results for batch 2<br />op 2: processed 10 elements';
         break;
 
       case 'batch_3':
-        $messages[] = 'results for batch 3<br>op 1: processed 10 elements<br>op 2: processed 10 elements';
+        $messages[] = 'results for batch 3<br />op 1: processed 10 elements<br />op 2: processed 10 elements';
         break;
 
       case 'batch_4':
-        $messages[] = 'results for batch 4<br>op 1: processed 10 elements';
+        $messages[] = 'results for batch 4<br />op 1: processed 10 elements';
         $messages = array_merge($messages, $this->_resultMessages('batch_2'));
         break;
 
       case 'batch_5':
-        $messages[] = 'results for batch 5<br>op 5: processed 10 elements';
+        $messages[] = 'results for batch 5<br />op 5: processed 10 elements';
         break;
 
       case 'chained':
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
index 888a699..3a11ccc 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
@@ -37,9 +37,6 @@ public static function getInfo() {
 
   function setUp() {
     parent::setUp();
-    // There are dependencies in drupal_get_js() on the theme layer so we need
-    // to initialize it.
-    drupal_theme_initialize();
 
     // Disable preprocessing
     $config = \Drupal::config('system.performance');
@@ -83,7 +80,7 @@ function testAddSetting() {
     drupal_add_library('system', 'drupalSettings');
     $javascript = drupal_add_js();
     $last_settings = reset($javascript['settings']['data']);
-    $this->assertTrue(array_key_exists('currentPath', $last_settings['path']), 'The current path JavaScript setting is set correctly.');
+    $this->assertTrue(array_key_exists('currentPath', $last_settings), 'The current path JavaScript setting is set correctly.');
 
     $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting');
     $last_settings = end($javascript['settings']['data']);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
index 12d02b0..f3985e0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
@@ -29,13 +29,6 @@ public static function getInfo() {
     );
   }
 
-  function setUp() {
-    parent::setUp();
-    // There are dependencies in drupal_get_js() on the theme layer so we need
-    // to initialize it.
-    drupal_theme_initialize();
-  }
-
   /**
    * Tests the output drupal_render() for some elementary input values.
    */
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitSetupFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitSetupFormTest.php
deleted file mode 100644
index 8489147..0000000
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitSetupFormTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\system\Tests\Image\ToolkitSetupFormTest.
- */
-
-namespace Drupal\system\Tests\Image;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Functional tests for the Image toolkit setup form.
- */
-class ToolkitSetupFormTest extends WebTestBase {
-
-  /**
-   * Admin user account.
-   *
-   * @var \Drupal\user\Entity\User
-   */
-  protected $admin_user;
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('system', 'image_test');
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Image toolkit setup form tests',
-      'description' => 'Check image toolkit setup form.',
-      'group' => 'Image',
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUp() {
-    parent::setUp();
-    $this->admin_user = $this->drupalCreateUser(array(
-      'access administration pages',
-    ));
-    $this->drupalLogin($this->admin_user);
-  }
-
-  /**
-   * Test Image toolkit setup form.
-   */
-  function testToolkitSetupForm() {
-    // Get form.
-    $this->drupalGet('admin/config/media/image-toolkit');
-
-    // Test that default toolkit is GD.
-    $this->assertFieldByName('image_toolkit', 'gd', 'The default image toolkit is GD.');
-
-    // Test changing the jpeg image quality.
-    $edit = array('gd[image_jpeg_quality]' => '70');
-    $this->drupalPostForm(NULL, $edit, 'Save configuration');
-    $this->assertEqual(\Drupal::config('system.image.gd')->get('jpeg_quality'), '70');
-
-    // Test changing the toolkit.
-    $edit = array('image_toolkit' => 'test');
-    $this->drupalPostForm(NULL, $edit, 'Save configuration');
-    $this->assertEqual(\Drupal::config('system.image')->get('toolkit'), 'test');
-    $this->assertFieldByName('test[test_parameter]', '10');
-
-    // Test changing the test toolkit parameter.
-    $edit = array('test[test_parameter]' => '20');
-    $this->drupalPostForm(NULL, $edit, 'Save configuration');
-    $this->assertEqual(\Drupal::config('system.image.test_toolkit')->get('test_parameter'), '20');
-  }
-}
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/StatusTest.php b/core/modules/system/lib/Drupal/system/Tests/System/StatusTest.php
deleted file mode 100644
index e2a4298..0000000
--- a/core/modules/system/lib/Drupal/system/Tests/System/StatusTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\system\Tests\System\StatusTest.
- */
-
-namespace Drupal\system\Tests\System;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests administrative status page.
- */
-class StatusTest extends WebTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Status page',
-      'description' => 'Tests output on the status overview page.',
-      'group' => 'System',
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $admin_user = $this->drupalCreateUser(array(
-      'administer site configuration',
-    ));
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Tests that the status page returns.
-   */
-  public function testStatusPage() {
-    // Go to Administration.
-    $this->drupalGet('admin/reports/status');
-    $this->assertResponse(200, 'The status page is reachable.');
-  }
-
-}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
index 97335d2..d1930c9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
@@ -2,15 +2,12 @@
 
 /**
  * @file
- * Contains \Drupal\system\Tests\Theme\FunctionsTest.
+ * Definition of Drupal\system\Tests\Theme\FunctionsTest.
  */
 
 namespace Drupal\system\Tests\Theme;
 
-use Drupal\Core\Session\UserSession;
 use Drupal\simpletest\WebTestBase;
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Tests for common theme functions.
@@ -162,6 +159,12 @@ function testLinks() {
     $expected = '';
     $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.');
 
+    // Set the current path to the front page path.
+    // Required to verify the "active" class in expected links below, and
+    // because the current path is different when running tests manually via
+    // simpletest.module ('batch') and via the testing framework ('').
+    _current_path(\Drupal::config('system.site')->get('page.front'));
+
     // Verify that a list of links is properly rendered.
     $variables = array();
     $variables['attributes'] = array('id' => 'somelinks');
@@ -188,7 +191,7 @@ function testLinks() {
     $expected_links .= '<ul id="somelinks">';
     $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '">' . check_plain('A <link>') . '</a></li>';
     $expected_links .= '<li class="plain-text even">' . check_plain('Plain "text"') . '</li>';
-    $expected_links .= '<li class="front-page odd"><a href="' . url('<front>') . '">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
     $expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
     $expected_links .= '</ul>';
 
@@ -221,24 +224,11 @@ function testLinks() {
     $expected_links .= '<ul id="somelinks">';
     $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '" class="a/class">' . check_plain('A <link>') . '</a></li>';
     $expected_links .= '<li class="plain-text even"><span class="a/class">' . check_plain('Plain "text"') . '</span></li>';
-    $expected_links .= '<li class="front-page odd"><a href="' . url('<front>') . '">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
     $expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
     $expected_links .= '</ul>';
     $expected = $expected_heading . $expected_links;
     $this->assertThemeOutput('links', $variables, $expected);
-
-    // Verify the data- attributes for setting the "active" class on links.
-    $this->container->set('current_user', new UserSession(array('uid' => 1)));
-    $variables['set_active_class'] = TRUE;
-    $expected_links = '';
-    $expected_links .= '<ul id="somelinks">';
-    $expected_links .= '<li class="a-link odd first" data-drupal-link-system-path="a/link"><a href="' . url('a/link') . '" class="a/class">' . check_plain('A <link>') . '</a></li>';
-    $expected_links .= '<li class="plain-text even"><span class="a/class">' . check_plain('Plain "text"') . '</span></li>';
-    $expected_links .= '<li class="front-page odd" data-drupal-link-system-path="&lt;front&gt;"><a href="' . url('<front>') . '">' . check_plain('Front page') . '</a></li>';
-    $expected_links .= '<li class="router-test even last" data-drupal-link-system-path="router_test/test1"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
-    $expected_links .= '</ul>';
-    $expected = $expected_heading . $expected_links;
-    $this->assertThemeOutput('links', $variables, $expected);
   }
 
   /**
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 34d8dde..14153a0 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -565,11 +565,6 @@ function system_install() {
   // Populate the cron key state variable.
   $cron_key = Crypt::randomStringHashed(55);
   \Drupal::state()->set('system.cron_key', $cron_key);
-
-  // Populate the site UUID.
-  \Drupal::config('system.site')
-    ->set('uuid', \Drupal::service('uuid')->generate())
-    ->save();
 }
 
 /**
diff --git a/core/modules/system/system.local_tasks.yml b/core/modules/system/system.local_tasks.yml
index 4d597ee..dedbf26 100644
--- a/core/modules/system/system.local_tasks.yml
+++ b/core/modules/system/system.local_tasks.yml
@@ -1,3 +1,8 @@
+system.performance_settings_tab:
+  route_name: system.performance_settings
+  title: Settings
+  base_route: system.performance_settings_tab
+
 system.rss_feeds_settings_tab:
   route_name: system.rss_feeds_settings
   title: Settings
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index f9ae056..ad5f7f3 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -877,19 +877,6 @@ function system_library_info() {
     ),
   );
 
-  // Drupal's active link marking.
-  $libraries['drupal.active-link'] = array(
-    'title' => 'Drupal active link marking',
-    'version' => \Drupal::VERSION,
-    'js' => array(
-      'core/misc/active-link.js' => array(),
-    ),
-    'dependencies' => array(
-      array('system', 'drupal'),
-      array('system', 'drupalSettings'),
-    ),
-  );
-
   // Drupal's Ajax framework.
   $libraries['drupal.ajax'] = array(
     'title' => 'Drupal AJAX',
@@ -1756,7 +1743,7 @@ function system_library_info() {
   $libraries['underscore'] = array(
     'title' => 'Underscore.js',
     'website' => 'http://underscorejs.org/',
-    'version' => '1.5.2',
+    'version' => '1.4.0',
     'js' => array(
       'core/assets/vendor/underscore/underscore.js' => array('group' => JS_LIBRARY, 'weight' => -20),
     ),
@@ -1766,7 +1753,7 @@ function system_library_info() {
   $libraries['backbone'] = array(
     'title' => 'Backbone.js',
     'website' => 'http://backbonejs.org/',
-    'version' => '1.1.0',
+    'version' => '0.9.2',
     'js' => array(
       'core/assets/vendor/backbone/backbone.js' => array('group' => JS_LIBRARY, 'weight' => -19),
     ),
@@ -2102,7 +2089,6 @@ function system_filetransfer_info() {
  * Implements hook_page_build().
  *
  * @see template_preprocess_maintenance_page()
- * @see \Drupal\system\Controller\SystemController::setLinkActiveClass()
  */
 function system_page_build(&$page) {
   // Ensure the same CSS is loaded in template_preprocess_maintenance_page().
@@ -2122,28 +2108,6 @@ function system_page_build(&$page) {
       'weight' => CSS_COMPONENT - 10,
     );
   }
-
-  // Handle setting the "active" class on links by:
-  // - loading the active-link library if the current user is authenticated;
-  // - applying a post-render cache callback if the current user is anonymous.
-  // @see l()
-  // @see \Drupal\Core\Utility\LinkGenerator::generate()
-  // @see theme_links()
-  // @see \Drupal\system\Controller\SystemController::setLinkActiveClass
-  if (\Drupal::currentUser()->isAuthenticated()) {
-    $page['#attached']['library'][] = array('system', 'drupal.active-link');
-  }
-  else {
-    $page['#post_render_cache']['\Drupal\system\Controller\SystemController::setLinkActiveClass'] = array(
-      // Collect the current state that determines whether a link is active.
-      array(
-        'path' => current_path(),
-        'front' => drupal_is_front_page(),
-        'language' => language(\Drupal\Core\Language\Language::TYPE_URL)->id,
-        'query' => \Drupal::service('request')->query->all(),
-      )
-    );
-  }
 }
 
 /**
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index 4d27aa6..4d56d47 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -187,7 +187,7 @@ system.image_toolkit_settings:
     _form: 'Drupal\system\Form\ImageToolkitForm'
     _title: 'Image toolkit'
   requirements:
-    _permission: 'access administration pages'
+    _permission: 'administer administration pages'
 
 system.site_maintenance_mode:
   path: '/admin/config/development/maintenance'
@@ -272,7 +272,7 @@ system.theme_enable:
 system.status:
   path: '/admin/reports/status'
   defaults:
-    _content: 'Drupal\system\Controller\SystemInfoController::status'
+    _controller: 'Drupal\system\Controller\SystemInfoController::status'
     _title: 'Status report'
   requirements:
     _permission: 'administer site configuration'
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
index ca1ea6f..6d9a9a6 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
+++ b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
@@ -94,7 +94,7 @@ function _batch_test_finished_helper($batch_id, $success, $results, $operations)
     $messages[] = t('An error occurred while processing @op with arguments:<br />@args', array('@op' => $error_operation[0], '@args' => print_r($error_operation[1], TRUE)));
   }
 
-  drupal_set_message(implode('<br>', $messages));
+  drupal_set_message(implode('<br />', $messages));
 }
 
 /**
diff --git a/core/modules/system/tests/modules/common_test/lib/Drupal/common_test/Controller/CommonTestController.php b/core/modules/system/tests/modules/common_test/lib/Drupal/common_test/Controller/CommonTestController.php
index ffce7dc..12d287f 100644
--- a/core/modules/system/tests/modules/common_test/lib/Drupal/common_test/Controller/CommonTestController.php
+++ b/core/modules/system/tests/modules/common_test/lib/Drupal/common_test/Controller/CommonTestController.php
@@ -35,9 +35,6 @@ public function typeLinkActiveClass() {
         '#type' => 'link',
         '#title' => t('Link with no query string'),
         '#href' => current_path(),
-        '#options' => array(
-          'set_active_class' => TRUE,
-        ),
       ),
       'with_query' => array(
         '#type' => 'link',
@@ -48,7 +45,6 @@ public function typeLinkActiveClass() {
             'foo' => 'bar',
             'one' => 'two',
           ),
-          'set_active_class' => TRUE,
         ),
       ),
       'with_query_reversed' => array(
@@ -60,7 +56,6 @@ public function typeLinkActiveClass() {
             'one' => 'two',
             'foo' => 'bar',
           ),
-          'set_active_class' => TRUE,
         ),
       ),
     );
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 4547ea7..d552d1d 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -382,11 +382,13 @@ function entity_test_entity_test_insert($entity) {
  *
  * @param $entity
  *   The entity object.
+ * @param $langcocde
+ *   (optional) The langcode.
  *
  * @return
  *   The label of the entity prefixed with "label callback".
  */
-function entity_test_label_callback($entity) {
+function entity_test_label_callback($entity, $langcode = NULL) {
   return 'label callback ' . $entity->name->value;
 }
 
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
index 9798c4f..1193cd5 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
@@ -107,7 +107,7 @@ public static function preCreate(EntityStorageControllerInterface $storage_contr
   /**
    * Overrides Drupal\entity\Entity::label().
    */
-  public function label() {
+  public function label($langcode = NULL) {
     $info = $this->entityInfo();
     if (!isset($langcode)) {
       $langcode = $this->activeLangcode;
diff --git a/core/modules/system/tests/modules/image_test/config/system.image.test_toolkit.yml b/core/modules/system/tests/modules/image_test/config/system.image.test_toolkit.yml
deleted file mode 100644
index 42a38c4..0000000
--- a/core/modules/system/tests/modules/image_test/config/system.image.test_toolkit.yml
+++ /dev/null
@@ -1 +0,0 @@
-test_parameter: 10
diff --git a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
index 5d62a82..15040a8 100644
--- a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
@@ -7,8 +7,9 @@
 
 namespace Drupal\image_test\Plugin\ImageToolkit;
 
+use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Image\ImageInterface;
-use Drupal\Core\ImageToolkit\ImageToolkitBase;
+use Drupal\Core\ImageToolkit\ImageToolkitInterface;
 
 /**
  * Defines a Test toolkit for image manipulation within Drupal.
@@ -18,32 +19,20 @@
  *   title = @Translation("A dummy toolkit that works")
  * )
  */
-class TestToolkit extends ImageToolkitBase {
+class TestToolkit extends PluginBase implements ImageToolkitInterface {
 
   /**
    * {@inheritdoc}
    */
   public function settingsForm() {
     $this->logCall('settings', array());
-    $form['test_parameter'] = array(
-      '#type' => 'number',
-      '#title' => $this->t('Test toolkit parameter'),
-      '#description' => $this->t('A toolkit parameter for testing purposes.'),
-      '#min' => 0,
-      '#max' => 100,
-      '#default_value' => \Drupal::config('system.image.test_toolkit')->get('test_parameter'),
-    );
-    return $form;
+    return array();
   }
 
   /**
    * {@inheritdoc}
    */
-  public function settingsFormSubmit($form, &$form_state) {
-    \Drupal::config('system.image.test_toolkit')
-      ->set('test_parameter', $form_state['values']['test']['test_parameter'])
-      ->save();
-  }
+  public function settingsFormSubmit($form, &$form_state) {}
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.module b/core/modules/system/tests/modules/test_page_test/test_page_test.module
index 7933a85..5911afb 100644
--- a/core/modules/system/tests/modules/test_page_test/test_page_test.module
+++ b/core/modules/system/tests/modules/test_page_test/test_page_test.module
@@ -18,13 +18,9 @@ function test_page_test_menu() {
  * @deprecated Use \Drupal\test_page_test\Controller\TestPageTestController::testPage()
  */
 function test_page_test_page() {
-  $attached['js'][] = array(
-    'data' => array('test-setting' => 'azAZ09();.,\\\/-_{}'),
-    'type' => 'setting',
-  );
+  drupal_add_js(array('test-setting' => 'azAZ09();.,\\\/-_{}'), array('type' => 'setting'));
   return array(
     '#title' => t('Test page'),
     '#markup' => t('Test page text.'),
-    '#attached' => $attached,
   );
 }
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index e41b467..978ac62 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -400,6 +400,12 @@ function template_preprocess_taxonomy_term(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 
+  // field_attach_preprocess() overwrites the $[field_name] variables with the
+  // values of the field in the language that was selected for display, instead
+  // of the raw values in $term->[field_name], which contain all values in all
+  // languages.
+  field_attach_preprocess($term, $variables['content'], $variables);
+
   // Gather classes, and clean up name so there are no underscores.
   $variables['attributes']['class'][] = 'taxonomy-term';
   $vocabulary_name_css = str_replace('_', '-', $term->bundle());
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index fa7dffa..955ef59 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -257,8 +257,8 @@ Drupal.toolbar = {
     initialize: function (options) {
       this.strings = options.strings;
 
-      this.listenTo(this.model, 'change:orientation', this.onOrientationChange);
-      this.listenTo(this.model, 'change:activeTray', this.onActiveTrayChange);
+      this.model.on('change:orientation', this.onOrientationChange, this);
+      this.model.on('change:activeTray', this.onActiveTrayChange, this);
     },
 
     /**
@@ -311,9 +311,9 @@ Drupal.toolbar = {
     initialize: function (options) {
       this.strings = options.strings;
 
-      this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render);
-      this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange);
-      this.listenTo(this.model, 'change:offsets', this.adjustPlacement);
+      this.model.on('change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render, this);
+      this.model.on('change:mqMatches', this.onMediaQueryChange, this);
+      this.model.on('change:offsets', this.adjustPlacement, this);
 
       // Add the tray orientation toggles.
       this.$el
@@ -576,7 +576,7 @@ Drupal.toolbar = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change:subtrees', this.render);
+      this.model.on('change:subtrees', this.render, this);
     },
 
     /**
@@ -611,7 +611,7 @@ Drupal.toolbar = {
      * {@inheritdoc}
      */
     initialize: function () {
-      this.listenTo(this.model, 'change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render);
+      this.model.on('change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render, this);
     },
 
     /**
diff --git a/core/modules/tour/js/tour.js b/core/modules/tour/js/tour.js
index 0f7a8fd..0438cdd 100644
--- a/core/modules/tour/js/tour.js
+++ b/core/modules/tour/js/tour.js
@@ -74,8 +74,8 @@ Drupal.tour.views.ToggleTourView = Backbone.View.extend({
    * Implements Backbone Views' initialize().
    */
   initialize: function () {
-    this.listenTo(this.model, 'change:tour change:isActive', this.render);
-    this.listenTo(this.model, 'change:isActive', this.toggleTour);
+    this.model.on('change:tour change:isActive', this.render, this);
+    this.model.on('change:isActive', this.toggleTour, this);
   },
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php
index 2954df5..35af76a 100644
--- a/core/modules/user/lib/Drupal/user/Entity/User.php
+++ b/core/modules/user/lib/Drupal/user/Entity/User.php
@@ -445,8 +445,6 @@ public static function baseFieldDefinitions($entity_type) {
       ->setLabel(t('Preferred language code'))
       ->setDescription(t("The user's preferred language code for viewing administration pages."));
 
-    // The name should not vary per language. The username is the visual
-    // identifier for a user and needs to be consistent in all languages.
     $fields['name'] = FieldDefinition::create('string')
       ->setLabel(t('Name'))
       ->setDescription(t('The name of this user.'))
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index f6a30cb..b5604a1 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1750,6 +1750,29 @@ function user_form_process_password_confirm($element) {
 }
 
 /**
+ * Implements hook_node_load().
+ *
+ * @todo Deprecated by $node->author, attached in
+ *   \Drupal\node\NodeViewBuilder::buildContent(). Update code that
+ *   depends on these properties.
+ */
+function user_node_load($nodes) {
+  // Build an array of all uids for node authors, keyed by nid.
+  $uids = array();
+  foreach ($nodes as $nid => $node) {
+    $uids[$nid] = $node->getAuthorId();
+  }
+
+  // Fetch name and data for these users.
+  $user_names = db_query("SELECT uid, name FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllKeyed();
+
+  // Add these values back into the node objects.
+  foreach ($uids as $nid => $uid) {
+    $nodes[$nid]->name = $user_names[$uid];
+  }
+}
+
+/**
  * Implements hook_modules_installed().
  */
 function user_modules_installed($modules) {
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index f9b5a91..2977253 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -113,6 +113,9 @@ function template_preprocess_user(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 
+  // Preprocess fields.
+  field_attach_preprocess($account, $variables['elements'], $variables);
+
   // Set up attributes.
   $variables['attributes']['class'][] = 'profile';
 }
diff --git a/core/modules/views/lib/Drupal/views/Entity/View.php b/core/modules/views/lib/Drupal/views/Entity/View.php
index f96fbd0..b91b6bd 100644
--- a/core/modules/views/lib/Drupal/views/Entity/View.php
+++ b/core/modules/views/lib/Drupal/views/Entity/View.php
@@ -147,7 +147,7 @@ public function createDuplicate() {
    *
    * When a certain view doesn't have a label return the ID.
    */
-  public function label() {
+  public function label($langcode = NULL) {
     if (!$label = $this->get('label')) {
       $label = $this->id();
     }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
index ddcc1fa..7915204 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\views\Plugin\views\display;
 
-use Drupal\Component\Utility\String;
 use Drupal\views\ViewExecutable;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -87,17 +86,11 @@ public function execute() {
    * Overrides \Drupal\views\Plugin\views\display\PathPluginBase::preview().
    */
   public function preview() {
-    $output = $this->view->render();
-
     if (!empty($this->view->live_preview)) {
-      $output = array(
-        '#prefix' => '<pre>',
-        '#markup' => String::checkPlain($output),
-        '#suffix' => '</pre>',
-      );
+      return '<pre>' . check_plain($this->view->render()) . '</pre>';
     }
 
-    return $output;
+    return $this->view->render();
   }
 
   /**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
index 662282d..424ac86 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
@@ -1374,13 +1374,6 @@ function execute(ViewExecutable $view) {
         $query->addTag($access_tag);
         $count_query->addTag($access_tag);
       }
-
-      if (isset($base_table_data['table']['base']['query metadata'])) {
-        foreach ($base_table_data['table']['base']['query metadata'] as $key => $value) {
-          $query->addMetaData($key, $value);
-          $count_query->addMetaData($key, $value);
-        }
-      }
     }
 
     if ($query) {
diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/SqlQueryTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/SqlQueryTest.php
deleted file mode 100644
index 3284733..0000000
--- a/core/modules/views/lib/Drupal/views/Tests/Plugin/SqlQueryTest.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views\Tests\Plugin\SqlQueryTest.
- */
-
-namespace Drupal\views\Tests\Plugin;
-
-use Drupal\views\Tests\ViewUnitTestBase;
-use Drupal\views\Views;
-
-/**
- * Tests the sql query plugin.
- *
- * @see \Drupal\views\Plugin\views\query\Sql
- */
-class SqlQueryTest extends ViewUnitTestBase {
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = array('test_view');
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Sql query',
-      'description' => 'Tests the sql query plugin',
-      'group' => 'Views Plugins'
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function viewsData() {
-    $data = parent::viewsData();
-    $data['views_test_data']['table']['base']['access query tag'] = 'test_tag';
-    $data['views_test_data']['table']['base']['query metadata'] = array('key1' => 'test_metadata', 'key2' => 'test_metadata2');
-
-    return $data;
-  }
-
-  /**
-   * Tests adding some metadata/tags to the views query.
-   */
-  public function testExecuteMetadata() {
-    $view = Views::getView('test_view');
-    $view->setDisplay();
-
-    $view->initQuery();
-    $view->execute();
-    /** @var \Drupal\Core\Database\Query\Select $query */
-    $main_query = $view->build_info['query'];
-    /** @var \Drupal\Core\Database\Query\Select $count_query */
-    $count_query = $view->build_info['count_query'];
-
-    foreach (array($main_query, $count_query) as $query) {
-      // Check query access tags.
-      $this->assertTrue($query->hasTag('test_tag'));
-
-      // Check metadata.
-      $this->assertIdentical($query->getMetaData('key1'), 'test_metadata');
-      $this->assertIdentical($query->getMetaData('key2'), 'test_metadata2');
-    }
-
-    $query_options = $view->display_handler->getOption('query');
-    $query_options['options']['disable_sql_rewrite'] = TRUE;
-    $view->display_handler->setOption('query', $query_options);
-    $view->save();
-    $view->destroy();
-
-    $view = Views::getView('test_view');
-    $view->setDisplay();
-    $view->initQuery();
-    $view->execute();
-    /** @var \Drupal\Core\Database\Query\Select $query */
-    $main_query = $view->build_info['query'];
-    /** @var \Drupal\Core\Database\Query\Select $count_query */
-    $count_query = $view->build_info['count_query'];
-
-    foreach (array($main_query, $count_query) as $query) {
-      // Check query access tags.
-      $this->assertFalse($query->hasTag('test_tag'));
-
-      // Check metadata.
-      $this->assertIdentical($query->getMetaData('key1'), NULL);
-      $this->assertIdentical($query->getMetaData('key2'), NULL);
-    }
-  }
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
index 77cc434..7f13413 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
@@ -77,21 +77,6 @@ function testPreviewUI() {
     $this->assertText('Test header text', 'Rendered header text found');
     $this->assertText('Test footer text', 'Rendered footer text found.');
     $this->assertText('Test empty text', 'Rendered empty text found.');
-
-    // Test feed preview.
-    $view = array();
-    $view['label'] = $this->randomName(16);
-    $view['id'] = strtolower($this->randomName(16));
-    $view['page[create]'] = 1;
-    $view['page[title]'] = $this->randomName(16);
-    $view['page[path]'] = $this->randomName(16);
-    $view['page[feed]'] = 1;
-    $view['page[feed_properties][path]'] = $this->randomName(16);
-    $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
-    $this->clickLink(t('Feed'));
-    $this->drupalPostForm(NULL, array(), t('Update preview'));
-    $result = $this->xpath('//div[@id="views-live-preview"]/pre');
-    $this->assertTrue(strpos($result[0], '<title>' . $view['page[title]'] . '</title>'), 'The Feed RSS preview was rendered.');
   }
 
   /**
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
index ea6448c..ed94fc7 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -897,8 +897,8 @@ public function uri() {
   /**
    * Implements \Drupal\Core\Entity\EntityInterface::label().
    */
-  public function label() {
-    return $this->storage->label();
+  public function label($langcode = NULL) {
+    return $this->storage->label($langcode);
   }
 
   /**
diff --git a/core/profiles/testing/config/locale.settings.yml b/core/profiles/testing/config/locale.settings.yml
deleted file mode 100644
index f1842a0..0000000
--- a/core/profiles/testing/config/locale.settings.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-cache_strings: true
-javascript:
-  directory: languages
-translation:
-  use_source: remote_and_local
-  default_filename: '%project-%version.%language.po'
-  default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'
-  overwrite_customized: false
-  overwrite_not_customized: true
-  update_interval_days: 0
-  path: ''
-  import_enabled: false
diff --git a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
index ee0d602..9bde39f 100644
--- a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php
@@ -73,21 +73,6 @@ public function testHmacBase64($data, $key, $expected_hmac) {
   }
 
   /**
-   * Tests the hmacBase64 method with invalid parameters.
-   *
-   * @param string $data
-   *   Data to hash.
-   * @param string $key
-   *   Key to use in hashing process.
-   *
-   * @dataProvider providerTestHmacBase64Invalid
-   * @expectedException InvalidArgumentException
-   */
-  public function testHmacBase64Invalid($data, $key) {
-    Crypt::hmacBase64($data, $key);
-  }
-
-  /**
    * Provides data for self::testHashBase64().
    *
    * @return array Test data.
@@ -120,39 +105,4 @@ public function providerTestHmacBase64() {
     );
   }
 
-  /**
-   * Provides data for self::testHmacBase64().
-   *
-   * @return array Test data.
-   */
-  public function providerTestHmacBase64Invalid() {
-    return array(
-      array(new \stdClass(), new \stdClass()),
-      array(new \stdClass(), 'string'),
-      array(new \stdClass(), 1),
-      array(new \stdClass(), 0),
-      array(NULL, new \stdClass()),
-      array('string', new \stdClass()),
-      array(1, new \stdClass()),
-      array(0, new \stdClass()),
-      array(array(), array()),
-      array(array(), NULL),
-      array(array(), 'string'),
-      array(array(), 1),
-      array(array(), 0),
-      array(NULL, array()),
-      array(1, array()),
-      array(0, array()),
-      array('string', array()),
-      array(array(), NULL),
-      array(NULL, NULL),
-      array(NULL, 'string'),
-      array(NULL, 1),
-      array(NULL, 0),
-      array(1, NULL),
-      array(0, NULL),
-      array('string', NULL),
-    );
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
index 3a6d75c..0db8f21 100644
--- a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
@@ -97,58 +97,33 @@ public function testValidate() {
    *   The token to be validated.
    * @param mixed $value
    *   (optional) An additional value to base the token on.
+   * @param mixed $expected
+   *   (optional) The expected result of validate(). Defaults to FALSE.
    *
    * @dataProvider providerTestValidateParameterTypes
    */
-  public function testValidateParameterTypes($token, $value) {
+  public function testValidateParameterTypes($token, $value = '', $expected = FALSE) {
     // The following check might throw PHP fatals and notices, so we disable
     // error assertions.
     set_error_handler(function () {return TRUE;});
-    $this->assertFalse($this->generator->validate($token, $value));
+    $this->assertSame($expected, $this->generator->validate($token, $value));
     restore_error_handler();
   }
 
   /**
-   * Provides data for testValidateParameterTypes.
+   * Provides data for the validate test.
    *
    * @return array
    *   An array of data used by the test.
    */
   public function providerTestValidateParameterTypes() {
     return array(
-      array(array(), ''),
-      array(TRUE, 'foo'),
-      array(0, 'foo'),
-    );
-  }
-
-  /**
-   * Tests CsrfTokenGenerator::validate() with invalid parameter types.
-   *
-   * @param mixed $token
-   *   The token to be validated.
-   * @param mixed $value
-   *   (optional) An additional value to base the token on.
-   *
-   * @dataProvider providerTestInvalidParameterTypes
-   * @expectedException InvalidArgumentException
-   */
-  public function testInvalidParameterTypes($token, $value = '') {
-    $this->generator->validate($token, $value);
-  }
-
-  /**
-   * Provides data for testInvalidParameterTypes.
-   *
-   * @return array
-   *   An array of data used by the test.
-   */
-  public function providerTestInvalidParameterTypes() {
-    return array(
       array(NULL, new \stdClass()),
       array(0, array()),
       array('', array()),
-      array(array(), array()),
+      array(array()),
+      array(TRUE, 'foo'),
+      array(0, 'foo'),
     );
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
index 708ab21..20550f5 100644
--- a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
@@ -268,7 +268,6 @@ public function testRebuildThemeData() {
     // Ensure that the css paths are set with the proper prefix.
     $this->assertEquals(array(
       'screen' => array(
-        'seven.base.css' => DRUPAL_ROOT . '/core/themes/seven/seven.base.css',
         'style.css' => DRUPAL_ROOT . '/core/themes/seven/style.css',
         'css/components/buttons.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/buttons.css',
         'css/components/buttons.theme.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/buttons.theme.css',
diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
index eec43a6..6b7334f 100644
--- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
@@ -43,6 +43,7 @@ class LinkGeneratorTest extends UnitTestCase {
   protected $moduleHandler;
 
   /**
+   *
    * The mocked language manager.
    *
    * @var \PHPUnit_Framework_MockObject_MockObject
@@ -50,20 +51,12 @@ class LinkGeneratorTest extends UnitTestCase {
   protected $languageManager;
 
   /**
-   * The mocked path alias manager.
-   *
-   * @var \Drupal\Core\Path\AliasManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $aliasManager;
-
-  /**
    * Contains the LinkGenerator default options.
    */
   protected $defaultOptions = array(
     'query' => array(),
     'html' => FALSE,
     'language' => NULL,
-    'set_active_class' => FALSE,
   );
 
   /**
@@ -87,9 +80,8 @@ protected function setUp() {
     $this->urlGenerator = $this->getMock('\Drupal\Core\Routing\UrlGenerator', array(), array(), '', FALSE);
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManager');
-    $this->aliasManager = $this->getMock('\Drupal\Core\Path\AliasManagerInterface');
 
-    $this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler, $this->languageManager, $this->aliasManager);
+    $this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler, $this->languageManager);
   }
 
   /**
@@ -320,31 +312,19 @@ public function testGenerateWithHtml() {
    *   service.
    */
   public function testGenerateActive() {
-    $this->urlGenerator->expects($this->exactly(8))
+    $this->urlGenerator->expects($this->exactly(7))
       ->method('generateFromRoute')
       ->will($this->returnValueMap(array(
         array('test_route_1', array(), FALSE, '/test-route-1'),
+        array('test_route_1', array(), FALSE, '/test-route-1'),
+        array('test_route_1', array(), FALSE, '/test-route-1'),
+        array('test_route_1', array(), FALSE, '/test-route-1'),
+        array('test_route_3', array(), FALSE, '/test-route-3'),
         array('test_route_3', array(), FALSE, '/test-route-3'),
         array('test_route_4', array('object' => '1'), FALSE, '/test-route-4/1'),
       )));
 
-    $this->urlGenerator->expects($this->exactly(7))
-      ->method('getPathFromRoute')
-      ->will($this->returnValueMap(array(
-        array('test_route_1', array(), 'test-route-1'),
-        array('test_route_3', array(), 'test-route-3'),
-        array('test_route_4', array('object' => '1'), 'test-route-4/1'),
-      )));
-
-    $this->aliasManager->expects($this->exactly(7))
-      ->method('getSystemPath')
-      ->will($this->returnValueMap(array(
-        array('test-route-1', NULL, 'test-route-1'),
-        array('test-route-3', NULL, 'test-route-3'),
-        array('test-route-4/1', NULL, 'test-route-4/1'),
-      )));
-
-    $this->moduleHandler->expects($this->exactly(8))
+    $this->moduleHandler->expects($this->exactly(7))
       ->method('alter');
 
     $this->setUpLanguageManager();
@@ -352,10 +332,10 @@ public function testGenerateActive() {
     // Render a link with a path different from the current path.
     $request = new Request(array(), array(), array('system_path' => 'test-route-2'));
     $this->linkGenerator->setRequest($request);
-    $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE));
-    $this->assertTag(array(
+    $result = $this->linkGenerator->generate('Test', 'test_route_1');
+    $this->assertNotTag(array(
       'tag' => 'a',
-      'attributes' => array('data-drupal-link-system-path' => 'test-route-1'),
+      'attributes' => array('class' => 'active'),
     ), $result);
 
     // Render a link with the same path as the current path.
@@ -365,31 +345,17 @@ public function testGenerateActive() {
     $raw_variables = new ParameterBag();
     $request->attributes->set('_raw_variables', $raw_variables);
     $this->linkGenerator->setRequest($request);
-    $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE));
+    $result = $this->linkGenerator->generate('Test', 'test_route_1');
     $this->assertTag(array(
       'tag' => 'a',
-      'attributes' => array('data-drupal-link-system-path' => 'test-route-1'),
-    ), $result);
-
-    // Render a link with the same path as the current path, but with the
-    // set_active_class option disabled.
-    $request = new Request(array(), array(), array('system_path' => 'test-route-1', RouteObjectInterface::ROUTE_NAME => 'test_route_1'));
-    // This attribute is expected to be set in a Drupal request by
-    // \Drupal\Core\ParamConverter\ParamConverterManager
-    $raw_variables = new ParameterBag();
-    $request->attributes->set('_raw_variables', $raw_variables);
-    $this->linkGenerator->setRequest($request);
-    $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => FALSE));
-    $this->assertNotTag(array(
-      'tag' => 'a',
-      'attributes' => array('data-drupal-link-system-path' => 'test-route-1'),
+      'attributes' => array('class' => 'active'),
     ), $result);
 
     // Render a link with the same path and language as the current path.
-    $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE));
+    $result = $this->linkGenerator->generate('Test', 'test_route_1');
     $this->assertTag(array(
       'tag' => 'a',
-      'attributes' => array('data-drupal-link-system-path' => 'test-route-1'),
+      'attributes' => array('class' => 'active'),
     ), $result);
 
     // Render a link with the same path but a different language than the current
@@ -398,17 +364,11 @@ public function testGenerateActive() {
       'Test',
       'test_route_1',
       array(),
-      array(
-        'language' => new Language(array('id' => 'de')),
-        'set_active_class' => TRUE,
-      )
+      array('language' => new Language(array('id' => 'de')))
     );
-    $this->assertTag(array(
+    $this->assertNotTag(array(
       'tag' => 'a',
-      'attributes' => array(
-        'data-drupal-link-system-path' => 'test-route-1',
-        'hreflang' => 'de',
-      ),
+      'attributes' => array('class' => 'active'),
     ), $result);
 
     // Render a link with the same path and query parameter as the current path.
@@ -420,17 +380,11 @@ public function testGenerateActive() {
       'Test',
       'test_route_3',
       array(),
-      array(
-        'query' => array('value' => 'example_1'),
-        'set_active_class' => TRUE,
-      )
-    );
+      array('query' => array('value' => 'example_1')
+    ));
     $this->assertTag(array(
       'tag' => 'a',
-      'attributes' => array(
-        'data-drupal-link-system-path' => 'test-route-3',
-        'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/',
-      ),
+      'attributes' => array('class' => 'active'),
     ), $result);
 
     // Render a link with the same path but a different query parameter than the
@@ -439,19 +393,12 @@ public function testGenerateActive() {
       'Test',
       'test_route_3',
       array(),
-      array(
-        'query' => array('value' => 'example_2'),
-        'set_active_class' => TRUE,
-      )
+      array('query' => array('value' => 'example_2'))
     );
-    $this->assertTag(array(
+    $this->assertNotTag(array(
       'tag' => 'a',
-      'attributes' => array(
-        'data-drupal-link-system-path' => 'test-route-3',
-        'data-drupal-link-query' => 'regexp:/.*value.*example_2.*/',
-      ),
+      'attributes' => array('class' => 'active'),
     ), $result);
-
     // Render a link with the same path and query parameter as the current path.
     $request = new Request(array('value' => 'example_1'), array(), array('system_path' => 'test-route-4/1', RouteObjectInterface::ROUTE_NAME => 'test_route_4'));
     $raw_variables = new ParameterBag(array('object' => '1'));
@@ -461,17 +408,11 @@ public function testGenerateActive() {
       'Test',
       'test_route_4',
       array('object' => '1'),
-      array(
-        'query' => array('value' => 'example_1'),
-        'set_active_class' => TRUE,
-      )
+      array('query' => array('value' => 'example_1'))
     );
     $this->assertTag(array(
       'tag' => 'a',
-      'attributes' => array(
-        'data-drupal-link-system-path' => 'test-route-4/1',
-        'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/',
-      ),
+      'attributes' => array('class' => 'active'),
     ), $result);
   }
 
diff --git a/core/themes/seven/seven.base.css b/core/themes/seven/seven.base.css
deleted file mode 100644
index b72bbce..0000000
--- a/core/themes/seven/seven.base.css
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Generic elements.
- */
-body {
-  color: #000;
-  background: #fff;
-  font: normal 81.3%/1.538em "Lucida Grande", "Lucida Sans Unicode", sans-serif;
-}
-a,
-.link {
-  color: #0074bd;
-  text-decoration: none;
-}
-a:hover,
-.link:hover {
-  text-decoration: underline;
-}
-hr {
-  margin: 0;
-  padding: 0;
-  border: none;
-  height: 1px;
-  background: #cccccc;
-}
-summary,
-legend {
-  font-weight: bold;
-  text-transform: uppercase;
-}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
-  font-weight: bold;
-  margin: 10px 0;
-}
-h1 {
-  font-size: 1.538em;
-}
-h2 {
-  font-size: 1.385em;
-}
-h3 {
-  font-size: 1.231em;
-}
-h4 {
-  font-size: 1.154em;
-}
-h5,
-h6 {
-  font-size: 1.077em;
-}
-p {
-  margin: 1em 0;
-}
-dl {
-  margin: 0 0 20px;
-}
-dl dd,
-dl dl {
-  margin-left: 20px; /* LTR */
-  margin-bottom: 10px;
-}
-[dir="rtl"] dl dd,
-[dir="rtl"] dl dl {
-  margin-right: 20px;
-}
-blockquote {
-  margin: 1em 40px;
-}
-address {
-  font-style: italic;
-}
-u,
-ins {
-  text-decoration: underline;
-}
-s,
-strike,
-del {
-  text-decoration: line-through;
-}
-big {
-  font-size: larger;
-}
-small {
-  font-size: smaller;
-}
-sub {
-  vertical-align: sub;
-  font-size: smaller;
-  line-height: normal;
-}
-sup {
-  vertical-align: super;
-  font-size: smaller;
-  line-height: normal;
-}
-nobr {
-  white-space: nowrap;
-}
-abbr,
-acronym {
-  border-bottom: dotted 1px;
-}
-ul {
-  list-style-type: disc;
-  list-style-image: none;
-  margin: 0.25em 0 0.25em 1.5em; /* LTR */
-}
-[dir="rtl"] ul {
-  margin: 0.25em 1.5em 0.25em 0;
-}
-ol {
-  list-style-type: decimal;
-  margin: 0.25em 0 0.25em 2em; /* LTR */
-}
-[dir="rtl"] ol {
-  margin: 0.25em 2em 0.25em 0;
-}
-quote,
-code {
-  margin: .5em 0;
-}
-code,
-pre,
-kbd {
-  font-size: 1.231em;
-}
-pre {
-  margin: 0.5em 0;
-  white-space: pre-wrap;
-}
diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml
index 582b498..62beff8 100644
--- a/core/themes/seven/seven.info.yml
+++ b/core/themes/seven/seven.info.yml
@@ -6,7 +6,6 @@ version: VERSION
 core: 8.x
 stylesheets:
   screen:
-    - seven.base.css
     - style.css
     - css/components/buttons.css
     - css/components/buttons.theme.css
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css
index 09645c8..11f9846 100644
--- a/core/themes/seven/style.css
+++ b/core/themes/seven/style.css
@@ -1,11 +1,117 @@
 /**
- * Menus and lists.
+ * Generic elements.
  */
+body {
+  color: #000;
+  background: #fff;
+  font: normal 81.3%/1.538em "Lucida Grande", "Lucida Sans Unicode", sans-serif;
+}
+a,
+.link {
+  color: #0074bd;
+  text-decoration: none;
+}
+a:hover,
+.link:hover {
+  text-decoration: underline;
+}
+hr {
+  margin: 0;
+  padding: 0;
+  border: none;
+  height: 1px;
+  background: #cccccc;
+}
+summary,
+legend {
+  font-weight: bold;
+  text-transform: uppercase;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-weight: bold;
+  margin: 10px 0;
+}
+h1 {
+  font-size: 1.538em;
+}
+h2 {
+  font-size: 1.385em;
+}
+h3 {
+  font-size: 1.231em;
+}
+h4 {
+  font-size: 1.154em;
+}
+h5,
+h6 {
+  font-size: 1.077em;
+}
+p {
+  margin: 1em 0;
+}
+dl {
+  margin: 0 0 20px;
+}
+dl dd,
+dl dl {
+  margin-left: 20px; /* LTR */
+  margin-bottom: 10px;
+}
+[dir="rtl"] dl dd,
+[dir="rtl"] dl dl {
+  margin-right: 20px;
+}
+blockquote {
+  margin: 1em 40px;
+}
+address {
+  font-style: italic;
+}
+u,
+ins {
+  text-decoration: underline;
+}
+s,
+strike,
+del {
+  text-decoration: line-through;
+}
+big {
+  font-size: larger;
+}
+small {
+  font-size: smaller;
+}
+sub {
+  vertical-align: sub;
+  font-size: smaller;
+  line-height: normal;
+}
+sup {
+  vertical-align: super;
+  font-size: smaller;
+  line-height: normal;
+}
+nobr {
+  white-space: nowrap;
+}
+abbr,
+acronym {
+  border-bottom: dotted 1px;
+}
+ul,
 .item-list ul {
   list-style-type: disc;
   list-style-image: none;
   margin: 0.25em 0 0.25em 1.5em; /* LTR */
 }
+[dir="rtl"] ul,
 [dir="rtl"] .item-list ul {
   margin: 0.25em 1.5em 0.25em 0;
 }
@@ -18,16 +124,37 @@ ul.menu li {
 ul.menu li {
   margin: 0;
 }
+ol {
+  list-style-type: decimal;
+  margin: 0.25em 0 0.25em 2em; /* LTR */
+}
+[dir="rtl"] ol {
+  margin: 0.25em 2em 0.25em 0;
+}
 .item-list ul li.collapsed,
 ul.menu li.collapsed {
-  list-style-image: url(../../misc/menu-collapsed.png);
-  list-style-type: disc;
+  list-style-image:url(../../misc/menu-collapsed.png);
+  list-style-type:disc;
 }
 .item-list ul li.expanded,
 ul.menu li.expanded {
-  list-style-image: url(../../misc/menu-expanded.png);
-  list-style-type: circle;
+  list-style-image:url(../../misc/menu-expanded.png);
+  list-style-type:circle;
+}
+quote,
+code {
+  margin: .5em 0;
 }
+code,
+pre,
+kbd {
+  font-size: 1.231em;
+}
+pre {
+  margin: 0.5em 0;
+  white-space: pre-wrap;
+}
+
 /**
  * Skip link.
  */
@@ -460,6 +587,8 @@ td {
 th > a {
   position: relative;
   display: block;
+  color: #0074bd;
+  text-decoration: none;
 }
 
 /* 1. Must match negative bottom padding of the parent <th> */
@@ -1588,3 +1717,4 @@ details.fieldset-no-legend {
 .page-admin-config-regional-language-detection .form-actions {
   margin-top: -2em;
 }
+
