diff --git a/core/includes/common.inc b/core/includes/common.inc
index d97ef30..4dfaf31 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2521,6 +2521,7 @@ function drupal_add_html_head_link($attributes, $header = FALSE) {
  * @return
  *   An array of queued cascading stylesheets.
  *
+ * @deprecated
  * @see drupal_get_css()
  */
 function drupal_add_css($data = NULL, $options = NULL) {
@@ -3738,6 +3739,7 @@ function drupal_add_js($data = NULL, $options = NULL) {
  *
  * @see drupal_get_js()
  * @see drupal_add_js()
+ * @deprecated
  */
 function drupal_js_defaults($data = NULL) {
   return array(
diff --git a/core/lib/Drupal/Core/Asset/AssetBag.php b/core/lib/Drupal/Core/Asset/AssetBag.php
new file mode 100644
index 0000000..61a6bb7
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetBag.php
@@ -0,0 +1,257 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetBag.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\AssetInterface;
+use Drupal\Core\Asset\AssetBagInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * The default AssetBag, used to declare assets needed for a response.
+ */
+class AssetBag implements AssetBagInterface {
+
+  /**
+   * The container to be used by this AssetBag when accessing services.
+   *
+   * @var \Symfony\Component\DependencyInjection\ContainerInterface
+   */
+  protected $container;
+
+  protected $assets;
+
+  protected $hasJs = FALSE;
+
+  protected $hasCss = FALSE;
+
+  protected $terminated = FALSE;
+
+  protected $sorted = array();
+
+  protected $needsSorting = FALSE;
+
+  /**
+   * An indexed array holding nested AssetBagInterface objects.
+   *
+   * @todo there's a better solution here using SplObjectStorage
+   *
+   * @var array
+   */
+  protected $bags;
+
+  /**
+   * Constructs an AssetBag object, initializing certain values.
+   *
+   * @return \Drupal\Core\Asset\AssetBag
+   */
+  public function __construct() {
+//    $this->javascript['settings'] = array(
+//      'type' => 'setting',
+//      'scope' => 'header',
+//      'group' => JS_SETTING,
+//      'every_page' => TRUE,
+//      'weight' => 0,
+//      'browsers' => array(),
+//    );
+    // @todo this stuff made sense in drupal_add_js(), but seems redundant to have in each AssetBag.
+    // url() generates the script and prefix using hook_url_outbound_alter().
+    // Instead of running the hook_url_outbound_alter() again here, extract
+    // them from url().
+    // @todo Make this less hacky: http://drupal.org/node/1547376.
+//    $scriptPath = $GLOBALS['script_path'];
+//    $pathPrefix = '';
+//    url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
+//    $this->javascript['settings']['data'][] = array(
+//      'basePath' => base_path(),
+//      'scriptPath' => $scriptPath,
+//      'pathPrefix' => $pathPrefix,
+//      'currentPath' => current_path(),
+//    );
+  }
+
+  public function add(AssetInterface $asset) {
+    if ($this->terminated) {
+      throw new \LogicException('Assets cannot be added to a terminated AssetBag.', E_ERROR);
+    }
+
+    $this->needsSorting = TRUE;
+
+    $this->assets[] = $asset;
+    if ($asset instanceof JavascriptAssetInterface) {
+      $this->hasJs = TRUE;
+    }
+    if ($asset instanceof StylesheetAssetInterface) {
+      $this->hasCss = TRUE;
+    }
+  }
+
+  /**
+   * Adds another AssetBag to this one.
+   *
+   * @param \Drupal\Core\Asset\AssetBagInterface $bag
+   * @param bool              $terminate
+   *   Whether or not the provided bag should be flagged as terminated.
+   *
+   * @return mixed|void
+   * @throws \LogicException
+   */
+  public function addAssetBag(AssetBagInterface $bag, $terminate = TRUE) {
+    if ($this->terminated) {
+      throw new \LogicException('Assets cannot be added to a terminated AssetBag.', E_ERROR);
+    }
+
+    foreach ($bag->all() as $asset) {
+      $this->add($asset);
+    }
+
+    if ($terminate) {
+      $bag->terminate();
+    }
+  }
+
+  /**
+   * Indicates whether this object contains any CSS assets.
+   *
+   * @return bool
+   */
+  public function hasCss() {
+    return $this->hasCss;
+  }
+
+  /**
+   * Returns the CSS assets in this bag, fully resolved into page order.
+   *
+   * @todo see if we can make this return an AssetCollection
+   *
+   * @return array
+   */
+  public function getCss() {
+    $this->sort();
+    return $this->sorted['css'];
+  }
+
+
+  /**
+   * Returns all CSS assets contained directly in the bag.
+   *
+   * Note that this will NOT include assets that have been brought in as part of
+   * dependency declarations.
+   *
+   * @return array
+   *   An array of CSS assets, ordered by the sequence in which they entered the
+   *   bag.
+   */
+  public function getUnsortedCss() {
+    $css = array();
+    foreach ($this->assets as $asset) {
+      if ($asset instanceof StylesheetAssetInterface) {
+        $css[] = $asset;
+      }
+    }
+
+    return $css;
+  }
+
+
+  /**
+   * Sorts all assets in this bag into their final rendering order.
+   */
+  protected function sort() {
+    if (!$this->needsSorting) {
+      return;
+    }
+
+    $this->sorted['js'] = $this->sorted['css'] = array();
+
+    $all = array();
+
+
+    $this->needsSorting = FALSE;
+  }
+
+
+  /**
+   * Returns all assets contained in this object.
+   *
+   * The assets are returned in the order in which they were added, which is
+   * unlikely to be the final correct rendering order.
+   *
+   * @return array
+   */
+  public function all() {
+    return $this->assets;
+  }
+
+
+  /**
+   * Adds configuration settings for eventual inclusion in drupalSettings.
+   *
+   * @todo decide how to handle these in a fully-classed asset system
+   *
+   * @param $data
+   *   An associative array containing configuration settings, to be eventually
+   *   merged into drupalSettings. Settings should be be wrapped in another
+   *   variable, typically by module name, in order to avoid conflicts in the
+   *   drupalSettings namespace. Items added with a string key will replace
+   *   existing settings with that key; items with numeric array keys will be
+   *   added to the existing settings array.
+   *
+   * @return AssetBagInterface $this
+   *   Returns the current AssetBagInterface object for method chaining.
+   */
+  public function addJsSetting($data) {
+    $this->javascript['settings']['data'][] = $data;
+  }
+
+  /**
+   * Indicates whether this AssetBagInterface contains any JavaScript assets.
+   *
+   * @return bool
+   */
+  public function hasJs() {
+    return $this->hasJs;
+  }
+
+  /**
+   * Returns the JavaScript assets in this bag, fully resolved into page order.
+   *
+   * @todo see if we can make this return an AssetCollection
+   *
+   * @return array
+   */
+  public function getJs() {
+    $this->sort();
+    return $this->sorted['js'];
+  }
+
+
+  /**
+   * Returns all JavaScript assets contained directly in the bag.
+   *
+   * Note that this will NOT include assets that have been brought in as part of
+   * dependency declarations.
+   *
+   * @return array
+   *   An array of JavaScript assets, ordered by the sequence in which they
+   *   entered the bag.
+   */
+  public function getUnsortedJs() {
+    $js = array();
+    foreach ($this->assets as $asset) {
+      if ($asset instanceof JavascriptAssetInterface) {
+        $js[] = $asset;
+      }
+    }
+
+    return $js;
+  }
+
+  public function terminate() {
+    $this->terminated = TRUE;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/AssetBagInterface.php b/core/lib/Drupal/Core/Asset/AssetBagInterface.php
new file mode 100644
index 0000000..8f0356d
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetBagInterface.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetBagInterface.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\AssetInterface;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+
+/**
+ * Defines a common interface for asset bags.
+ *
+ * Asset bags are a mechanism for internal Drupal code to list a set of assets
+ * and provide some metadata about their manner of use. During a normal page
+ * build, a number of these bags are likely to be built and ultimately merged
+ * onto the Response object.
+ *
+ * An AssetBagInterface object's contents are not expected to be in the final,
+ * ordered form in which will ultimately be delivered as part of the page
+ * response. Rather, a stack of such bags will be combined towards the end of
+ * the page request into the final asset list.
+ */
+interface AssetBagInterface {
+
+  public function add(AssetInterface $asset);
+
+  /**
+   * Adds another AssetBag to this one.
+   *
+   * @param AssetBagInterface $bag
+   *
+   * @return mixed
+   */
+  public function addAssetBag(AssetBagInterface $bag);
+
+  /**
+   * Adds configuration settings for eventual inclusion in Drupal.settings.
+   *
+   * @todo fix this up to use proper classes asset objects somehow
+   *
+   * @param $data
+   *   An associative array containing configuration settings, to be eventually
+   *   merged into drupalSettings. Settings should be be wrapped in another
+   *   variable, typically by module name, in order to avoid conflicts in the
+   *   Drupal.settings namespace. Items added with a string key will replace
+   *   existing settings with that key; items with numeric array keys will be
+   *   added to the existing settings array.
+   *
+   * @return AssetBagInterface $this
+   *   Returns the current AssetBagInterface object for method chaining.
+   */
+  public function addJsSetting($data);
+
+  /**
+   * Indicates whether this object contains any CSS assets.
+   *
+   * @return bool
+   */
+  public function hasCss();
+
+  /**
+   * Returns the CSS assets in this bag, fully resolved into page order.
+   *
+   * @todo see if we can make this return an AssetCollection
+   *
+   * @return array
+   */
+  public function getCss();
+
+  /**
+   * Returns all CSS assets contained directly in the bag.
+   *
+   * Note that this will NOT include assets that have been brought in as part of
+   * dependency declarations.
+   *
+   * @return array
+   *   An array of CSS assets, ordered by the sequence in which they entered the
+   *   bag.
+   */
+  public function getUnsortedCss();
+
+  /**
+   * Indicates whether this AssetBagInterface contains any JavaScript assets.
+   *
+   * @return bool
+   */
+  public function hasJs();
+
+  /**
+   * Returns the JavaScript assets in this bag, fully resolved into page order.
+   *
+   * @todo see if we can make this return an AssetCollection
+   *
+   * @return array
+   */
+  public function getJs();
+
+  /**
+   * Returns all JavaScript assets contained directly in the bag.
+   *
+   * Note that this will NOT include assets that have been brought in as part of
+   * dependency declarations.
+   *
+   * @return array
+   *   An array of JavaScript assets, ordered by the sequence in which they
+   *   entered the bag.
+   */
+  public function getUnsortedJs();
+
+  /**
+   * Returns all assets contained in this object.
+   *
+   * The assets are returned in the order in which they were added, which is
+   * unlikely to be the final correct rendering order.
+   *
+   * @return array
+   */
+  public function all();
+
+  /**
+   * Marks this bag as incapable of receiving new assets.
+   *
+   * @return void
+   */
+  public function terminate();
+}
diff --git a/core/lib/Drupal/Core/Asset/AssetInterface.php b/core/lib/Drupal/Core/Asset/AssetInterface.php
new file mode 100644
index 0000000..c8f2465
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetInterface.php
@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetInterface.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Asset\AssetInterface as AsseticAssetInterface;
+use Drupal\Core\Asset\AssetLibraryReference;
+
+/**
+ * Represents an asset.
+ *
+ * This interface extends the AssetInterface provided by Assetic to allow
+ * more sophisticated logic and behaviors to be attached to individual assets.
+ */
+interface AssetInterface extends AsseticAssetInterface {
+
+  /**
+   * Sets the flag indicating preprocessability.
+   *
+   * @param bool $preprocess
+   *
+   * @return AssetInterface
+   *
+   * @see AssetInterface::isPreprocessable()
+   */
+  public function setPreprocessable($preprocess = TRUE);
+
+  /**
+   * Indicates whether or not this asset is eligible for preprocessing.
+   *
+   * Assets that are marked as not preprocessable will always be passed directly
+   * through to the browser without aggregation. Assets that are marked as
+   * eligible for preprocessing will be included in any broader aggregation
+   * logic that has been configured.
+   *
+   * @return bool
+   */
+  public function isPreprocessable();
+
+  /**
+   * @todo can we do this with a filter?
+   */
+  public function setBrowsers();
+
+  public function getBrowsers();
+
+  /**
+   * Declares that the current asset must follow the provided asset.
+   *
+   * This method describes sequencing, not a dependency. That is, passing an
+   * asset to this method does NOT declare that it should be used on the page;
+   * only that it IF that asset is declared elsewhere for use on the page, THEN
+   * this asset should always follow it.
+   *
+   * However, declaring an explicit dependency will trigger this method
+   * internally, so there is no need for client code to call it directly.
+   *
+   * @param AssetInterface $asset
+   *   The asset which the current asset should follow when rendered onto the
+   *   page.
+   *
+   * @return void
+   * @throws \UnexpectedValueException
+   *   If the current asset is of a different type (e.g. CSS vs. Javascript), an
+   *   exception will be thrown.
+   */
+  public function after(AssetInterface $asset);
+
+  /**
+   * Indicates whether this asset has any sequencing requirements.
+   *
+   * Sequencing requirements are declared by calling AssetInterface::after().
+   *
+   * @return bool
+   */
+  public function hasSequencing();
+
+  /**
+   * Gets any assets that must precede this one in the rendering sequence.
+   *
+   * @return array
+   *   An array of AssetInterface objects that should precede this one.
+   */
+  public function getPreceders();
+
+  /**
+   * Declares a dependency on the provided asset library.
+   *
+   * @param AssetLibraryReference $reference
+   *
+   * @return void
+   */
+  public function addDependency(AssetLibraryReference $reference);
+
+  /**
+   * Indicates whether or not this asset has library dependencies.
+   *
+   * @return bool
+   */
+  public function hasDependencies();
+
+  /**
+   * Gets the library dependencies attached to this asset, if any.
+   *
+   * This method may trigger some compilation steps, so if you only need to know
+   * whether or not the asset has dependencies but not what they are, call
+   * AssetInterface::hasDependencies().
+   *
+   * @return array
+   */
+  public function getDependencies();
+}
diff --git a/core/lib/Drupal/Core/Asset/AssetLibrary.php b/core/lib/Drupal/Core/Asset/AssetLibrary.php
new file mode 100644
index 0000000..4b65ecf
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetLibrary.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetLibrary.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\AssetInterface as AsseticAssetInterface;
+use Drupal\Core\Asset\AssetInterface as DrupalAssetInterface;
+
+/**
+ * @todo not sure if AssetCollection will be a good baseline for this
+ */
+class AssetLibrary extends AssetCollection {
+
+  protected $title = '';
+
+  protected $version;
+
+  protected $website = '';
+
+  /**
+   * @todo really, what's the use case here?
+   *
+   * @param $title
+   */
+  public function setTitle($title) {
+    $this->title = $title;
+    return $this;
+  }
+
+  public function getTitle() {
+    return $this->title;
+  }
+
+  /**
+   * @todo omgwtfbbqsigh - do we really need this?
+   *
+   * @param $website
+   */
+  public function setWebsite($website) {
+    $this->website = $website;
+    return $this;
+  }
+
+  public function getWebsite() {
+    return $this->website;
+  }
+
+  public function setVersion($version) {
+    $this->version = $version;
+    return $this;
+  }
+
+  public function getVersion() {
+    return $this->version;
+  }
+
+  public function add(AsseticAssetInterface $asset) {
+    // @todo ugh.
+    if (!$asset instanceof DrupalAssetInterface) {
+      throw new \InvalidArgumentException('Drupal library assets must conform to Drupal\'s AssetInterface.');
+    }
+
+    return parent::add($asset);
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/AssetLibraryManager.php b/core/lib/Drupal/Core/Asset/AssetLibraryManager.php
new file mode 100644
index 0000000..b3ff5bb
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetLibraryManager.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetLibraryManager.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\AssetManager;
+
+class AssetLibraryManager extends AssetManager {
+  protected $libraries;
+}
diff --git a/core/lib/Drupal/Core/Asset/AssetLibraryReference.php b/core/lib/Drupal/Core/Asset/AssetLibraryReference.php
new file mode 100644
index 0000000..df48267
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/AssetLibraryReference.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\AssetLibraryReference.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Asset\AssetReference;
+use Drupal\Core\Asset\AssetLibraryManager;
+
+class AssetLibraryReference {
+
+  /**
+   * @var \Drupal\Core\Asset\AssetLibraryManager;
+   */
+  protected $manager;
+
+  public function __construct($name, AssetLibraryManager $manager = NULL) {
+    if (!$manager instanceof AssetLibraryManager) {
+      // If no manager was injected, fetch it via global container access
+      $this->manager = drupal_container()->get('asset_library_manager');
+    }
+  }
+
+  public function getAssets() {
+
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/BaseAsset.php b/core/lib/Drupal/Core/Asset/BaseAsset.php
new file mode 100644
index 0000000..97f8a80
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/BaseAsset.php
@@ -0,0 +1,278 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\BaseAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Filter\FilterCollection;
+use Assetic\Filter\FilterInterface;
+use Drupal\Core\Asset\AssetInterface;
+
+/**
+ * A base abstract asset.
+ *
+ * This is an amalgam of Assetic\Asset\BaseAsset (copied directly) with
+ * implementations of the additional methods specified by Drupal's own
+ * Drupal\Core\Asset\AssetInterface.
+ *
+ * The methods load() and getLastModified() are left undefined, although a
+ * reusable doLoad() method is available to child classes.
+ */
+abstract class BaseAsset implements AssetInterface {
+
+  protected $filters;
+
+  protected $sourceRoot;
+
+  protected $sourcePath;
+
+  protected $targetPath;
+
+  protected $content;
+
+  protected $loaded;
+
+  protected $vars;
+
+  protected $values;
+
+  protected $preprocess = TRUE;
+
+  /**
+   * Constructor.
+   *
+   * @param array $filters Filters for the asset
+   */
+  public function __construct($filters = array(), $sourceRoot = NULL, $sourcePath = NULL, array $vars = array()) {
+    $this->filters = new FilterCollection($filters);
+    $this->sourceRoot = $sourceRoot;
+    $this->sourcePath = $sourcePath;
+    $this->vars = $vars;
+    $this->values = array();
+    $this->loaded = FALSE;
+  }
+
+  public function __clone() {
+    $this->filters = clone $this->filters;
+  }
+
+  public function ensureFilter(FilterInterface $filter) {
+    $this->filters->ensure($filter);
+  }
+
+  public function getFilters() {
+    return $this->filters->all();
+  }
+
+  public function clearFilters() {
+    $this->filters->clear();
+  }
+
+  /**
+   * Encapsulates asset loading logic.
+   *
+   * @param string          $content          The asset content
+   * @param FilterInterface $additionalFilter An additional filter
+   */
+  protected function doLoad($content, FilterInterface $additionalFilter = NULL) {
+    $filter = clone $this->filters;
+    if ($additionalFilter) {
+      $filter->ensure($additionalFilter);
+    }
+
+    $asset = clone $this;
+    $asset->setContent($content);
+
+    $filter->filterLoad($asset);
+    $this->content = $asset->getContent();
+
+    $this->loaded = TRUE;
+  }
+
+  public function dump(FilterInterface $additionalFilter = NULL) {
+    if (!$this->loaded) {
+      $this->load();
+    }
+
+    $filter = clone $this->filters;
+    if ($additionalFilter) {
+      $filter->ensure($additionalFilter);
+    }
+
+    $asset = clone $this;
+    $filter->filterDump($asset);
+
+    return $asset->getContent();
+  }
+
+  public function getContent() {
+    return $this->content;
+  }
+
+  public function setContent($content) {
+    $this->content = $content;
+  }
+
+  public function getSourceRoot() {
+    return $this->sourceRoot;
+  }
+
+  public function getSourcePath() {
+    return $this->sourcePath;
+  }
+
+  public function getTargetPath() {
+    return $this->targetPath;
+  }
+
+  public function setTargetPath($targetPath) {
+    if ($this->vars) {
+      foreach ($this->vars as $var) {
+        if (FALSE === strpos($targetPath, $var)) {
+          throw new \RuntimeException(sprintf('The asset target path "%s" must contain the variable "{%s}".', $targetPath, $var));
+        }
+      }
+    }
+
+    $this->targetPath = $targetPath;
+  }
+
+  public function getVars() {
+    return $this->vars;
+  }
+
+  public function setValues(array $values) {
+    foreach ($values as $var => $v) {
+      if (!in_array($var, $this->vars, TRUE)) {
+        throw new \InvalidArgumentException(sprintf('The asset with source path "%s" has no variable named "%s".', $this->sourcePath, $var));
+      }
+    }
+
+    $this->values = $values;
+    $this->loaded = FALSE;
+  }
+
+  public function getValues() {
+    return $this->values;
+  }
+
+  /**
+   * Sets the flag indicating preprocessability.
+   *
+   * @param bool $preprocess
+   *
+   * @return AssetInterface
+   *
+   * @see AssetInterface::isPreprocessable()
+   */
+  public function setPreprocessable($preprocess = TRUE) {
+    $this->preprocess = $preprocess;
+  }
+
+  /**
+   * Indicates whether or not this asset is eligible for preprocessing.
+   *
+   * Assets that are marked as not preprocessable will always be passed directly
+   * through to the browser without aggregation. Assets that are marked as
+   * eligible for preprocessing will be included in any broader aggregation
+   * logic that has been configured.
+   *
+   * @return bool
+   */
+  public function isPreprocessable() {
+    return (bool) $this->preprocess;
+  }
+
+  /**
+   * @todo can we do this with a filter?
+   */
+  public function setBrowsers() {
+    // TODO: Implement setBrowsers() method.
+  }
+
+  public function getBrowsers() {
+    // TODO: Implement getBrowsers() method.
+  }
+
+  /**
+   * Declares that the current asset must follow the provided asset.
+   *
+   * This method describes sequencing, not a dependency. That is, passing an
+   * asset to this method does NOT declare that it should be used on the page;
+   * only that it IF that asset is declared elsewhere for use on the page, THEN
+   * this asset should always follow it.
+   *
+   * However, declaring an explicit dependency will trigger this method
+   * internally, so there is no need for client code to call it directly.
+   *
+   * @param AssetInterface $asset
+   *   The asset which the current asset should follow when rendered onto the
+   *   page.
+   *
+   * @return void
+   * @throws \UnexpectedValueException
+   *   If the current asset is of a different type (e.g. CSS vs. Javascript), an
+   *   exception will be thrown.
+   */
+  public function after(AssetInterface $asset) {
+    // TODO: Implement after() method.
+  }
+
+  /**
+   * Indicates whether this asset has any sequencing requirements.
+   *
+   * Sequencing requirements are declared by calling AssetInterface::after().
+   *
+   * @return bool
+   */
+  public function hasSequencing() {
+    // TODO: Implement hasSequencing() method.
+  }
+
+  /**
+   * Gets any assets that must precede this one in the rendering sequence.
+   *
+   * @return array
+   *   An array of AssetInterface objects that should precede this one.
+   */
+  public function getPreceders() {
+    // TODO: Implement getPreceders() method.
+  }
+
+  /**
+   * Declares a dependency on the provided asset library.
+   *
+   * @param AssetLibraryReference $reference
+   *
+   * @return void
+   */
+  public function addDependency(AssetLibraryReference $reference) {
+    // TODO: Implement addDependency() method.
+  }
+
+  /**
+   * Indicates whether or not this asset has library dependencies.
+   *
+   * @return bool
+   */
+  public function hasDependencies() {
+    // TODO: Implement hasDependencies() method.
+  }
+
+  /**
+   * Gets the library dependencies attached to this asset, if any.
+   *
+   * This method may trigger some compilation steps, so if you only need to know
+   * whether or not the asset has dependencies but not what they are, call
+   * AssetInterface::hasDependencies().
+   *
+   * @return array
+   */
+  public function getDependencies() {
+    // TODO: Implement getDependencies() method.
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Asset/BaseExternalAsset.php b/core/lib/Drupal/Core/Asset/BaseExternalAsset.php
new file mode 100644
index 0000000..c61dbcc
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/BaseExternalAsset.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\BaseFileAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Util\PathUtils;
+use Assetic\Filter\FilterInterface;
+use Drupal\Core\Asset\BaseAsset;
+
+abstract class BaseExternalAsset extends BaseAsset {
+
+  protected $preprocess = FALSE;
+
+  /**
+   * @todo Wholly grabbed from Assetic; probably needs Druplification
+   *
+   * @param array $sourceUrl
+   * @param array $filters
+   * @param bool  $ignoreErrors
+   * @param array $vars
+   */
+  public function __construct($sourceUrl, $filters = array(), $ignoreErrors = FALSE, array $vars = array()) {
+    if (0 === strpos($sourceUrl, '//')) {
+      $sourceUrl = 'http:'.$sourceUrl;
+    } elseif (FALSE === strpos($sourceUrl, '://')) {
+      throw new \InvalidArgumentException(sprintf('"%s" is not a valid URL.', $sourceUrl));
+    }
+
+    $this->sourceUrl = $sourceUrl;
+    $this->ignoreErrors = $ignoreErrors;
+
+    list($scheme, $url) = explode('://', $sourceUrl, 2);
+    list($host, $path) = explode('/', $url, 2);
+
+    parent::__construct($filters, $scheme.'://'.$host, $path, $vars);
+  }
+  /**
+   * Returns the time the current asset was last modified.
+   *
+   * @todo copied right from Assetic. needs to be made more Drupalish.
+   *
+   * @return integer|null A UNIX timestamp
+   */
+  public function getLastModified() {
+    if (false !== @file_get_contents($this->sourceUrl, false, stream_context_create(array('http' => array('method' => 'HEAD'))))) {
+      foreach ($http_response_header as $header) {
+        if (0 === stripos($header, 'Last-Modified: ')) {
+          list(, $mtime) = explode(':', $header, 2);
+
+          return strtotime(trim($mtime));
+        }
+      }
+    }
+  }
+
+  /**
+   * Loads the asset into memory and applies load filters.
+   *
+   * You may provide an additional filter to apply during load.
+   *
+   * @todo copied right from Assetic. needs to be made more Drupalish.
+   *
+   * @param FilterInterface $additionalFilter An additional filter
+   */
+  public function load(FilterInterface $additionalFilter = NULL) {
+    if (false === $content = @file_get_contents(PathUtils::resolvePath(
+      $this->sourceUrl, $this->getVars(), $this->getValues()))) {
+      if ($this->ignoreErrors) {
+        return;
+      } else {
+        throw new \RuntimeException(sprintf('Unable to load asset from URL "%s"', $this->sourceUrl));
+      }
+    }
+
+    $this->doLoad($content, $additionalFilter);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Asset/BaseFileAsset.php b/core/lib/Drupal/Core/Asset/BaseFileAsset.php
new file mode 100644
index 0000000..ee3c52a
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/BaseFileAsset.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\BaseFileAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Util\PathUtils;
+use Assetic\Filter\FilterInterface;
+use Drupal\Core\Asset\BaseAsset;
+
+abstract class BaseFileAsset extends BaseAsset {
+
+  protected $source;
+
+  public function __construct($source, $filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array()) {
+    if (null === $sourceRoot) {
+      $sourceRoot = dirname($source);
+      if (null === $sourcePath) {
+        $sourcePath = basename($source);
+      }
+    } elseif (null === $sourcePath) {
+      if (0 !== strpos($source, $sourceRoot)) {
+        throw new \InvalidArgumentException(sprintf('The source "%s" is not in the root directory "%s"', $source, $sourceRoot));
+      }
+
+      $sourcePath = substr($source, strlen($sourceRoot) + 1);
+    }
+
+    $this->source = $source;
+
+    parent::__construct($filters, $sourceRoot, $sourcePath, $vars);
+  }
+
+  /**
+   * Returns the time the current asset was last modified.
+   *
+   * @todo copied right from Assetic. needs to be made more Drupalish.
+   *
+   * @return integer|null A UNIX timestamp
+   */
+  public function getLastModified() {
+    $source = PathUtils::resolvePath($this->source, $this->getVars(),
+      $this->getValues());
+
+    if (!is_file($source)) {
+      throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source));
+    }
+
+    return filemtime($source);
+  }
+
+  /**
+   * Loads the asset into memory and applies load filters.
+   *
+   * You may provide an additional filter to apply during load.
+   *
+   * @todo copied right from Assetic. needs to be made more Drupalish.
+   *
+   * @param FilterInterface $additionalFilter An additional filter
+   */
+  public function load(FilterInterface $additionalFilter = NULL) {
+    $source = PathUtils::resolvePath($this->source, $this->getVars(),
+      $this->getValues());
+
+    if (!is_file($source)) {
+      throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source));
+    }
+
+    $this->doLoad(file_get_contents($source), $additionalFilter);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Asset/BaseStringAsset.php b/core/lib/Drupal/Core/Asset/BaseStringAsset.php
new file mode 100644
index 0000000..4f7b4b3
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/BaseStringAsset.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\BaseInlineAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Assetic\Filter\FilterInterface;
+use Drupal\Core\Asset\BaseAsset;
+
+abstract class BaseStringAsset extends BaseAsset {
+
+  protected $lastModified;
+
+  protected $preprocess = FALSE;
+
+  public function __construct($content, $filters = array(), $sourceRoot = null, $sourcePath = null) {
+    $this->content = $content;
+
+    parent::__construct($filters, $sourceRoot, $sourcePath);
+  }
+
+  public function setLastModified($last_modified) {
+    $this->lastModified = $last_modified;
+  }
+
+  public function getLastModified() {
+    return $this->lastModified;
+  }
+
+  public function load(FilterInterface $additionalFilter = NULL) {
+    $this->doLoad($this->content, $additionalFilter);
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/JavascriptAssetInterface.php b/core/lib/Drupal/Core/Asset/JavascriptAssetInterface.php
new file mode 100644
index 0000000..ca4c220
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/JavascriptAssetInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\JavascriptAssetInterface.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\AssetInterface;
+
+/**
+ * Represents a JavaScript asset.
+ */
+interface JavascriptAssetInterface extends AssetInterface {
+
+  public function setScope($scope);
+
+  public function getScope();
+
+  public function getScopeDefault();
+}
diff --git a/core/lib/Drupal/Core/Asset/JavascriptExternalAsset.php b/core/lib/Drupal/Core/Asset/JavascriptExternalAsset.php
new file mode 100644
index 0000000..0984dd7
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/JavascriptExternalAsset.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\JavascriptExternalAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\JavascriptAssetInterface;
+use Drupal\Core\Asset\BaseExternalAsset;
+
+class JavascriptExternalAsset extends BaseExternalAsset implements JavascriptAssetInterface {
+
+  protected $scope;
+
+  /**
+   * Scope defaults to footer as almost all JavaScript assets can be placed in
+   * the footer.
+   *
+   * @tricky this is a change from the previous behavior!
+   *
+   * @var string
+   */
+  protected $scopeDefault = 'footer';
+
+  public function setScope($scope) {
+    $this->scope = $scope;
+  }
+
+  public function getScope() {
+    return empty($this->scope) ? $this->scopeDefault : $this->scope;
+  }
+
+  public function getScopeDefault() {
+    return $this->scopeDefault;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/JavascriptFileAsset.php b/core/lib/Drupal/Core/Asset/JavascriptFileAsset.php
new file mode 100644
index 0000000..3235e14
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/JavascriptFileAsset.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\JavascriptFileAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\JavascriptAssetInterface;
+use Drupal\Core\Asset\AssetLibraryReference;
+use Drupal\Core\Asset\BaseFileAsset;
+
+class JavascriptFileAsset extends BaseFileAsset implements JavascriptAssetInterface {
+
+  protected $scope;
+
+  /**
+   * Scope defaults to footer as almost all JavaScript assets can be placed in
+   * the footer.
+   *
+   * @tricky this is a change from the previous behavior!
+   *
+   * @var string
+   */
+  protected $scopeDefault = 'footer';
+
+  public function setScope($scope) {
+    $this->scope = $scope;
+  }
+
+  public function getScope() {
+    return empty($this->scope) ? $this->scopeDefault : $this->scope;
+  }
+
+  public function getScopeDefault() {
+    return $this->scopeDefault;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/JavascriptStringAsset.php b/core/lib/Drupal/Core/Asset/JavascriptStringAsset.php
new file mode 100644
index 0000000..c8f3767
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/JavascriptStringAsset.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\JavascriptStringAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\JavascriptAssetInterface;
+use Drupal\Core\Asset\BaseStringAsset;
+
+class JavascriptStringAsset extends BaseStringAsset implements JavascriptAssetInterface {
+
+  protected $scope;
+
+  /**
+   * Scope defaults to footer as almost all JavaScript assets can be placed in
+   * the footer.
+   *
+   * @tricky this is a change from the previous behavior!
+   *
+   * @var string
+   */
+  protected $scopeDefault = 'footer';
+
+  public function setScope($scope) {
+    $this->scope = $scope;
+  }
+
+  public function getScope() {
+    return empty($this->scope) ? $this->scopeDefault : $this->scope;
+  }
+
+  public function getScopeDefault() {
+    return $this->scopeDefault;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/StylesheetAssetInterface.php b/core/lib/Drupal/Core/Asset/StylesheetAssetInterface.php
new file mode 100644
index 0000000..9a81daf
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/StylesheetAssetInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\StylesheetAssetInterface.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\AssetInterface;
+
+/**
+ * Represents a cascading stylesheet (CSS) asset.
+ */
+interface StylesheetAssetInterface extends AssetInterface {
+
+  /**
+   * Sets the media property to be applied on this stylesheet asset.
+   *
+   * @param string $type
+   *   Either a media type, or a media query.
+   *
+   * @return NULL
+   */
+  public function setMedia($type);
+
+  /**
+   * Returns the current value of the media property on this stylesheet asset.
+   *
+   * @return string
+   */
+  public function getMedia();
+
+  /**
+   * Returns the default value of the media property on this stylesheet asset.
+   *
+   * @return mixed
+   */
+  public function getMediaDefault();
+}
diff --git a/core/lib/Drupal/Core/Asset/StylesheetExternalAsset.php b/core/lib/Drupal/Core/Asset/StylesheetExternalAsset.php
new file mode 100644
index 0000000..b7dc800
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/StylesheetExternalAsset.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\StylesheetExternalAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\StylesheetAssetInterface;
+use Drupal\Core\Asset\BaseExternalAsset;
+
+class StylesheetExternalAsset extends BaseExternalAsset implements StylesheetAssetInterface {
+
+  /**
+   * The media query or type to use for this asset. Defaults to 'all'.
+   *
+   * @todo inject the defaults instead of hardcoding them.
+   *
+   * @var string
+   */
+  protected $mediaDefault = 'all';
+
+  protected $media;
+
+  protected $preprocess = FALSE;
+
+  /**
+   * Returns the current value of the media property on this stylesheet asset.
+   *
+   * @return string
+   */
+  public function getMedia() {
+    return $this->media;
+  }
+
+  /**
+   * Returns the default value of the media property on this stylesheet asset.
+   *
+   * @return mixed
+   */
+  public function getMediaDefault() {
+    return $this->mediaDefault;
+  }
+
+  /**
+   * Sets the media property to be applied on this stylesheet asset.
+   *
+   * @param string $type
+   *   Either a media type, or a media query.
+   *
+   * @return NULL
+   */
+  public function setMedia($type) {
+    $this->media = $type;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/StylesheetFileAsset.php b/core/lib/Drupal/Core/Asset/StylesheetFileAsset.php
new file mode 100644
index 0000000..38b3a6b
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/StylesheetFileAsset.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\StylesheetFileAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\StylesheetAssetInterface;
+use Drupal\Core\Asset\BaseFileAsset;
+
+class StylesheetFileAsset extends BaseFileAsset implements StylesheetAssetInterface {
+
+  /**
+   * The media query or type to use for this asset. Defaults to 'all'.
+   *
+   * @todo inject the defaults instead of hardcoding them.
+   *
+   * @var string
+   */
+  protected $mediaDefault = 'all';
+
+  protected $media;
+
+  /**
+   * Returns the current value of the media property on this stylesheet asset.
+   *
+   * @return string
+   */
+  public function getMedia() {
+    return $this->media;
+  }
+
+  /**
+   * Returns the default value of the media property on this stylesheet asset.
+   *
+   * @return mixed
+   */
+  public function getMediaDefault() {
+    return $this->mediaDefault;
+  }
+
+  /**
+   * Sets the media property to be applied on this stylesheet asset.
+   *
+   * @param string $type
+   *   Either a media type, or a media query.
+   *
+   * @return NULL
+   */
+  public function setMedia($type) {
+    $this->media = $type;
+  }
+}
diff --git a/core/lib/Drupal/Core/Asset/StylesheetStringAsset.php b/core/lib/Drupal/Core/Asset/StylesheetStringAsset.php
new file mode 100644
index 0000000..639f6c1
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/StylesheetStringAsset.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\StylesheetStringAsset.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\StylesheetAssetInterface;
+use Drupal\Core\Asset\BaseStringAsset;
+
+class StylesheetStringAsset extends BaseStringAsset implements StylesheetAssetInterface {
+
+  /**
+   * The media query or type to use for this asset. Defaults to 'all'.
+   *
+   * @todo inject the defaults instead of hardcoding them.
+   *
+   * @var string
+   */
+  protected $mediaDefault = 'all';
+
+  protected $media;
+
+  protected $preprocess = FALSE;
+
+  /**
+   * Returns the current value of the media property on this stylesheet asset.
+   *
+   * @return string
+   */
+  public function getMedia() {
+    return $this->media;
+  }
+
+  /**
+   * Returns the default value of the media property on this stylesheet asset.
+   *
+   * @return mixed
+   */
+  public function getMediaDefault() {
+    return $this->mediaDefault;
+  }
+
+  /**
+   * Sets the media property to be applied on this stylesheet asset.
+   *
+   * @param string $type
+   *   Either a media type, or a media query.
+   *
+   * @return NULL
+   */
+  public function setMedia($type) {
+    $this->media = $type;
+  }
+}
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 2076707..1f27569 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -236,6 +236,9 @@ public function build(ContainerBuilder $container) {
     $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
       ->addArgument(new Reference('database'));
 
+    // Add the AssetLibraryManager, which manages versioned libraries as dependencies.
+    $container->register('asset_library_manager', 'Drupal\Core\Asset\AssetLibraryManager');
+
     $container->addCompilerPass(new RegisterMatchersPass());
     $container->addCompilerPass(new RegisterRouteFiltersPass());
     // Add a compiler pass for registering event subscribers.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Asset/AssetAssemblyTest.php b/core/modules/system/lib/Drupal/system/Tests/Asset/AssetAssemblyTest.php
new file mode 100644
index 0000000..d52e760
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Asset/AssetAssemblyTest.php
@@ -0,0 +1,147 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Asset\AssetAssemblyTest.
+ */
+
+namespace Drupal\system\Tests\Asset;
+
+use Drupal\Core\Asset\AssetBag;
+use Drupal\Core\Asset\AssetLibrary;
+use Drupal\Core\Asset\AssetLibraryManager;
+use Drupal\Core\Asset\AssetLibraryReference;
+use Drupal\Core\Asset\JavascriptFileAsset;
+use Drupal\Core\Asset\JavascriptStringAsset;
+use Drupal\Core\Asset\JavascriptExternalAsset;
+use Drupal\Core\Asset\StylesheetFileAsset;
+use Drupal\Core\Asset\StylesheetStringAsset;
+use Drupal\Core\Asset\StylesheetExternalAsset;
+
+use Drupal\simpletest\UnitTestBase;
+
+/**
+ * Provides a base class for Ajax tests.
+ */
+class AssetAssemblyTest extends UnitTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Asset Assembly tests',
+      'description' => 'Tests to ensure assets declared via the various possible approaches come out with the correct properties, in the proper order.',
+      'group' => 'Asset',
+    );
+  }
+
+  public function createJQueryAssetLibrary() {
+    $library = new AssetLibrary(array(new JavascriptFileAsset('core/misc/jquery.js')));
+    return $library->setTitle('jQuery')
+      ->setVersion('1.8.2')
+      ->setWebsite('http://jquery.com');
+  }
+
+  /**
+   * Tests various simple single-bag asset assembly scenarios.
+   *
+   * Much of the real complexity of asset ordering in AssetBags comes from
+   * nesting them, but these tests are focused on the basic mechanics of
+   * assembly within a single bag.
+   */
+  public function testSingleBagAssetAssemblies() {
+    // Dead-simple bag - contains just one css and one js assets, both local files.
+    $bag = new AssetBag();
+
+    $css1 = new StylesheetFileAsset(DRUPAL_ROOT . '/core/misc/vertical-tabs.css');
+    $js1 = new JavascriptFileAsset(DRUPAL_ROOT . '/core/misc/ajax.js');
+
+    $bag->add($css1);
+    $bag->add($js1);
+
+    $this->assertTrue($bag->hasCss(), 'AssetBag correctly reports that it contains CSS assets.');
+    $this->assertTrue($bag->hasJs(), 'AssetBag correctly reports that it contains javascript assets.');
+
+    $this->assertIdentical(array($css1), $bag->getUnsortedCss());
+    $this->assertIdentical(array($js1), $bag->getUnsortedJs());
+
+    $css2 = new StylesheetFileAsset(DRUPAL_ROOT . 'core/misc/dropbutton/dropbutton.base.css');
+    $bag->add($css2);
+
+    $this->assertIdentical(array($css1, $css2), $bag->getCss());
+
+    $this->assertIdentical(array($css1, $js1, $css2), $bag->all());
+  }
+
+  public function testSortingAndDependencyResolution() {
+    $bag = new AssetBag();
+
+    // Populate a mock AssetLibraryManager with the jquery library.
+    $alm = new AssetLibraryManager();
+    $alm->set('jquery', $this->createJQueryAssetLibrary());
+    $dep = new AssetLibraryReference('jquery', $alm);
+
+    $css1 = new StylesheetFileAsset(DRUPAL_ROOT . '/core/misc/vertical-tabs.css');
+    $js1 = new JavascriptFileAsset(DRUPAL_ROOT . '/core/misc/ajax.js');
+    $js1->addDependency($dep);
+
+    $bag->add($css1);
+    $bag->add($js1);
+
+    // Calling getJs() should dereference the dependency into the object
+    // instance contained in the AssetLibraryManager.
+    $this->assertEqual(array($alm->get('jquery'), $js1), $bag->getJs());
+  }
+
+  /**
+   * Tests ensuring that multiple asset bags are combined together correctly.
+   *
+   * @todo introduce some dependency interweaving for real robustness.
+   */
+  public function testMultiBagAssetAssemblies() {
+    $outer_bag = new AssetBag();
+
+    $css1 = new StylesheetFileAsset('core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/main.css');
+    $js1 = new JavascriptFileAsset('core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/jsmin/js.js');
+
+    $outer_bag->add($css1);
+    $outer_bag->add($js1);
+
+    $inner_bag_one = new AssetBag();
+    $inner_bag_two = new AssetBag();
+
+    $css2 = new StylesheetFileAsset('core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssmin/fonts.css');
+    $js2 = new JavascriptFileAsset('core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/packer/example.js');
+    $css3 = new StylesheetExternalAsset('http://example.com/style.css');
+    $css4 = new StylesheetFileAsset('core/vendor/kriswallsmith/assetic/tests/Assetic/Test/Filter/fixtures/cssimport/import.css');
+
+    $inner_bag_one->add($css2);
+    $inner_bag_one->add($js2);
+    // The third asset goes to the inner-inner bag in order to test that it is
+    // spliced in correctly.
+    $inner_bag_two->add($css3);
+    $inner_bag_one->add($css4);
+
+    $inner_bag_one->addAssetBag($inner_bag_two);
+    $outer_bag->addAssetBag($inner_bag_one);
+
+    // Adding the bag will, by default, mark it as terminated and incapable of
+    // receiving new assets.
+    try {
+      $inner_bag_one->add(new JavascriptExternalAsset('http://example.com/script.js'));
+      $this->fail('Terminated AssetBag did not throw expected exception when attempting to add a new asset.');
+    }
+    catch (\LogicException $e) {
+      $this->pass('Terminated AssetBag threw expected LogicException when attempting to add a new asset.');
+    }
+
+    $this->assertIdentical(array($css1, $css2, $css3, $css4), $outer_bag->getCss());
+    $this->assertIdentical(array($js1, $js2), $outer_bag->getJs());
+  }
+
+  /**
+   * Tests to ensure expected variables for use by templates are retrievable.
+   *
+   * @todo variable-generated stage has not yet been dealt with.
+   */
+  public function testTemplateVariableRetrieval() {
+
+  }
+}
diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php
index 913d6b8..43be7ec 100644
--- a/core/vendor/composer/autoload_namespaces.php
+++ b/core/vendor/composer/autoload_namespaces.php
@@ -23,5 +23,5 @@
     'Guzzle\\Common' => $vendorDir . '/guzzle/common/',
     'EasyRdf_' => $vendorDir . '/easyrdf/easyrdf/lib/',
     'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/',
-    'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/',
+    'Assetic\\' => $vendorDir . '/kriswallsmith/assetic/src/',
 );
