Index: sandbox/newExpressoMail/newExpressoMail/inc/load_lang.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/inc/load_lang.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/inc/load_lang.php	(revision 7265)
@@ -0,0 +1,32 @@
+<?php
+		/*************************************************************************** 
+		* Expresso Livre                                                           * 
+		* http://www.expressolivre.org                                             * 
+		* --------------------------------------------                             * 
+		*  This program is free software; you can redistribute it and/or modify it * 
+		*  under the terms of the GNU General Public License as published by the   * 
+		*  Free Software Foundation; either version 2 of the License, or (at your  * 
+		*  option) any later version.                                              * 
+		\**************************************************************************/ 
+		
+// Load the lang of the module.
+	if(isset($offline_language)) { //Expresso offline, quando o gears sincroniza com uma nova versão, não é dado acesso as sessões do usuário, e é preciso o nome do arquivo de linguagens na session abaixo.
+		$_SESSION['phpgw_info']['expressomail']['user']['preferences']['common']['lang'] = $offline_language;
+	}
+	
+	$array_keys = array();
+	$fn = 'setup/phpgw_'.$_SESSION['phpgw_info']['expressomail']['user']['preferences']['common']['lang'].'.lang';			
+	if (file_exists($fn)){
+		$fp = fopen($fn,'r');
+		while ($data = fgets($fp,16000)){
+			list($message_id,$app_name,$null,$content) = explode("\t",substr($data,0,-1));
+			$expressomaillang[$message_id] =  $content;
+			$_SESSION['phpgw_info']['expressomail']['lang'][$message_id] = $content;
+		}
+		fclose($fp);
+	}
+	
+	foreach($expressomaillang as $key => $value)
+		$script .= "array_lang['".str_replace("'","\'",strtolower($key))."'] = '".str_replace("'","\'",$value)."';\n";
+	echo "<script type='text/javascript'>$script</script>";
+?>
Index: sandbox/newExpressoMail/newExpressoMail/inc/style.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/inc/style.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/inc/style.php	(revision 7265)
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Created by JetBrains PhpStorm.
+ * User: Gustavo
+ * Date: 19/09/12
+ * Time: 11:14
+ * To change this template use File | Settings | File Templates.
+ */
+    class ClassAutoloader {
+        public function __construct() {
+            spl_autoload_register(array($this, 'loader'));
+        }
+        private function loader($className) {
+            include "../".str_replace('\\', '/', $className) . '.php';
+        }
+    }
+    define( 'PLUGINSURL' , '../../prototype/plugins' );
+    define( 'MODULESURL' , '../../prototype/modules/newMail' );
+
+    $autoloader = new ClassAutoloader();
+
+    use Assetic\Asset\AssetCollection;
+    use Assetic\Asset\FileAsset;
+    use Assetic\Asset\GlobAsset;
+
+    $css = new AssetCollection(
+        array(
+            new FileAsset(MODULESURL.'/css/reset.css'),
+            new FileAsset(PLUGINSURL.'/jquery/jquery-ui.css'),
+            new FileAsset(PLUGINSURL.'/wijmo/jquery-ui.wijmo.css'),
+            new FileAsset(PLUGINSURL.'/wijmo/jquery.wijmo-open.2.2.0.css'),
+            new FileAsset(PLUGINSURL.'/icalendar/jquery.icalendar.css'),
+            new FileAsset(PLUGINSURL.'/fgmenu/fg.menu.css'),
+            new FileAsset(PLUGINSURL.'/fileupload/jquery.fileupload-ui.css'),
+            new FileAsset(PLUGINSURL.'/jpicker/css/jPicker-1.1.6.min.css'),
+            new FileAsset(PLUGINSURL.'/jpicker/jPicker.css'),
+            new FileAsset(PLUGINSURL.'/farbtastic/farbtastic.css'),
+            new FileAsset(PLUGINSURL.'/timepicker/jquery-ui-timepicker-addon.css'),
+            new FileAsset(PLUGINSURL.'/zebradialog/css/zebra_dialog.css'),
+            new FileAsset(PLUGINSURL.'/treeview/jquery.treeview.css'),
+            new FileAsset(PLUGINSURL.'/jqgrid/css/ui.jqgrid.css'),
+
+
+            new FileAsset(MODULESURL.'/../attach_message/attach_message.css'),
+            new FileAsset(MODULESURL.'/css/layout.css'),
+            new FileAsset(MODULESURL.'/css/style.css'),
+            new FileAsset(MODULESURL.'/css/grid.css'),
+            new FileAsset(MODULESURL.'/css/main.css')
+        )
+     );
+    header('Content-Type: text/css');
+    echo $css->dump();
+?>
Index: sandbox/newExpressoMail/newExpressoMail/inc/core.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/inc/core.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/inc/core.php	(revision 7265)
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Created by JetBrains PhpStorm.
+ * User: Gustavo
+ * Date: 19/09/12
+ * Time: 09:49
+ * To change this template use File | Settings | File Templates.
+ */
+    class ClassAutoloader {
+        public function __construct() {
+            spl_autoload_register(array($this, 'loader'));
+        }
+        private function loader($className) {
+            include "../".str_replace('\\', '/', $className) . '.php';
+        }
+    }
+    define( 'PLUGINSURL' , '../../prototype/plugins' );
+    define( 'MODULESURL' , '../../prototype/modules/newMail' );
+
+    $autoloader = new ClassAutoloader();
+
+    use Assetic\Asset\AssetCollection;
+    use Assetic\Asset\FileAsset;
+    use Assetic\Asset\GlobAsset;
+
+    $js = new AssetCollection(array(
+        //new FileAsset(PLUGINSURL.'/zebradialog/javascript/zebra_dialog.js'),
+        //new FileAsset(PLUGINSURL.'/scrollto/jquery.scrollTo.js'),
+        new FileAsset(PLUGINSURL.'/fileupload/jquery.fileupload.js'),
+        new FileAsset(PLUGINSURL.'/fileupload/jquery.iframe-transport.js'),
+        //new FileAsset(PLUGINSURL.'/jpicker/jpicker-1.1.6.min.js'),
+        new FileAsset(PLUGINSURL.'/watermark/jquery.watermarkinput.js'),
+        new FileAsset(PLUGINSURL.'/alphanumeric/jquery.alphanumeric.js'),
+        new FileAsset(PLUGINSURL.'/qtip/jquery.qtip-1.0.0-rc3.min.js'),
+        new FileAsset(PLUGINSURL.'/contextmenu/jquery.contextMenu.js'),
+        new FileAsset(PLUGINSURL.'/farbtastic/farbtastic.js'),
+        new FileAsset(PLUGINSURL.'/fgmenu/fg.menu.js'),
+        new FileAsset(PLUGINSURL.'/treeview/jquery.treeview.js'),
+        new FileAsset(PLUGINSURL.'/treeview/lib/jquery.cookie.js'),
+        new FileAsset(PLUGINSURL.'/layout/jquery.layout.min.js'),
+        new FileAsset(PLUGINSURL.'/wijmo/jquery.wijmo-open.all.2.2.0.min.js'),
+        new FileAsset(PLUGINSURL.'/jqgrid/js/i18n/grid.locale-pt-br.js'),
+        new FileAsset(PLUGINSURL.'/jqgrid/js/jquery.jqGrid.min.js'),
+        new FileAsset(PLUGINSURL.'/ejs/ejs.js'),
+        new FileAsset(PLUGINSURL.'/countdown/jquery.countdown.min.js'),
+        new FileAsset(PLUGINSURL.'/countdown/jquery.countdown-pt-BR.js'),
+
+        new FileAsset(MODULESURL.'/js/formatters.js'),
+        new FileAsset(MODULESURL.'/js/newfoldertree.js'),
+        new FileAsset(MODULESURL.'/js/tabs.js'),
+        new FileAsset(MODULESURL.'/js/alerts.js'),
+        new FileAsset(MODULESURL.'/js/folder.js'),
+        new FileAsset(MODULESURL.'/js/init.js')
+
+        //new FileAsset(PLUGINSURL.'/mask/jquery.maskedinput.js')
+    ));
+    header('Content-Type: text/javascript');
+    echo $js->dump();
+?>
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/BaseAsset.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/BaseAsset.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/BaseAsset.php	(revision 7265)
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterCollection;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A base abstract asset.
+ *
+ * The methods load() and getLastModified() are left undefined, although a
+ * reusable doLoad() method is available to child classes.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseAsset implements AssetInterface
+{
+    private $filters;
+    private $sourceRoot;
+    private $sourcePath;
+    private $targetPath;
+    private $content;
+    private $loaded;
+    private $vars;
+    private $values;
+
+    /**
+     * Constructor.
+     *
+     * @param array  $filters    Filters for the asset
+     * @param string $sourceRoot The root directory
+     * @param string $sourcePath The asset path
+     * @param array  $vars
+     */
+    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;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollection.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollection.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollection.php	(revision 7265)
@@ -0,0 +1,227 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Asset\Iterator\AssetCollectionFilterIterator;
+use Assetic\Asset\Iterator\AssetCollectionIterator;
+use Assetic\Filter\FilterCollection;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A collection of assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollection implements \IteratorAggregate, AssetCollectionInterface
+{
+    private $assets;
+    private $filters;
+    private $sourceRoot;
+    private $targetPath;
+    private $content;
+    private $clones;
+    private $vars;
+    private $values;
+
+    /**
+     * Constructor.
+     *
+     * @param array  $assets     Assets for the current collection
+     * @param array  $filters    Filters for the current collection
+     * @param string $sourceRoot The root directory
+     * @param array  $vars
+     */
+    public function __construct($assets = array(), $filters = array(), $sourceRoot = null, array $vars = array())
+    {
+        $this->assets = array();
+        foreach ($assets as $asset) {
+            $this->add($asset);
+        }
+
+        $this->filters = new FilterCollection($filters);
+        $this->sourceRoot = $sourceRoot;
+        $this->clones = new \SplObjectStorage();
+        $this->vars = $vars;
+        $this->values = array();
+    }
+
+    public function all()
+    {
+        return $this->assets;
+    }
+
+    public function add(AssetInterface $asset)
+    {
+        $this->assets[] = $asset;
+    }
+
+    public function removeLeaf(AssetInterface $needle, $graceful = false)
+    {
+        foreach ($this->assets as $i => $asset) {
+            $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null;
+            if (in_array($needle, array($asset, $clone), true)) {
+                unset($this->clones[$asset], $this->assets[$i]);
+
+                return true;
+            }
+
+            if ($asset instanceof AssetCollectionInterface && $asset->removeLeaf($needle, true)) {
+                return true;
+            }
+        }
+
+        if ($graceful) {
+            return false;
+        }
+
+        throw new \InvalidArgumentException('Leaf not found.');
+    }
+
+    public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false)
+    {
+        foreach ($this->assets as $i => $asset) {
+            $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null;
+            if (in_array($needle, array($asset, $clone), true)) {
+                unset($this->clones[$asset]);
+                $this->assets[$i] = $replacement;
+
+                return true;
+            }
+
+            if ($asset instanceof AssetCollectionInterface && $asset->replaceLeaf($needle, $replacement, true)) {
+                return true;
+            }
+        }
+
+        if ($graceful) {
+            return false;
+        }
+
+        throw new \InvalidArgumentException('Leaf not found.');
+    }
+
+    public function ensureFilter(FilterInterface $filter)
+    {
+        $this->filters->ensure($filter);
+    }
+
+    public function getFilters()
+    {
+        return $this->filters->all();
+    }
+
+    public function clearFilters()
+    {
+        $this->filters->clear();
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        // loop through leaves and load each asset
+        $parts = array();
+        foreach ($this as $asset) {
+            $asset->load($additionalFilter);
+            $parts[] = $asset->getContent();
+        }
+
+        $this->content = implode("\n", $parts);
+    }
+
+    public function dump(FilterInterface $additionalFilter = null)
+    {
+        // loop through leaves and dump each asset
+        $parts = array();
+        foreach ($this as $asset) {
+            $parts[] = $asset->dump($additionalFilter);
+        }
+
+        return implode("\n", $parts);
+    }
+
+    public function getContent()
+    {
+        return $this->content;
+    }
+
+    public function setContent($content)
+    {
+        $this->content = $content;
+    }
+
+    public function getSourceRoot()
+    {
+        return $this->sourceRoot;
+    }
+
+    public function getSourcePath()
+    {
+    }
+
+    public function getTargetPath()
+    {
+        return $this->targetPath;
+    }
+
+    public function setTargetPath($targetPath)
+    {
+        $this->targetPath = $targetPath;
+    }
+
+    /**
+     * Returns the highest last-modified value of all assets in the current collection.
+     *
+     * @return integer|null A UNIX timestamp
+     */
+    public function getLastModified()
+    {
+        if (!count($this->assets)) {
+            return;
+        }
+
+        $mtime = 0;
+        foreach ($this as $asset) {
+            $assetMtime = $asset->getLastModified();
+            if ($assetMtime > $mtime) {
+                $mtime = $assetMtime;
+            }
+        }
+
+        return $mtime;
+    }
+
+    /**
+     * Returns an iterator for looping recursively over unique leaves.
+     */
+    public function getIterator()
+    {
+        return new \RecursiveIteratorIterator(new AssetCollectionFilterIterator(new AssetCollectionIterator($this, $this->clones)));
+    }
+
+    public function getVars()
+    {
+        return $this->vars;
+    }
+
+    public function setValues(array $values)
+    {
+        $this->values = $values;
+
+        foreach ($this as $asset) {
+            $asset->setValues(array_intersect_key($values, array_flip($asset->getVars())));
+        }
+    }
+
+    public function getValues()
+    {
+        return $this->values;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollectionInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollectionInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCollectionInterface.php	(revision 7265)
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+/**
+ * An asset collection.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface AssetCollectionInterface extends AssetInterface, \Traversable
+{
+    /**
+     * Returns all child assets.
+     *
+     * @return array An array of AssetInterface objects
+     */
+    public function all();
+
+    /**
+     * Adds an asset to the current collection.
+     *
+     * @param AssetInterface $asset An asset
+     */
+    public function add(AssetInterface $asset);
+
+    /**
+     * Removes a leaf.
+     *
+     * @param AssetInterface $leaf      The leaf to remove
+     * @param Boolean        $graceful  Whether the failure should return false or throw an exception
+     *
+     * @return Boolean Whether the asset has been found
+     *
+     * @throws \InvalidArgumentException If the asset cannot be found
+     */
+    public function removeLeaf(AssetInterface $leaf, $graceful = false);
+
+    /**
+     * Replaces an existing leaf with a new one.
+     *
+     * @param AssetInterface $needle      The current asset to replace
+     * @param AssetInterface $replacement The new asset
+     * @param Boolean        $graceful  Whether the failure should return false or throw an exception
+     *
+     * @return Boolean Whether the asset has been found
+     *
+     * @throws \InvalidArgumentException If the asset cannot be found
+     */
+    public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false);
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetReference.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetReference.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetReference.php	(revision 7265)
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\AssetManager;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A reference to an asset in the asset manager.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetReference implements AssetInterface
+{
+    private $am;
+    private $name;
+    private $filters = array();
+
+    public function __construct(AssetManager $am, $name)
+    {
+        $this->am = $am;
+        $this->name = $name;
+    }
+
+    public function ensureFilter(FilterInterface $filter)
+    {
+        $this->filters[] = $filter;
+    }
+
+    public function getFilters()
+    {
+        $this->flushFilters();
+
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function clearFilters()
+    {
+        $this->filters = array();
+        $this->callAsset(__FUNCTION__);
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        $this->flushFilters();
+
+        return $this->callAsset(__FUNCTION__, array($additionalFilter));
+    }
+
+    public function dump(FilterInterface $additionalFilter = null)
+    {
+        $this->flushFilters();
+
+        return $this->callAsset(__FUNCTION__, array($additionalFilter));
+    }
+
+    public function getContent()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function setContent($content)
+    {
+        $this->callAsset(__FUNCTION__, array($content));
+    }
+
+    public function getSourceRoot()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function getSourcePath()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function getTargetPath()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function setTargetPath($targetPath)
+    {
+        $this->callAsset(__FUNCTION__, array($targetPath));
+    }
+
+    public function getLastModified()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function getVars()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function getValues()
+    {
+        return $this->callAsset(__FUNCTION__);
+    }
+
+    public function setValues(array $values)
+    {
+        $this->callAsset(__FUNCTION__, array($values));
+    }
+
+    // private
+
+    private function callAsset($method, $arguments = array())
+    {
+        $asset = $this->am->get($this->name);
+
+        return call_user_func_array(array($asset, $method), $arguments);
+    }
+
+    private function flushFilters()
+    {
+        $asset = $this->am->get($this->name);
+
+        while ($filter = array_shift($this->filters)) {
+            $asset->ensureFilter($filter);
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/FileAsset.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/FileAsset.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/FileAsset.php	(revision 7265)
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Util\PathUtils;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Represents an asset loaded from a file.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FileAsset extends BaseAsset
+{
+    private $source;
+
+    /**
+     * Constructor.
+     *
+     * @param string $source     An absolute path
+     * @param array  $filters    An array of filters
+     * @param string $sourceRoot The source asset root directory
+     * @param string $sourcePath The source asset path
+     * @param array  $vars
+     *
+     * @throws \InvalidArgumentException If the supplied root doesn't match the source when guessing the path
+     */
+    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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/HttpAsset.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/HttpAsset.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/HttpAsset.php	(revision 7265)
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Util\PathUtils;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Represents an asset loaded via an HTTP request.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class HttpAsset extends BaseAsset
+{
+    private $sourceUrl;
+    private $ignoreErrors;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $sourceUrl    The source URL
+     * @param array   $filters      An array of filters
+     * @param Boolean $ignoreErrors
+     * @param array   $vars
+     *
+     * @throws \InvalidArgumentException If the first argument is not an URL
+     */
+    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);
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        if (false === $content = @file_get_contents(PathUtils::resolvePath(
+                $this->sourceUrl, $this->getVars(), $this->getValues()))
+        ) {
+            if ($this->ignoreErrors) {
+                return;
+            }
+
+            throw new \RuntimeException(sprintf('Unable to load asset from URL "%s"', $this->sourceUrl));
+        }
+
+        $this->doLoad($content, $additionalFilter);
+    }
+
+    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));
+                }
+            }
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetInterface.php	(revision 7265)
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * An asset has a mutable URL and content and can be loaded and dumped.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface AssetInterface
+{
+    /**
+     * Ensures the current asset includes the supplied filter.
+     *
+     * @param FilterInterface $filter A filter
+     */
+    public function ensureFilter(FilterInterface $filter);
+
+    /**
+     * Returns an array of filters currently applied.
+     *
+     * @return array An array of filters
+     */
+    public function getFilters();
+
+    /**
+     * Clears all filters from the current asset.
+     */
+    public function clearFilters();
+
+    /**
+     * Loads the asset into memory and applies load filters.
+     *
+     * You may provide an additional filter to apply during load.
+     *
+     * @param FilterInterface $additionalFilter An additional filter
+     */
+    public function load(FilterInterface $additionalFilter = null);
+
+    /**
+     * Applies dump filters and returns the asset as a string.
+     *
+     * You may provide an additional filter to apply during dump.
+     *
+     * Dumping an asset should not change its state.
+     *
+     * If the current asset has not been loaded yet, it should be
+     * automatically loaded at this time.
+     *
+     * @param FilterInterface $additionalFilter An additional filter
+     *
+     * @return string The filtered content of the current asset
+     */
+    public function dump(FilterInterface $additionalFilter = null);
+
+    /**
+     * Returns the loaded content of the current asset.
+     *
+     * @return string The content
+     */
+    public function getContent();
+
+    /**
+     * Sets the content of the current asset.
+     *
+     * Filters can use this method to change the content of the asset.
+     *
+     * @param string $content The asset content
+     */
+    public function setContent($content);
+
+    /**
+     * Returns an absolute path or URL to the source asset's root directory.
+     *
+     * This value should be an absolute path to a directory in the filesystem,
+     * an absolute URL with no path, or null.
+     *
+     * For example:
+     *
+     *  * '/path/to/web'
+     *  * 'http://example.com'
+     *  * null
+     *
+     * @return string|null The asset's root
+     */
+    public function getSourceRoot();
+
+    /**
+     * Returns the relative path for the source asset.
+     *
+     * This value can be combined with the asset's source root (if both are
+     * non-null) to get something compatible with file_get_contents().
+     *
+     * For example:
+     *
+     *  * 'js/main.js'
+     *  * 'main.js'
+     *  * null
+     *
+     * @return string|null The source asset path
+     */
+    public function getSourcePath();
+
+    /**
+     * Returns the URL for the current asset.
+     *
+     * @return string|null A web URL where the asset will be dumped
+     */
+    public function getTargetPath();
+
+    /**
+     * Sets the URL for the current asset.
+     *
+     * @param string $targetPath A web URL where the asset will be dumped
+     */
+    public function setTargetPath($targetPath);
+
+    /**
+     * Returns the time the current asset was last modified.
+     *
+     * @return integer|null A UNIX timestamp
+     */
+    public function getLastModified();
+
+    /**
+     * Returns an array of variable names for this asset.
+     *
+     * @return array
+     */
+    public function getVars();
+
+    /**
+     * Sets the values for the asset's variables.
+     *
+     * @param array $values
+     */
+    public function setValues(array $values);
+
+    /**
+     * Returns the current values for this asset.
+     *
+     * @return array an array of strings
+     */
+    public function getValues();
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCache.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCache.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/AssetCache.php	(revision 7265)
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Cache\CacheInterface;
+use Assetic\Filter\FilterInterface;
+use Assetic\Filter\HashableInterface;
+
+/**
+ * Caches an asset to avoid the cost of loading and dumping.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCache implements AssetInterface
+{
+    private $asset;
+    private $cache;
+
+    public function __construct(AssetInterface $asset, CacheInterface $cache)
+    {
+        $this->asset = $asset;
+        $this->cache = $cache;
+    }
+
+    public function ensureFilter(FilterInterface $filter)
+    {
+        $this->asset->ensureFilter($filter);
+    }
+
+    public function getFilters()
+    {
+        return $this->asset->getFilters();
+    }
+
+    public function clearFilters()
+    {
+        $this->asset->clearFilters();
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'load');
+        if ($this->cache->has($cacheKey)) {
+            $this->asset->setContent($this->cache->get($cacheKey));
+
+            return;
+        }
+
+        $this->asset->load($additionalFilter);
+        $this->cache->set($cacheKey, $this->asset->getContent());
+    }
+
+    public function dump(FilterInterface $additionalFilter = null)
+    {
+        $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'dump');
+        if ($this->cache->has($cacheKey)) {
+            return $this->cache->get($cacheKey);
+        }
+
+        $content = $this->asset->dump($additionalFilter);
+        $this->cache->set($cacheKey, $content);
+
+        return $content;
+    }
+
+    public function getContent()
+    {
+        return $this->asset->getContent();
+    }
+
+    public function setContent($content)
+    {
+        $this->asset->setContent($content);
+    }
+
+    public function getSourceRoot()
+    {
+        return $this->asset->getSourceRoot();
+    }
+
+    public function getSourcePath()
+    {
+        return $this->asset->getSourcePath();
+    }
+
+    public function getTargetPath()
+    {
+        return $this->asset->getTargetPath();
+    }
+
+    public function setTargetPath($targetPath)
+    {
+        $this->asset->setTargetPath($targetPath);
+    }
+
+    public function getLastModified()
+    {
+        return $this->asset->getLastModified();
+    }
+
+    public function getVars()
+    {
+        return $this->asset->getVars();
+    }
+
+    public function setValues(array $values)
+    {
+        $this->asset->setValues($values);
+    }
+
+    public function getValues()
+    {
+        return $this->asset->getValues();
+    }
+
+    /**
+     * Returns a cache key for the current asset.
+     *
+     * The key is composed of everything but an asset's content:
+     *
+     *  * source root
+     *  * source path
+     *  * target url
+     *  * last modified
+     *  * filters
+     *
+     * @param AssetInterface  $asset            The asset
+     * @param FilterInterface $additionalFilter Any additional filter being applied
+     * @param string          $salt             Salt for the key
+     *
+     * @return string A key for identifying the current asset
+     */
+    private static function getCacheKey(AssetInterface $asset, FilterInterface $additionalFilter = null, $salt = '')
+    {
+        if ($additionalFilter) {
+            $asset = clone $asset;
+            $asset->ensureFilter($additionalFilter);
+        }
+
+        $cacheKey  = $asset->getSourceRoot();
+        $cacheKey .= $asset->getSourcePath();
+        $cacheKey .= $asset->getTargetPath();
+        $cacheKey .= $asset->getLastModified();
+
+        foreach ($asset->getFilters() as $filter) {
+            if ($filter instanceof HashableInterface) {
+                $cacheKey .= $filter->hash();
+            } else {
+                $cacheKey .= serialize($filter);
+            }
+        }
+
+        if ($values = $asset->getValues()) {
+            asort($values);
+            $cacheKey .= serialize($values);
+        }
+
+        return md5($cacheKey.$salt);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/GlobAsset.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/GlobAsset.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/GlobAsset.php	(revision 7265)
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Util\PathUtils;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A collection of assets loaded by glob.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class GlobAsset extends AssetCollection
+{
+    private $globs;
+    private $initialized;
+
+    /**
+     * Constructor.
+     *
+     * @param string|array $globs   A single glob path or array of paths
+     * @param array        $filters An array of filters
+     * @param string       $root    The root directory
+     * @param array        $vars
+     */
+    public function __construct($globs, $filters = array(), $root = null, array $vars = array())
+    {
+        $this->globs = (array) $globs;
+        $this->initialized = false;
+
+        parent::__construct(array(), $filters, $root, $vars);
+    }
+
+    public function all()
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        return parent::all();
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        parent::load($additionalFilter);
+    }
+
+    public function dump(FilterInterface $additionalFilter = null)
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        return parent::dump($additionalFilter);
+    }
+
+    public function getLastModified()
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        return parent::getLastModified();
+    }
+
+    public function getIterator()
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        return parent::getIterator();
+    }
+
+    public function setValues(array $values)
+    {
+        parent::setValues($values);
+        $this->initialized = false;
+    }
+
+    /**
+     * Initializes the collection based on the glob(s) passed in.
+     */
+    private function initialize()
+    {
+        foreach ($this->globs as $glob) {
+            $glob = PathUtils::resolvePath($glob, $this->getVars(), $this->getValues());
+
+            if (false !== $paths = glob($glob)) {
+                foreach ($paths as $path) {
+                    if (is_file($path)) {
+                        $this->add(new FileAsset($path, array(), $this->getSourceRoot()));
+                    }
+                }
+            }
+        }
+
+        $this->initialized = true;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php	(revision 7265)
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset\Iterator;
+
+/**
+ * Asset collection filter iterator.
+ *
+ * The filter iterator is responsible for de-duplication of leaf assets based
+ * on both strict equality and source URL.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollectionFilterIterator extends \RecursiveFilterIterator
+{
+    private $visited;
+    private $sources;
+
+    /**
+     * Constructor.
+     *
+     * @param AssetCollectionIterator $iterator The inner iterator
+     * @param array                   $visited  An array of visited asset objects
+     * @param array                   $sources  An array of visited source strings
+     */
+    public function __construct(AssetCollectionIterator $iterator, array $visited = array(), array $sources = array())
+    {
+        parent::__construct($iterator);
+
+        $this->visited = $visited;
+        $this->sources = $sources;
+    }
+
+    /**
+     * Determines whether the current asset is a duplicate.
+     *
+     * De-duplication is performed based on either strict equality or by
+     * matching sources.
+     *
+     * @return Boolean Returns true if we have not seen this asset yet
+     */
+    public function accept()
+    {
+        $asset = $this->getInnerIterator()->current(true);
+        $duplicate = false;
+
+        // check strict equality
+        if (in_array($asset, $this->visited, true)) {
+            $duplicate = true;
+        } else {
+            $this->visited[] = $asset;
+        }
+
+        // check source
+        $sourceRoot = $asset->getSourceRoot();
+        $sourcePath = $asset->getSourcePath();
+        if ($sourceRoot && $sourcePath) {
+            $source = $sourceRoot.'/'.$sourcePath;
+            if (in_array($source, $this->sources)) {
+                $duplicate = true;
+            } else {
+                $this->sources[] = $source;
+            }
+        }
+
+        return !$duplicate;
+    }
+
+    /**
+     * Passes visited objects and source URLs to the child iterator.
+     */
+    public function getChildren()
+    {
+        return new self($this->getInnerIterator()->getChildren(), $this->visited, $this->sources);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionIterator.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionIterator.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/Iterator/AssetCollectionIterator.php	(revision 7265)
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset\Iterator;
+
+use Assetic\Asset\AssetCollectionInterface;
+
+/**
+ * Iterates over an asset collection.
+ *
+ * The iterator is responsible for cascading filters and target URL patterns
+ * from parent to child assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollectionIterator implements \RecursiveIterator
+{
+    private $assets;
+    private $filters;
+    private $output;
+    private $clones;
+
+    public function __construct(AssetCollectionInterface $coll, \SplObjectStorage $clones)
+    {
+        $this->assets  = $coll->all();
+        $this->filters = $coll->getFilters();
+        $this->output  = $coll->getTargetPath();
+        $this->clones  = $clones;
+
+        if (false === $pos = strpos($this->output, '.')) {
+            $this->output .= '_*';
+        } else {
+            $this->output = substr($this->output, 0, $pos).'_*'.substr($this->output, $pos);
+        }
+    }
+
+    /**
+     * Returns a copy of the current asset with filters and a target URL applied.
+     *
+     * @param Boolean $raw Returns the unmodified asset if true
+     * @return \Assetic\Asset\AssetInterface
+     */
+    public function current($raw = false)
+    {
+        $asset = current($this->assets);
+
+        if ($raw) {
+            return $asset;
+        }
+
+        // clone once
+        if (!isset($this->clones[$asset])) {
+            $clone = $this->clones[$asset] = clone $asset;
+
+            // generate a target path based on asset name
+            $name = sprintf('%s_%d', pathinfo($asset->getSourcePath(), PATHINFO_FILENAME) ?: 'part', $this->key() + 1);
+            $clone->setTargetPath(str_replace('*', $name, $this->output));
+        } else {
+            $clone = $this->clones[$asset];
+        }
+
+        // cascade filters
+        foreach ($this->filters as $filter) {
+            $clone->ensureFilter($filter);
+        }
+
+        return $clone;
+    }
+
+    public function key()
+    {
+        return key($this->assets);
+    }
+
+    public function next()
+    {
+        return next($this->assets);
+    }
+
+    public function rewind()
+    {
+        return reset($this->assets);
+    }
+
+    public function valid()
+    {
+        return false !== current($this->assets);
+    }
+
+    public function hasChildren()
+    {
+        return current($this->assets) instanceof AssetCollectionInterface;
+    }
+
+    /**
+     * @uses current()
+     */
+    public function getChildren()
+    {
+        return new self($this->current(), $this->clones);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/StringAsset.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/StringAsset.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Asset/StringAsset.php	(revision 7265)
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Represents a string asset.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class StringAsset extends BaseAsset
+{
+    private $content;
+    private $lastModified;
+
+    /**
+     * Constructor.
+     *
+     * @param string $content    The content of the asset
+     * @param array  $filters    Filters for the asset
+     * @param string $sourceRoot The source asset root directory
+     * @param string $sourcePath The source asset path
+     */
+    public function __construct($content, $filters = array(), $sourceRoot = null, $sourcePath = null)
+    {
+        $this->content = $content;
+
+        parent::__construct($filters, $sourceRoot, $sourcePath);
+    }
+
+    public function load(FilterInterface $additionalFilter = null)
+    {
+        $this->doLoad($this->content, $additionalFilter);
+    }
+
+    public function setLastModified($lastModified)
+    {
+        $this->lastModified = $lastModified;
+    }
+
+    public function getLastModified()
+    {
+        return $this->lastModified;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/AssetManager.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/AssetManager.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/AssetManager.php	(revision 7265)
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Manages assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetManager
+{
+    private $assets = array();
+
+    /**
+     * Gets an asset by name.
+     *
+     * @param string $name The asset name
+     *
+     * @return AssetInterface The asset
+     *
+     * @throws \InvalidArgumentException If there is no asset by that name
+     */
+    public function get($name)
+    {
+        if (!isset($this->assets[$name])) {
+            throw new \InvalidArgumentException(sprintf('There is no "%s" asset.', $name));
+        }
+
+        return $this->assets[$name];
+    }
+
+    /**
+     * Checks if the current asset manager has a certain asset.
+     *
+     * @param string $name an asset name
+     *
+     * @return Boolean True if the asset has been set, false if not
+     */
+    public function has($name)
+    {
+        return isset($this->assets[$name]);
+    }
+
+    /**
+     * Registers an asset to the current asset manager.
+     *
+     * @param string         $name  The asset name
+     * @param AssetInterface $asset The asset
+     *
+     * @throws \InvalidArgumentException If tthe asset name is invalid
+     */
+    public function set($name, AssetInterface $asset)
+    {
+        if (!ctype_alnum(str_replace('_', '', $name))) {
+            throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name));
+        }
+
+        $this->assets[$name] = $asset;
+    }
+
+    /**
+     * Returns an array of asset names.
+     *
+     * @return array An array of asset names
+     */
+    public function getNames()
+    {
+        return array_keys($this->assets);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/AssetWriter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/AssetWriter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/AssetWriter.php	(revision 7265)
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Util\PathUtils;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Writes assets to the filesystem.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class AssetWriter
+{
+    private $dir;
+    private $varValues;
+
+    /**
+     * Constructor.
+     *
+     * @param string $dir The base web directory
+     * @param array  $varValues
+     *
+     * @throws \InvalidArgumentException if a variable value is not a string
+     */
+    public function __construct($dir, array $varValues = array())
+    {
+        foreach ($varValues as $var => $values) {
+            foreach ($values as $value) {
+                if (!is_string($value)) {
+                    throw new \InvalidArgumentException(sprintf('All variable values must be strings, but got %s for variable "%s".', json_encode($value), $var));
+                }
+            }
+        }
+
+        $this->dir = $dir;
+        $this->varValues = $varValues;
+    }
+
+    public function writeManagerAssets(AssetManager $am)
+    {
+        foreach ($am->getNames() as $name) {
+            $this->writeAsset($am->get($name));
+        }
+    }
+
+    public function writeAsset(AssetInterface $asset)
+    {
+        foreach ($this->getCombinations($asset->getVars()) as $combination) {
+            $asset->setValues($combination);
+
+            static::write($this->dir.'/'.PathUtils::resolvePath(
+                $asset->getTargetPath(), $asset->getVars(), $asset->getValues()),
+                $asset->dump());
+        }
+    }
+
+    private function getCombinations(array $vars)
+    {
+        if (!$vars) {
+            return array(array());
+        }
+
+        $combinations = array();
+        $nbValues = array();
+        foreach ($this->varValues as $var => $values) {
+            if (!in_array($var, $vars, true)) {
+                continue;
+            }
+
+            $nbValues[$var] = count($values);
+        }
+
+        for ($i=array_product($nbValues),$c=$i*2; $i<$c; $i++) {
+            $k = $i;
+            $combination = array();
+
+            foreach ($vars as $var) {
+                $combination[$var] = $this->varValues[$var][$k % $nbValues[$var]];
+                $k = intval($k/$nbValues[$var]);
+            }
+
+            $combinations[] = $combination;
+        }
+
+        return $combinations;
+    }
+
+    protected static function write($path, $contents)
+    {
+        if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) {
+            throw new \RuntimeException('Unable to create directory '.$dir);
+        }
+
+        if (false === @file_put_contents($path, $contents)) {
+            throw new \RuntimeException('Unable to write file '.$path);
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ConfigCache.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ConfigCache.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ConfigCache.php	(revision 7265)
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * A config cache stores values using var_export() and include.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ConfigCache
+{
+    private $dir;
+
+    /**
+     * Construct.
+     *
+     * @param string $dir The cache directory
+     */
+    public function __construct($dir)
+    {
+        $this->dir = $dir;
+    }
+
+    /**
+     * Checks of the cache has a file.
+     *
+     * @param string $resource A cache key
+     *
+     * @return Boolean True if a file exists
+     */
+    public function has($resource)
+    {
+        return file_exists($this->getSourcePath($resource));
+    }
+
+    /**
+     * Writes a value to a file.
+     *
+     * @param string $resource A cache key
+     * @param mixed  $value    A value to cache
+     */
+    public function set($resource, $value)
+    {
+        $path = $this->getSourcePath($resource);
+
+        if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) {
+            // @codeCoverageIgnoreStart
+            throw new \RuntimeException('Unable to create directory '.$dir);
+            // @codeCoverageIgnoreEnd
+        }
+
+        if (false === @file_put_contents($path, sprintf("<?php\n\n// $resource\nreturn %s;\n", var_export($value, true)))) {
+            // @codeCoverageIgnoreStart
+            throw new \RuntimeException('Unable to write file '.$path);
+            // @codeCoverageIgnoreEnd
+        }
+    }
+
+    /**
+     * Loads and returns the value for the supplied cache key.
+     *
+     * @param string $resource A cache key
+     *
+     * @return mixed The cached value
+     */
+    public function get($resource)
+    {
+        $path = $this->getSourcePath($resource);
+
+        if (!file_exists($path)) {
+            throw new \RuntimeException('There is no cached value for '.$resource);
+        }
+
+        return include $path;
+    }
+
+    /**
+     * Returns a timestamp for when the cache was created.
+     *
+     * @param string $resource A cache key
+     *
+     * @return integer A UNIX timestamp
+     */
+    public function getTimestamp($resource)
+    {
+        $path = $this->getSourcePath($resource);
+
+        if (!file_exists($path)) {
+            throw new \RuntimeException('There is no cached value for '.$resource);
+        }
+
+        if (false === $mtime = @filemtime($path)) {
+            // @codeCoverageIgnoreStart
+            throw new \RuntimeException('Unable to determine file mtime for '.$path);
+            // @codeCoverageIgnoreEnd
+        }
+
+        return $mtime;
+    }
+
+    /**
+     * Returns the path where the file corresponding to the supplied cache key can be included from.
+     *
+     * @param string $resource A cache key
+     *
+     * @return string A file path
+     */
+    private function getSourcePath($resource)
+    {
+        $key = md5($resource);
+
+        return $this->dir.'/'.$key[0].'/'.$key.'.php';
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ExpiringCache.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ExpiringCache.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ExpiringCache.php	(revision 7265)
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Adds expiration to a cache backend.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ExpiringCache implements CacheInterface
+{
+    private $cache;
+    private $lifetime;
+
+    public function __construct(CacheInterface $cache, $lifetime)
+    {
+        $this->cache = $cache;
+        $this->lifetime = $lifetime;
+    }
+
+    public function has($key)
+    {
+        if ($this->cache->has($key)) {
+            if (time() < $this->cache->get($key.'.expires')) {
+                return true;
+            }
+
+            $this->cache->remove($key.'.expires');
+            $this->cache->remove($key);
+        }
+
+        return false;
+    }
+
+    public function get($key)
+    {
+        return $this->cache->get($key);
+    }
+
+    public function set($key, $value)
+    {
+        $this->cache->set($key.'.expires', time() + $this->lifetime);
+        $this->cache->set($key, $value);
+    }
+
+    public function remove($key)
+    {
+        $this->cache->remove($key.'.expires');
+        $this->cache->remove($key);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/CacheInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/CacheInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/CacheInterface.php	(revision 7265)
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Interface for a cache backend.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface CacheInterface
+{
+    /**
+     * Checks if the cache has a value for a key.
+     *
+     * @param string $key A unique key
+     *
+     * @return Boolean Whether the cache has a value for this key
+     */
+    public function has($key);
+
+    /**
+     * Returns the value for a key.
+     *
+     * @param string $key A unique key
+     *
+     * @return string|null The value in the cache
+     */
+    public function get($key);
+
+    /**
+     * Sets a value in the cache.
+     *
+     * @param string $key   A unique key
+     * @param string $value The value to cache
+     */
+    public function set($key, $value);
+
+    /**
+     * Removes a value from the cache.
+     *
+     * @param string $key A unique key
+     */
+    public function remove($key);
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ApcCache.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ApcCache.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/ApcCache.php	(revision 7265)
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Uses APC to cache files
+ *
+ * @author AndrÃ© Roaldseth <andre@roaldseth.net>
+ */
+class ApcCache implements CacheInterface
+{
+    public $ttl = 0;
+
+    /**
+     * @see CacheInterface::has()
+     */
+    public function has($key)
+    {
+        return apc_exists($key);
+    }
+
+    /**
+     * @see CacheInterface::get()
+     */
+    public function get($key)
+    {
+        $value = apc_fetch($key, $success);
+
+        if (!$success) {
+            throw new \RuntimeException('There is no cached value for ' . $key);
+        }
+
+        return $value;
+    }
+
+    /**
+     * @see CacheInterface::set()
+     */
+    public function set($key, $value)
+    {
+        $store = apc_store($key, $value, $this->ttl);
+
+        if (!$store) {
+            throw new \RuntimeException('Unable to store "' . $key . '" for ' . $this->ttl . ' seconds.');
+        }
+
+        return $store;
+    }
+
+    /**
+     * @see CacheInterface::remove()
+     */
+    public function remove($key)
+    {
+        return apc_delete($key);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/FilesystemCache.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/FilesystemCache.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Cache/FilesystemCache.php	(revision 7265)
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * A simple filesystem cache.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilesystemCache implements CacheInterface
+{
+    private $dir;
+
+    public function __construct($dir)
+    {
+        $this->dir = $dir;
+    }
+
+    public function has($key)
+    {
+        return file_exists($this->dir.'/'.$key);
+    }
+
+    public function get($key)
+    {
+        $path = $this->dir.'/'.$key;
+
+        if (!file_exists($path)) {
+            throw new \RuntimeException('There is no cached value for '.$key);
+        }
+
+        return file_get_contents($path);
+    }
+
+    public function set($key, $value)
+    {
+        if (!is_dir($this->dir) && false === @mkdir($this->dir, 0777, true)) {
+            throw new \RuntimeException('Unable to create directory '.$this->dir);
+        }
+
+        $path = $this->dir.'/'.$key;
+
+        if (false === @file_put_contents($path, $value)) {
+            throw new \RuntimeException('Unable to write file '.$path);
+        }
+    }
+
+    public function remove($key)
+    {
+        $path = $this->dir.'/'.$key;
+
+        if (file_exists($path) && false === @unlink($path)) {
+            throw new \RuntimeException('Unable to remove file '.$path);
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/BaseCssFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/BaseCssFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/BaseCssFilter.php	(revision 7265)
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+/**
+ * An abstract filter for dealing with CSS.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCssFilter implements FilterInterface
+{
+    /**
+     * Filters all references -- url() and "@import" -- through a callable.
+     *
+     * @param string   $content  The CSS
+     * @param callable $callback A PHP callable
+     * @param integer  $limit
+     * @param integer  $count
+     *
+     * @return string The filtered CSS
+     */
+    protected function filterReferences($content, $callback, $limit = -1, &$count = 0)
+    {
+        $content = $this->filterUrls($content, $callback, $limit, $count);
+        $content = $this->filterImports($content, $callback, $limit, $count, false);
+        $content = $this->filterIEFilters($content, $callback, $limit, $count);
+
+        return $content;
+    }
+
+    /**
+     * Filters all CSS url()'s through a callable.
+     *
+     * @param string   $content  The CSS
+     * @param callable $callback A PHP callable
+     * @param integer  $limit    Limit the number of replacements
+     * @param integer  $count    Will be populated with the count
+     *
+     * @return string The filtered CSS
+     */
+    protected function filterUrls($content, $callback, $limit = -1, &$count = 0)
+    {
+        return preg_replace_callback('/url\((["\']?)(?P<url>.*?)(\\1)\)/', $callback, $content, $limit, $count);
+    }
+
+    /**
+     * Filters all CSS imports through a callable.
+     *
+     * @param string   $content    The CSS
+     * @param callable $callback   A PHP callable
+     * @param integer  $limit      Limit the number of replacements
+     * @param integer  $count      Will be populated with the count
+     * @param Boolean  $includeUrl Whether to include url() in the pattern
+     *
+     * @return string The filtered CSS
+     */
+    protected function filterImports($content, $callback, $limit = -1, &$count = 0, $includeUrl = true)
+    {
+        $pattern = $includeUrl
+            ? '/@import (?:url\()?(\'|"|)(?P<url>[^\'"\)\n\r]*)\1\)?;?/'
+            : '/@import (?!url\()(\'|"|)(?P<url>[^\'"\)\n\r]*)\1;?/';
+
+        return preg_replace_callback($pattern, $callback, $content, $limit, $count);
+    }
+
+    /**
+     * Filters all IE filters (AlphaImageLoader filter) through a callable.
+     *
+     * @param string   $content  The CSS
+     * @param callable $callback A PHP callable
+     * @param integer  $limit    Limit the number of replacements
+     * @param integer  $count    Will be populated with the count
+     *
+     * @return string The filtered CSS
+     */
+    protected function filterIEFilters($content, $callback, $limit = -1, &$count = 0)
+    {
+        return preg_replace_callback('/src=(["\']?)(?<url>.*?)\\1/', $callback, $content, $limit, $count);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinPlusFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinPlusFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinPlusFilter.php	(revision 7265)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through JSMinPlus.
+ *
+ * All credit for the filter itself is mentioned in the file itself.
+ *
+ * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMinPlus.php
+ * @author Brunoais <brunoaiss@gmail.com>
+ */
+class JSMinPlusFilter implements FilterInterface
+{
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $asset->setContent(\JSMinPlus::minify($asset->getContent()));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssEmbedFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssEmbedFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssEmbedFilter.php	(revision 7265)
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * CSSEmbed filter
+ *
+ * @link https://github.com/nzakas/cssembed
+ * @author Maxime Thirouin <maxime.thirouin@gmail.com>
+ */
+class CssEmbedFilter implements FilterInterface
+{
+    private $jarPath;
+    private $javaPath;
+    private $charset;
+    private $mhtml; // Enable MHTML mode.
+    private $mhtmlRoot; // Use <root> as the MHTML root for the file.
+    private $root; // Prepends <root> to all relative URLs.
+    private $skipMissing; // Don't throw an error for missing image files.
+    private $maxUriLength; // Maximum length for a data URI. Defaults to 32768.
+    private $maxImageSize; // Maximum image size (in bytes) to convert.
+
+    public function __construct($jarPath, $javaPath = '/usr/bin/java')
+    {
+        $this->jarPath = $jarPath;
+        $this->javaPath = $javaPath;
+    }
+
+    public function setCharset($charset)
+    {
+        $this->charset = $charset;
+    }
+
+    public function setMhtml($mhtml)
+    {
+        $this->mhtml = $mhtml;
+    }
+
+    public function setMhtmlRoot($mhtmlRoot)
+    {
+        $this->mhtmlRoot = $mhtmlRoot;
+    }
+
+    public function setRoot($root)
+    {
+        $this->root = $root;
+    }
+
+    public function setSkipMissing($skipMissing)
+    {
+        $this->skipMissing = $skipMissing;
+    }
+
+    public function setMaxUriLength($maxUriLength)
+    {
+        $this->maxUriLength = $maxUriLength;
+    }
+
+    public function setMaxImageSize($maxImageSize)
+    {
+        $this->maxImageSize = $maxImageSize;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $pb = new ProcessBuilder(array(
+            $this->javaPath,
+            '-jar',
+            $this->jarPath,
+        ));
+
+        if (null !== $this->charset) {
+            $pb->add('--charset')->add($this->charset);
+        }
+
+        if ($this->mhtml) {
+            $pb->add('--mhtml');
+        }
+
+        if (null !== $this->mhtmlRoot) {
+            $pb->add('--mhtmlroot')->add($this->mhtmlRoot);
+        }
+
+        // automatically define root if not already defined
+        if (null === $this->root) {
+            $root = $asset->getSourceRoot();
+            $path = $asset->getSourcePath();
+
+            if ($root && $path) {
+                $pb->add('--root')->add(dirname($root.'/'.$path));
+            }
+        } else {
+            $pb->add('--root')->add($this->root);
+        }
+
+        if ($this->skipMissing) {
+            $pb->add('--skip-missing');
+        }
+
+        if (null !== $this->maxUriLength) {
+            $pb->add('--max-uri-length')->add($this->maxUriLength);
+        }
+
+        if (null !== $this->maxImageSize) {
+            $pb->add('--max-image-size')->add($this->maxImageSize);
+        }
+
+        // input
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_cssembed'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyJsFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyJsFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyJsFilter.php	(revision 7265)
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * UglifyJs filter.
+ *
+ * @link https://github.com/mishoo/UglifyJS
+ * @author AndrÃ© Roaldseth <andre@roaldseth.net>
+ */
+class UglifyJsFilter implements FilterInterface
+{
+    private $uglifyJsPath;
+    private $nodeJsPath;
+
+    private $noCopyright;
+    private $beautify;
+    private $unsafe;
+
+    /**
+     * @param string $uglifyJsPath Absolute path to the uglifyjs executable
+     * @param string $nodeJsPath   Absolute path to the folder containg node.js executable
+     */
+    public function __construct($uglifyJsPath, $nodeJsPath = null)
+    {
+        $this->uglifyJsPath = $uglifyJsPath;
+        $this->nodeJsPath = $nodeJsPath;
+    }
+
+    /**
+     * Removes the first block of comments as well
+     * @param bool $noCopyright True to enable
+     */
+    public function setNoCopyright($noCopyright)
+    {
+        $this->noCopyright = $noCopyright;
+    }
+
+    /**
+     * Output indented code
+     * @param bool $beautify True to enable
+     */
+    public function setBeautify($beautify)
+    {
+        $this->beautify = $beautify;
+    }
+
+    /**
+     * Enable additional optimizations that are known to be unsafe in some situations.
+     * @param bool $unsafe True to enable
+     */
+    public function setUnsafe($unsafe)
+    {
+        $this->unsafe = $unsafe;
+    }
+
+    /**
+     * @see Assetic\Filter\FilterInterface::filterLoad()
+     */
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    /**
+     * Run the asset through UglifyJs
+     *
+     * @see Assetic\Filter\FilterInterface::filterDump()
+     */
+    public function filterDump(AssetInterface $asset)
+    {
+        $executables = array();
+
+        if ($this->nodeJsPath !== null) {
+            $executables[] = $this->nodeJsPath;
+        }
+
+        $executables[] = $this->uglifyJsPath;
+
+        $pb = new ProcessBuilder($executables);
+
+        if ($this->noCopyright) {
+            $pb->add('--no-copyright');
+        }
+
+        if ($this->beautify) {
+            $pb->add('--beautify');
+        }
+
+        if ($this->unsafe) {
+            $pb->add('--unsafe');
+        }
+
+        // input and output files
+        $input = tempnam(sys_get_temp_dir(), 'input');
+        $output = tempnam(sys_get_temp_dir(), 'output');
+
+        file_put_contents($input, $asset->getContent());
+        $pb->add('-o')->add($output)->add($input);
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            if (file_exists($output)) {
+                unlink($output);
+            }
+
+            if (127 === $code) {
+                throw new \RuntimeException('Path to node executable could not be resolved.');
+            }
+
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        if (!file_exists($output)) {
+            throw new \RuntimeException('Error creating output file.');
+        }
+
+        $uglifiedJs = file_get_contents($output);
+        unlink($output);
+
+        $asset->setContent($uglifiedJs);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GssFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GssFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GssFilter.php	(revision 7265)
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Filter for the Google Closure Stylesheets Compiler JAR.
+ *
+ * @link http://code.google.com/p/closure-stylesheets/
+ * @author Matthias Krauser <matthias@krauser.eu>
+ */
+class GssFilter implements FilterInterface
+{
+    private $jarPath;
+    private $javaPath;
+    private $allowUnrecognizedFunctions;
+    private $allowedNonStandardFunctions;
+    private $copyrightNotice;
+    private $define;
+    private $gssFunctionMapProvider;
+    private $inputOrientation;
+    private $outputOrientation;
+    private $prettyPrint;
+
+    public function __construct($jarPath, $javaPath = '/usr/bin/java')
+    {
+        $this->jarPath = $jarPath;
+        $this->javaPath = $javaPath;
+    }
+
+    public function setAllowUnrecognizedFunctions($allowUnrecognizedFunctions)
+    {
+        $this->allowUnrecognizedFunctions = $allowUnrecognizedFunctions;
+    }
+
+    public function setAllowedNonStandardFunctions($allowNonStandardFunctions)
+    {
+        $this->allowedNonStandardFunctions = $allowNonStandardFunctions;
+    }
+
+    public function setCopyrightNotice($copyrightNotice)
+    {
+        $this->copyrightNotice = $copyrightNotice;
+    }
+
+    public function setDefine($define)
+    {
+        $this->define = $define;
+    }
+
+    public function setGssFunctionMapProvider($gssFunctionMapProvider)
+    {
+        $this->gssFunctionMapProvider = $gssFunctionMapProvider;
+    }
+
+    public function setInputOrientation($inputOrientation)
+    {
+        $this->inputOrientation = $inputOrientation;
+    }
+
+    public function setOutputOrientation($outputOrientation)
+    {
+        $this->outputOrientation = $outputOrientation;
+    }
+
+    public function setPrettyPrint($prettyPrint)
+    {
+        $this->prettyPrint = $prettyPrint;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $cleanup = array();
+
+        $pb = new ProcessBuilder(array(
+            $this->javaPath,
+            '-jar',
+            $this->jarPath,
+        ));
+
+        if (null !== $this->allowUnrecognizedFunctions) {
+            $pb->add('--allow-unrecognized-functions');
+        }
+
+        if (null !== $this->allowedNonStandardFunctions) {
+            $pb->add('--allowed_non_standard_functions')->add($this->allowedNonStandardFunctions);
+        }
+
+        if (null !== $this->copyrightNotice) {
+            $pb->add('--copyright-notice')->add($this->copyrightNotice);
+        }
+
+        if (null !== $this->define) {
+            $pb->add('--define')->add($this->define);
+        }
+
+        if (null !== $this->gssFunctionMapProvider) {
+            $pb->add('--gss-function-map-provider')->add($this->gssFunctionMapProvider);
+        }
+
+        if (null !== $this->inputOrientation) {
+            $pb->add('--input-orientation')->add($this->inputOrientation);
+        }
+
+        if (null !== $this->outputOrientation) {
+            $pb->add('--output-orientation')->add($this->outputOrientation);
+        }
+
+        if (null !== $this->prettyPrint) {
+            $pb->add('--pretty-print');
+        }
+
+        $pb->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_stylesheets_compiler'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        array_map('unlink', $cleanup);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterInterface.php	(revision 7265)
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A filter manipulates an asset at load and dump.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface FilterInterface
+{
+    /**
+     * Filters an asset after it has been loaded.
+     *
+     * @param AssetInterface $asset An asset
+     */
+    public function filterLoad(AssetInterface $asset);
+
+    /**
+     * Filters an asset just before it's dumped.
+     *
+     * @param AssetInterface $asset An asset
+     */
+    public function filterDump(AssetInterface $asset);
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackerFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackerFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackerFilter.php	(revision 7265)
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Runs assets through Packager, a JavaScript Compressor/Obfuscator.
+ *
+ * PHP Version of the Dean Edwards's Packer, ported by Nicolas Martin.
+ *
+ * @link http://joliclic.free.fr/php/javascript-packer/en/
+ * @author Maximilian Walter <github@max-walter.net>
+ */
+class PackerFilter implements FilterInterface
+{
+    protected $encoding = 'None';
+
+    protected $fastDecode = true;
+
+    protected $specialChars = false;
+
+    public function setEncoding($encoding)
+    {
+        $this->encoding = $encoding;
+    }
+
+    public function setFastDecode($fastDecode)
+    {
+        $this->fastDecode = (bool) $fastDecode;
+    }
+
+    public function setSpecialChars($specialChars)
+    {
+        $this->specialChars = (bool) $specialChars;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $packer = new \JavaScriptPacker($asset->getContent(), $this->encoding, $this->fastDecode, $this->specialChars);
+        $asset->setContent($packer->pack());
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CompassFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CompassFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CompassFilter.php	(revision 7265)
@@ -0,0 +1,376 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Exception\FilterException;
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Loads Compass files.
+ *
+ * @link http://compass-style.org/
+ * @author Maxime Thirouin <maxime.thirouin@gmail.com>
+ */
+class CompassFilter implements FilterInterface
+{
+    private $compassPath;
+    private $rubyPath;
+    private $scss;
+
+    // sass options
+    private $unixNewlines;
+    private $debugInfo;
+    private $cacheLocation;
+    private $noCache;
+
+    // compass options
+    private $force;
+    private $style;
+    private $quiet;
+    private $boring;
+    private $noLineComments;
+    private $imagesDir;
+    private $javascriptsDir;
+
+    // compass configuration file options
+    private $plugins = array();
+    private $loadPaths = array();
+    private $httpPath;
+    private $httpImagesPath;
+    private $httpGeneratedImagesPath;
+    private $generatedImagesPath;
+    private $httpJavascriptsPath;
+    private $homeEnv = true;
+
+    public function __construct($compassPath = '/usr/bin/compass', $rubyPath = null)
+    {
+        $this->compassPath = $compassPath;
+        $this->rubyPath = $rubyPath;
+        $this->cacheLocation = sys_get_temp_dir();
+
+        if ('cli' !== php_sapi_name()) {
+            $this->boring = true;
+        }
+    }
+
+    public function setScss($scss)
+    {
+        $this->scss = $scss;
+    }
+
+    // sass options setters
+    public function setUnixNewlines($unixNewlines)
+    {
+        $this->unixNewlines = $unixNewlines;
+    }
+
+    public function setDebugInfo($debugInfo)
+    {
+        $this->debugInfo = $debugInfo;
+    }
+
+    public function setCacheLocation($cacheLocation)
+    {
+        $this->cacheLocation = $cacheLocation;
+    }
+
+    public function setNoCache($noCache)
+    {
+        $this->noCache = $noCache;
+    }
+
+    // compass options setters
+    public function setForce($force)
+    {
+        $this->force = $force;
+    }
+
+    public function setStyle($style)
+    {
+        $this->style = $style;
+    }
+
+    public function setQuiet($quiet)
+    {
+        $this->quiet = $quiet;
+    }
+
+    public function setBoring($boring)
+    {
+        $this->boring = $boring;
+    }
+
+    public function setNoLineComments($noLineComments)
+    {
+        $this->noLineComments = $noLineComments;
+    }
+
+    public function setImagesDir($imagesDir)
+    {
+        $this->imagesDir = $imagesDir;
+    }
+
+    public function setJavascriptsDir($javascriptsDir)
+    {
+        $this->javascriptsDir = $javascriptsDir;
+    }
+
+    // compass configuration file options setters
+    public function setPlugins(array $plugins)
+    {
+        $this->plugins = $plugins;
+    }
+
+    public function addPlugin($plugin)
+    {
+        $this->plugins[] = $plugin;
+    }
+
+    public function setLoadPaths(array $loadPaths)
+    {
+        $this->loadPaths = $loadPaths;
+    }
+
+    public function addLoadPath($loadPath)
+    {
+        $this->loadPaths[] = $loadPath;
+    }
+
+    public function setHttpPath($httpPath)
+    {
+        $this->httpPath = $httpPath;
+    }
+
+    public function setHttpImagesPath($httpImagesPath)
+    {
+        $this->httpImagesPath = $httpImagesPath;
+    }
+
+    public function setHttpGeneratedImagesPath($httpGeneratedImagesPath)
+    {
+        $this->httpGeneratedImagesPath = $httpGeneratedImagesPath;
+    }
+
+    public function setGeneratedImagesPath($generatedImagesPath)
+    {
+        $this->generatedImagesPath = $generatedImagesPath;
+    }
+
+    public function setHttpJavascriptsPath($httpJavascriptsPath)
+    {
+        $this->httpJavascriptsPath = $httpJavascriptsPath;
+    }
+
+    public function setHomeEnv($homeEnv)
+    {
+        $this->homeEnv = $homeEnv;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        $loadPaths = $this->loadPaths;
+        if ($root && $path) {
+            $loadPaths[] = dirname($root.'/'.$path);
+        }
+
+        // compass does not seems to handle symlink, so we use realpath()
+        $tempDir = realpath(sys_get_temp_dir());
+
+        $compassProcessArgs = array(
+            $this->compassPath,
+            'compile',
+            $tempDir,
+        );
+        if (null !== $this->rubyPath) {
+            $compassProcessArgs = array_merge(explode(' ', $this->rubyPath), $compassProcessArgs);
+        }
+
+        $pb = new ProcessBuilder($compassProcessArgs);
+        $pb->inheritEnvironmentVariables();
+
+        if ($this->force) {
+            $pb->add('--force');
+        }
+
+        if ($this->style) {
+            $pb->add('--output-style')->add($this->style);
+        }
+
+        if ($this->quiet) {
+            $pb->add('--quiet');
+        }
+
+        if ($this->boring) {
+            $pb->add('--boring');
+        }
+
+        if ($this->noLineComments) {
+            $pb->add('--no-line-comments');
+        }
+
+        // these two options are not passed into the config file
+        // because like this, compass adapts this to be xxx_dir or xxx_path
+        // whether it's an absolute path or not
+        if ($this->imagesDir) {
+            $pb->add('--images-dir')->add($this->imagesDir);
+        }
+
+        if ($this->javascriptsDir) {
+            $pb->add('--javascripts-dir')->add($this->javascriptsDir);
+        }
+
+        // options in config file
+        $optionsConfig = array();
+
+        if (!empty($loadPaths)) {
+            $optionsConfig['additional_import_paths'] = $loadPaths;
+        }
+
+        if ($this->unixNewlines) {
+            $optionsConfig['sass_options']['unix_newlines'] = true;
+        }
+
+        if ($this->debugInfo) {
+            $optionsConfig['sass_options']['debug_info'] = true;
+        }
+
+        if ($this->cacheLocation) {
+            $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation;
+        }
+
+        if ($this->noCache) {
+            $optionsConfig['sass_options']['no_cache'] = true;
+        }
+
+        if ($this->httpPath) {
+            $optionsConfig['http_path'] = $this->httpPath;
+        }
+
+        if ($this->httpImagesPath) {
+            $optionsConfig['http_images_path'] = $this->httpImagesPath;
+        }
+
+        if ($this->httpGeneratedImagesPath) {
+            $optionsConfig['http_generated_images_path'] = $this->httpGeneratedImagesPath;
+        }
+
+        if ($this->generatedImagesPath) {
+            $optionsConfig['generated_images_path'] = $this->generatedImagesPath;
+        }
+
+        if ($this->httpJavascriptsPath) {
+            $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath;
+        }
+
+        // options in configuration file
+        if (count($optionsConfig)) {
+            $config = array();
+            foreach ($this->plugins as $plugin) {
+                $config[] = sprintf("require '%s'", addcslashes($plugin, '\\'));
+            }
+            foreach ($optionsConfig as $name => $value) {
+                if (!is_array($value)) {
+                    $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\'));
+                } elseif (!empty($value)) {
+                    $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value));
+                }
+            }
+
+            $configFile = tempnam($tempDir, 'assetic_compass');
+            file_put_contents($configFile, implode("\n", $config)."\n");
+            $pb->add('--config')->add($configFile);
+        }
+
+        $pb->add('--sass-dir')->add('')->add('--css-dir')->add('');
+
+        // compass choose the type (sass or scss from the filename)
+        if (null !== $this->scss) {
+            $type = $this->scss ? 'scss' : 'sass';
+        } elseif ($path) {
+            // FIXME: what if the extension is something else?
+            $type = pathinfo($path, PATHINFO_EXTENSION);
+        } else {
+            $type = 'scss';
+        }
+
+        $tempName = tempnam($tempDir, 'assetic_compass');
+        unlink($tempName); // FIXME: don't use tempnam() here
+
+        // input
+        $input = $tempName.'.'.$type;
+
+        // work-around for https://github.com/chriseppstein/compass/issues/748
+        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+            $input = str_replace('\\', '/', $input);
+        }
+
+        $pb->add($input);
+        file_put_contents($input, $asset->getContent());
+
+        // output
+        $output = $tempName.'.css';
+
+        if ($this->homeEnv) {
+            // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376
+            $pb->setEnv('HOME', sys_get_temp_dir());
+        }
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+
+        if (0 < $code) {
+            unlink($input);
+            if (isset($configFile)) {
+                unlink($configFile);
+            }
+
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent(file_get_contents($output));
+
+        unlink($input);
+        unlink($output);
+        if (isset($configFile)) {
+            unlink($configFile);
+        }
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+
+    private function formatArrayToRuby($array)
+    {
+        $output = array();
+
+        // does we have an associative array ?
+        if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) {
+            foreach ($array as $name => $value) {
+                $output[] = sprintf('    :%s => "%s"', $name, addcslashes($value, '\\'));
+            }
+            $output = "{\n".implode(",\n", $output)."\n}";
+        } else {
+            foreach ($array as $name => $value) {
+                $output[] = sprintf('    "%s"', addcslashes($value, '\\'));
+            }
+            $output = "[\n".implode(",\n", $output)."\n]";
+        }
+
+        return $output;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyCssFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyCssFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/UglifyCssFilter.php	(revision 7265)
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * UglifyCss filter.
+ *
+ * @link https://github.com/fmarcia/UglifyCSS
+ * @author Franck Marcia <franck.marcia@gmail.com>
+ */
+class UglifyCssFilter implements FilterInterface
+{
+    private $uglifyCssPath;
+    private $nodeJsPath;
+
+    private $expandVars;
+    private $uglyComments;
+    private $cuteComments;
+
+    /**
+     * @param string $uglifyCssPath Absolute path to the uglifycss executable
+     * @param string $nodeJsPath Absolute path to the folder containg node.js executable
+     */
+    public function __construct($uglifyCssPath, $nodeJsPath = null)
+    {
+        $this->uglifyCssPath = $uglifyCssPath;
+        $this->nodeJsPath = $nodeJsPath;
+    }
+
+    /**
+     * Expand variables
+     * @param bool $expandVars True to enable
+     */
+    public function setExpandVars($expandVars)
+    {
+        $this->expandVars = $expandVars;
+    }
+
+    /**
+     * Remove newlines within preserved comments
+     * @param bool $uglyComments True to enable
+     */
+    public function setUglyComments($uglyComments)
+    {
+        $this->uglyComments = $uglyComments;
+    }
+
+    /**
+     * Preserve newlines within and around preserved comments
+     * @param bool $cuteComments True to enable
+     */
+    public function setCuteComments($cuteComments)
+    {
+        $this->cuteComments = $cuteComments;
+    }
+
+    /**
+     * @see Assetic\Filter\FilterInterface::filterLoad()
+     */
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    /**
+     * Run the asset through UglifyJs
+     *
+     * @see Assetic\Filter\FilterInterface::filterDump()
+     */
+    public function filterDump(AssetInterface $asset)
+    {
+        $executables = array();
+
+        if ($this->nodeJsPath !== null) {
+            $executables[] = $this->nodeJsPath;
+        }
+
+        $executables[] = $this->uglifyCssPath;
+
+        $pb = new ProcessBuilder($executables);
+
+        if ($this->expandVars) {
+            $pb->add('--expand-vars');
+        }
+
+        if ($this->uglyComments) {
+            $pb->add('--ugly-comments');
+        }
+
+        if ($this->cuteComments) {
+            $pb->add('--cute-comments');
+        }
+
+        // input and output files
+        $input = tempnam(sys_get_temp_dir(), 'input');
+
+        file_put_contents($input, $asset->getContent());
+        $pb->add($input);
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (127 === $code) {
+            throw new \RuntimeException('Path to node executable could not be resolved.');
+        }
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/CssCompressorFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/CssCompressorFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/CssCompressorFilter.php	(revision 7265)
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * CSS YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssCompressorFilter extends BaseCompressorFilter
+{
+    public function filterDump(AssetInterface $asset)
+    {
+        $asset->setContent($this->compress($asset->getContent(), 'css'));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/BaseCompressorFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/BaseCompressorFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/BaseCompressorFilter.php	(revision 7265)
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Base YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCompressorFilter implements FilterInterface
+{
+    private $jarPath;
+    private $javaPath;
+    private $charset;
+    private $lineBreak;
+
+    public function __construct($jarPath, $javaPath = '/usr/bin/java')
+    {
+        $this->jarPath = $jarPath;
+        $this->javaPath = $javaPath;
+    }
+
+    public function setCharset($charset)
+    {
+        $this->charset = $charset;
+    }
+
+    public function setLineBreak($lineBreak)
+    {
+        $this->lineBreak = $lineBreak;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    /**
+     * Compresses a string.
+     *
+     * @param string $content The content to compress
+     * @param string $type    The type of content, either "js" or "css"
+     * @param array  $options An indexed array of additional options
+     *
+     * @return string The compressed content
+     */
+    protected function compress($content, $type, $options = array())
+    {
+        $pb = new ProcessBuilder(array(
+            $this->javaPath,
+            '-jar',
+            $this->jarPath,
+        ));
+
+        foreach ($options as $option) {
+            $pb->add($option);
+        }
+
+        if (null !== $this->charset) {
+            $pb->add('--charset')->add($this->charset);
+        }
+
+        if (null !== $this->lineBreak) {
+            $pb->add('--line-break')->add($this->lineBreak);
+        }
+
+        // input and output files
+        $tempDir = realpath(sys_get_temp_dir());
+        $input = tempnam($tempDir, 'YUI-IN-');
+        $output = tempnam($tempDir, 'YUI-OUT-');
+        file_put_contents($input, $content);
+        $pb->add('-o')->add($output)->add('--type')->add($type)->add($input);
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            if (file_exists($output)) {
+                unlink($output);
+            }
+
+            throw FilterException::fromProcess($proc)->setInput($content);
+        }
+
+        if (!file_exists($output)) {
+            throw new \RuntimeException('Error creating output file.');
+        }
+
+        $retval = file_get_contents($output);
+        unlink($output);
+
+        return $retval;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/JsCompressorFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/JsCompressorFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Yui/JsCompressorFilter.php	(revision 7265)
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Javascript YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JsCompressorFilter extends BaseCompressorFilter
+{
+    private $nomunge;
+    private $preserveSemi;
+    private $disableOptimizations;
+
+    public function setNomunge($nomunge = true)
+    {
+        $this->nomunge = $nomunge;
+    }
+
+    public function setPreserveSemi($preserveSemi)
+    {
+        $this->preserveSemi = $preserveSemi;
+    }
+
+    public function setDisableOptimizations($disableOptimizations)
+    {
+        $this->disableOptimizations = $disableOptimizations;
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $options = array();
+
+        if ($this->nomunge) {
+            $options[] = '--nomunge';
+        }
+
+        if ($this->preserveSemi) {
+            $options[] = '--preserve-semi';
+        }
+
+        if ($this->disableOptimizations) {
+            $options[] = '--disable-optimizations';
+        }
+
+        $asset->setContent($this->compress($asset->getContent(), 'js', $options));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CoffeeScriptFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CoffeeScriptFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CoffeeScriptFilter.php	(revision 7265)
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Compiles CoffeeScript into Javascript.
+ *
+ * @link http://coffeescript.org/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CoffeeScriptFilter implements FilterInterface
+{
+    private $coffeePath;
+    private $nodePath;
+
+    // coffee options
+    private $bare;
+
+    public function __construct($coffeePath = '/usr/bin/coffee', $nodePath = '/usr/bin/node')
+    {
+        $this->coffeePath = $coffeePath;
+        $this->nodePath = $nodePath;
+    }
+
+    public function setBare($bare)
+    {
+        $this->bare = $bare;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $input = tempnam(sys_get_temp_dir(), 'assetic_coffeescript');
+        file_put_contents($input, $asset->getContent());
+
+        $pb = new ProcessBuilder(array(
+            $this->nodePath,
+            $this->coffeePath,
+            '-cp',
+        ));
+
+        if ($this->bare) {
+            $pb->add('--bare');
+        }
+
+        $pb->add($input);
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/SassFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/SassFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/SassFilter.php	(revision 7265)
@@ -0,0 +1,176 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Sass;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Loads SASS files.
+ *
+ * @link http://sass-lang.com/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class SassFilter implements FilterInterface
+{
+    const STYLE_NESTED     = 'nested';
+    const STYLE_EXPANDED   = 'expanded';
+    const STYLE_COMPACT    = 'compact';
+    const STYLE_COMPRESSED = 'compressed';
+
+    private $sassPath;
+    private $rubyPath;
+    private $unixNewlines;
+    private $scss;
+    private $style;
+    private $quiet;
+    private $debugInfo;
+    private $lineNumbers;
+    private $loadPaths = array();
+    private $cacheLocation;
+    private $noCache;
+    private $compass;
+
+    public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
+    {
+        $this->sassPath = $sassPath;
+        $this->rubyPath = $rubyPath;
+        $this->cacheLocation = realpath(sys_get_temp_dir());
+    }
+
+    public function setUnixNewlines($unixNewlines)
+    {
+        $this->unixNewlines = $unixNewlines;
+    }
+
+    public function setScss($scss)
+    {
+        $this->scss = $scss;
+    }
+
+    public function setStyle($style)
+    {
+        $this->style = $style;
+    }
+
+    public function setQuiet($quiet)
+    {
+        $this->quiet = $quiet;
+    }
+
+    public function setDebugInfo($debugInfo)
+    {
+        $this->debugInfo = $debugInfo;
+    }
+
+    public function setLineNumbers($lineNumbers)
+    {
+        $this->lineNumbers = $lineNumbers;
+    }
+
+    public function addLoadPath($loadPath)
+    {
+        $this->loadPaths[] = $loadPath;
+    }
+
+    public function setCacheLocation($cacheLocation)
+    {
+        $this->cacheLocation = $cacheLocation;
+    }
+
+    public function setNoCache($noCache)
+    {
+        $this->noCache = $noCache;
+    }
+
+    public function setCompass($compass)
+    {
+        $this->compass = $compass;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $sassProcessArgs = array($this->sassPath);
+        if (null !== $this->rubyPath) {
+            $sassProcessArgs = array_merge(explode(' ', $this->rubyPath), $sassProcessArgs);
+        }
+
+        $pb = new ProcessBuilder($sassProcessArgs);
+
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        if ($root && $path) {
+            $pb->add('--load-path')->add(dirname($root.'/'.$path));
+        }
+
+        if ($this->unixNewlines) {
+            $pb->add('--unix-newlines');
+        }
+
+        if (true === $this->scss || (null === $this->scss && 'scss' == pathinfo($path, PATHINFO_EXTENSION))) {
+            $pb->add('--scss');
+        }
+
+        if ($this->style) {
+            $pb->add('--style')->add($this->style);
+        }
+
+        if ($this->quiet) {
+            $pb->add('--quiet');
+        }
+
+        if ($this->debugInfo) {
+            $pb->add('--debug-info');
+        }
+
+        if ($this->lineNumbers) {
+            $pb->add('--line-numbers');
+        }
+
+        foreach ($this->loadPaths as $loadPath) {
+            $pb->add('--load-path')->add($loadPath);
+        }
+
+        if ($this->cacheLocation) {
+            $pb->add('--cache-location')->add($this->cacheLocation);
+        }
+
+        if ($this->noCache) {
+            $pb->add('--no-cache');
+        }
+
+        if ($this->compass) {
+            $pb->add('--compass');
+        }
+
+        // input
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_sass'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/ScssFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/ScssFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/Sass/ScssFilter.php	(revision 7265)
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Sass;
+
+/**
+ * Loads SCSS files.
+ *
+ * @link http://sass-lang.com/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ScssFilter extends SassFilter
+{
+    public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
+    {
+        parent::__construct($sassPath, $rubyPath);
+
+        $this->setScss(true);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessphpFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessphpFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessphpFilter.php	(revision 7265)
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Loads LESS files using the PHP implementation of less, lessphp.
+ *
+ * Less files are mostly compatible, but there are slight differences.
+ *
+ * @link http://leafo.net/lessphp/
+ *
+ * @author David Buchmann <david@liip.ch>
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LessphpFilter implements FilterInterface
+{
+    private $presets = array();
+
+    /**
+     * Lessphp Load Paths
+     * 
+     * @var array
+     */
+    protected $loadPaths = array();
+
+    /**
+     * Adds a load path to the paths used by lessphp
+     * 
+     * @param string $path Load Path
+     */
+    public function addLoadPath($path)
+    {
+        $this->loadPaths[] = $path;
+    }
+
+    public function setPresets(array $presets)
+    {
+        $this->presets = $presets;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        $lc = new \lessc();
+        if ($root && $path) {
+            $lc->importDir = dirname($root.'/'.$path);
+        }
+        foreach ($this->loadPaths as $loadPath) {
+            $lc->addImportDir($loadPath);
+        }
+
+        $asset->setContent($lc->parse($asset->getContent(), $this->presets));
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/OptiPngFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/OptiPngFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/OptiPngFilter.php	(revision 7265)
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Runs assets through OptiPNG.
+ *
+ * @link   http://optipng.sourceforge.net/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class OptiPngFilter implements FilterInterface
+{
+    private $optipngBin;
+    private $level;
+
+    /**
+     * Constructor.
+     *
+     * @param string $optipngBin Path to the optipng binary
+     */
+    public function __construct($optipngBin = '/usr/bin/optipng')
+    {
+        $this->optipngBin = $optipngBin;
+    }
+
+    public function setLevel($level)
+    {
+        $this->level = $level;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $pb = new ProcessBuilder(array($this->optipngBin));
+
+        if (null !== $this->level) {
+            $pb->add('-o')->add($this->level);
+        }
+
+        $pb->add('-out')->add($output = tempnam(sys_get_temp_dir(), 'assetic_optipng'));
+        unlink($output);
+
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_optipng'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+
+        if (0 < $code) {
+            unlink($input);
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent(file_get_contents($output));
+
+        unlink($input);
+        unlink($output);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HashableInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HashableInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HashableInterface.php	(revision 7265)
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+/**
+ * A filter can implement a hash function
+ *
+ * @author Francisco Facioni <fran6co@gmail.com>
+ */
+interface HashableInterface
+{
+    /**
+     * Generates a hash for the object
+     *
+     * @return string Object hash
+     */
+    public function hash();
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssImportFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssImportFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssImportFilter.php	(revision 7265)
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\HttpAsset;
+
+/**
+ * Inlines imported stylesheets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssImportFilter extends BaseCssFilter
+{
+    private $importFilter;
+
+    /**
+     * Constructor.
+     *
+     * @param FilterInterface $importFilter Filter for each imported asset
+     */
+    public function __construct(FilterInterface $importFilter = null)
+    {
+        $this->importFilter = $importFilter ?: new CssRewriteFilter();
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $importFilter = $this->importFilter;
+        $sourceRoot = $asset->getSourceRoot();
+        $sourcePath = $asset->getSourcePath();
+
+        $callback = function($matches) use ($importFilter, $sourceRoot, $sourcePath) {
+            if (!$matches['url'] || null === $sourceRoot) {
+                return $matches[0];
+            }
+
+            $importRoot = $sourceRoot;
+
+            if (false !== strpos($matches['url'], '://')) {
+                // absolute
+                list($importScheme, $tmp) = explode('://', $matches['url'], 2);
+                list($importHost, $importPath) = explode('/', $tmp, 2);
+                $importRoot = $importScheme.'://'.$importHost;
+            } elseif (0 === strpos($matches['url'], '//')) {
+                // protocol-relative
+                list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2);
+                $importHost = '//'.$importHost;
+            } elseif ('/' == $matches['url'][0]) {
+                // root-relative
+                $importPath = substr($matches['url'], 1);
+            } elseif (null !== $sourcePath) {
+                // document-relative
+                $importPath = $matches['url'];
+                if ('.' != $sourceDir = dirname($sourcePath)) {
+                    $importPath = $sourceDir.'/'.$importPath;
+                }
+            } else {
+                return $matches[0];
+            }
+
+            // ignore other imports
+            if ('css' != pathinfo($importPath, PATHINFO_EXTENSION)) {
+                return $matches[0];
+            }
+
+            $importSource = $importRoot.'/'.$importPath;
+            if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) {
+                $import = new HttpAsset($importSource, array($importFilter), true);
+            } elseif (!file_exists($importSource)) {
+                // ignore not found imports
+                return $matches[0];
+            } else {
+                $import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath);
+            }
+
+            $import->setTargetPath($sourcePath);
+
+            return $import->dump();
+        };
+
+        $content = $asset->getContent();
+        $lastHash = md5($content);
+
+        do {
+            $content = $this->filterImports($content, $callback);
+            $hash = md5($content);
+        } while ($lastHash != $hash && $lastHash = $hash);
+
+        $asset->setContent($content);
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/ScssphpFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/ScssphpFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/ScssphpFilter.php	(revision 7265)
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Loads SCSS files using the PHP implementation of scss, scssphp.
+ *
+ * Scss files are mostly compatible, but there are slight differences.
+ *
+ * @link http://leafo.net/scssphp/
+ *
+ * @author Bart van den Burg <bart@samson-it.nl>
+ */
+class ScssphpFilter implements FilterInterface
+{
+    private $compass = false;
+
+    public function enableCompass($enable = true)
+    {
+        $this->compass = (Boolean) $enable;
+    }
+
+    public function isCompassEnabled()
+    {
+        return $this->compass;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        $lc = new \scssc();
+        if ($this->compass) {
+            new \scss_compass($lc);
+        }
+        if ($root && $path) {
+            $lc->addImportPath(dirname($root.'/'.$path));
+        }
+
+        $asset->setContent($lc->compile($asset->getContent()));
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssRewriteFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssRewriteFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssRewriteFilter.php	(revision 7265)
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Fixes relative CSS urls.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssRewriteFilter extends BaseCssFilter
+{
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $sourceBase = $asset->getSourceRoot();
+        $sourcePath = $asset->getSourcePath();
+        $targetPath = $asset->getTargetPath();
+
+        if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) {
+            return;
+        }
+
+        // learn how to get from the target back to the source
+        if (false !== strpos($sourceBase, '://')) {
+            list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2);
+            list($host, $path) = explode('/', $url, 2);
+
+            $host = $scheme.'://'.$host.'/';
+            $path = false === strpos($path, '/') ? '' : dirname($path);
+            $path .= '/';
+        } else {
+            // assume source and target are on the same host
+            $host = '';
+
+            // pop entries off the target until it fits in the source
+            if ('.' == dirname($sourcePath)) {
+                $path = str_repeat('../', substr_count($targetPath, '/'));
+            } elseif ('.' == $targetDir = dirname($targetPath)) {
+                $path = dirname($sourcePath).'/';
+            } else {
+                $path = '';
+                while (0 !== strpos($sourcePath, $targetDir)) {
+                    if (false !== $pos = strrpos($targetDir, '/')) {
+                        $targetDir = substr($targetDir, 0, $pos);
+                        $path .= '../';
+                    } else {
+                        $targetDir = '';
+                        $path .= '../';
+                        break;
+                    }
+                }
+                $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/');
+            }
+        }
+
+        $content = $this->filterReferences($asset->getContent(), function($matches) use ($host, $path) {
+            if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) {
+                // absolute or protocol-relative or data uri
+                return $matches[0];
+            }
+
+            if ('/' == $matches['url'][0]) {
+                // root relative
+                return str_replace($matches['url'], $host.$matches['url'], $matches[0]);
+            }
+
+            // document relative
+            $url = $matches['url'];
+            while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) {
+                $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1);
+                $url = substr($url, 3);
+            }
+
+            $parts = array();
+            foreach (explode('/', $host.$path.$url) as $part) {
+                if ('..' === $part && count($parts) && '..' !== end($parts)) {
+                    array_pop($parts);
+                } else {
+                    $parts[] = $part;
+                }
+            }
+
+            return str_replace($matches['url'], implode('/', $parts), $matches[0]);
+        });
+
+        $asset->setContent($content);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterCollection.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterCollection.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/FilterCollection.php	(revision 7265)
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A collection of filters.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilterCollection implements FilterInterface, \IteratorAggregate, \Countable
+{
+    private $filters = array();
+
+    public function __construct($filters = array())
+    {
+        foreach ($filters as $filter) {
+            $this->ensure($filter);
+        }
+    }
+
+    /**
+     * Checks that the current collection contains the supplied filter.
+     *
+     * If the supplied filter is another filter collection, each of its
+     * filters will be checked.
+     */
+    public function ensure(FilterInterface $filter)
+    {
+        if ($filter instanceof \Traversable) {
+            foreach ($filter as $f) {
+                $this->ensure($f);
+            }
+        } elseif (!in_array($filter, $this->filters, true)) {
+            $this->filters[] = $filter;
+        }
+    }
+
+    public function all()
+    {
+        return $this->filters;
+    }
+
+    public function clear()
+    {
+        $this->filters = array();
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        foreach ($this->filters as $filter) {
+            $filter->filterLoad($asset);
+        }
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        foreach ($this->filters as $filter) {
+            $filter->filterDump($asset);
+        }
+    }
+
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->filters);
+    }
+
+    public function count()
+    {
+        return count($this->filters);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssMinFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssMinFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CssMinFilter.php	(revision 7265)
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through CssMin.
+ *
+ * @link http://code.google.com/p/cssmin
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssMinFilter implements FilterInterface
+{
+    private $filters;
+    private $plugins;
+
+    public function __construct()
+    {
+        $this->filters = array();
+        $this->plugins = array();
+    }
+
+    public function setFilters(array $filters)
+    {
+        $this->filters = $filters;
+    }
+
+    public function setFilter($name, $value)
+    {
+        $this->filters[$name] = $value;
+    }
+
+    public function setPlugins(array $plugins)
+    {
+        $this->plugins = $plugins;
+    }
+
+    public function setPlugin($name, $value)
+    {
+        $this->plugins[$name] = $value;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $filters = $this->filters;
+        $plugins = $this->plugins;
+
+        if (isset($filters['ImportImports']) && true === $filters['ImportImports']) {
+            $root = $asset->getSourceRoot();
+            $path = $asset->getSourcePath();
+            if ($root && $path) {
+                $filters['ImportImports'] = array('BasePath' => dirname($root.'/'.$path));
+            } else {
+                unset($filters['ImportImports']);
+            }
+        }
+
+        $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PhpCssEmbedFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PhpCssEmbedFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PhpCssEmbedFilter.php	(revision 7265)
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use CssEmbed\CssEmbed;
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A filter that embed url directly into css
+ *
+ * @author Pierre Tachoire <pierre.tachoire@gmail.com>
+ * @link https://github.com/krichprollsch/phpCssEmbed
+ */
+class PhpCssEmbedFilter implements FilterInterface
+{
+    private $presets = array();
+
+    public function setPresets(array $presets)
+    {
+        $this->presets = $presets;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        $pce = new CssEmbed();
+        if ($root && $path) {
+            $pce->setRootDir(dirname($root.'/'.$path));
+        }
+
+        $asset->setContent($pce->embedString($asset->getContent()));
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegoptimFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegoptimFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegoptimFilter.php	(revision 7265)
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Runs assets through Jpegoptim.
+ *
+ * @link   http://www.kokkonen.net/tjko/projects.html
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JpegoptimFilter implements FilterInterface
+{
+    private $jpegoptimBin;
+    private $stripAll;
+    private $max;
+
+    /**
+     * Constructor.
+     *
+     * @param string $jpegoptimBin Path to the jpegoptim binary
+     */
+    public function __construct($jpegoptimBin = '/usr/bin/jpegoptim')
+    {
+        $this->jpegoptimBin = $jpegoptimBin;
+    }
+
+    public function setStripAll($stripAll)
+    {
+        $this->stripAll = $stripAll;
+    }
+
+    public function setMax($max)
+    {
+        $this->max = $max;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $pb = new ProcessBuilder(array($this->jpegoptimBin));
+
+        if ($this->stripAll) {
+            $pb->add('--strip-all');
+        }
+
+        if ($this->max) {
+            $pb->add('--max='.$this->max);
+        }
+
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegoptim'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $proc->run();
+
+        if (false !== strpos($proc->getOutput(), 'ERROR')) {
+            unlink($input);
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent(file_get_contents($input));
+
+        unlink($input);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HandlebarsFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HandlebarsFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/HandlebarsFilter.php	(revision 7265)
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Compiles Handlebars templates into Javascript.
+ *
+ * @link http://handlebarsjs.com/
+ * @author Keyvan Akbary <keyvan@funddy.com>
+ */
+class HandlebarsFilter implements FilterInterface
+{
+    private $handlebarsPath;
+    private $nodePath;
+
+    private $minimize = false;
+    private $simple = false;
+
+    public function __construct($handlebarsPath = '/usr/bin/handlebars', $nodePath = null)
+    {
+        $this->handlebarsPath = $handlebarsPath;
+        $this->nodePath = $nodePath;
+    }
+
+    public function setMinimize($minimize)
+    {
+        $this->minimize = $minimize;
+    }
+
+    public function setSimple($simple)
+    {
+        $this->simple = $simple;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        $executables = array();
+
+        if ($this->nodePath !== null) {
+            $executables[] = $this->nodePath;
+        }
+
+        $executables[] = $this->handlebarsPath;
+
+        $processBuilder = new ProcessBuilder($executables);
+
+        $templateName = basename($asset->getSourcePath());
+
+        $inputDirPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.uniqid('input_dir');
+        $inputPath = $inputDirPath.DIRECTORY_SEPARATOR.$templateName;
+        $outputPath = tempnam(sys_get_temp_dir(), 'output');
+
+        mkdir($inputDirPath);
+        file_put_contents($inputPath, $asset->getContent());
+
+        $processBuilder->add($inputPath)->add('-f')->add($outputPath);
+
+        if ($this->minimize) {
+            $processBuilder->add('--min');
+        }
+
+        if ($this->simple) {
+            $processBuilder->add('--simple');
+        }
+
+        $process = $processBuilder->getProcess();
+        $returnCode = $process->run();
+
+        unlink($inputPath);
+        rmdir($inputDirPath);
+
+        if (127 === $returnCode) {
+            throw new \RuntimeException('Path to node executable could not be resolved.');
+        }
+
+        if (0 < $returnCode) {
+            if (file_exists($outputPath)) {
+                unlink($outputPath);
+            }
+            throw FilterException::fromProcess($process)->setInput($asset->getContent());
+        }
+
+        if (!file_exists($outputPath)) {
+            throw new \RuntimeException('Error creating output file.');
+        }
+
+        $compiledJs = file_get_contents($outputPath);
+        unlink($outputPath);
+
+        $asset->setContent($compiledJs);
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/StylusFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/StylusFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/StylusFilter.php	(revision 7265)
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Loads STYL files.
+ *
+ * @link http://learnboost.github.com/stylus/
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StylusFilter implements FilterInterface
+{
+    private $nodeBin;
+    private $nodePaths;
+    private $compress;
+
+    /**
+     * Constructs filter.
+     *
+     * @param string $nodeBin   The path to the node binary
+     * @param array  $nodePaths An array of node paths
+     */
+    public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array())
+    {
+        $this->nodeBin = $nodeBin;
+        $this->nodePaths = $nodePaths;
+    }
+
+    /**
+     * Enable output compression.
+     *
+     * @param boolean $compress
+     */
+    public function setCompress($compress)
+    {
+        $this->compress = $compress;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filterLoad(AssetInterface $asset)
+    {
+        static $format = <<<'EOF'
+var stylus = require('stylus');
+var sys    = require(process.binding('natives').util ? 'util' : 'sys');
+
+stylus(%s, %s).render(function(e, css){
+    if (e) {
+        throw e;
+    }
+
+    sys.print(css);
+    process.exit(0);
+});
+
+EOF;
+
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        // parser options
+        $parserOptions = array();
+        if ($root && $path) {
+            $parserOptions['paths'] = array(dirname($root.'/'.$path));
+            $parserOptions['filename'] = basename($path);
+        }
+
+        if (null !== $this->compress) {
+            $parserOptions['compress'] = $this->compress;
+        }
+
+        $pb = new ProcessBuilder();
+        $pb->inheritEnvironmentVariables();
+
+        // node.js configuration
+        if (0 < count($this->nodePaths)) {
+            $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths));
+        }
+
+        $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_stylus'));
+        file_put_contents($input, sprintf($format,
+            json_encode($asset->getContent()),
+            json_encode($parserOptions)
+        ));
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/LessFilter.php	(revision 7265)
@@ -0,0 +1,136 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Loads LESS files.
+ *
+ * @link http://lesscss.org/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LessFilter implements FilterInterface
+{
+    private $nodeBin;
+    private $nodePaths;
+    private $compress;
+
+    /**
+     * Load Paths
+     *
+     * A list of paths which less will search for includes.
+     * 
+     * @var array
+     */
+    protected $loadPaths = array();
+
+    /**
+     * Constructor.
+     *
+     * @param string $nodeBin   The path to the node binary
+     * @param array  $nodePaths An array of node paths
+     */
+    public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array())
+    {
+        $this->nodeBin = $nodeBin;
+        $this->nodePaths = $nodePaths;
+    }
+
+    public function setCompress($compress)
+    {
+        $this->compress = $compress;
+    }
+
+    /**
+     * Adds a path where less will search for includes
+     * 
+     * @param string $path Load path (absolute)
+     */
+    public function addLoadPath($path)
+    {
+        $this->loadPaths[] = $path;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        static $format = <<<'EOF'
+var less = require('less');
+var sys  = require(process.binding('natives').util ? 'util' : 'sys');
+
+new(less.Parser)(%s).parse(%s, function(e, tree) {
+    if (e) {
+        less.writeError(e);
+        process.exit(2);
+    }
+
+    try {
+        sys.print(tree.toCSS(%s));
+    } catch (e) {
+        less.writeError(e);
+        process.exit(3);
+    }
+});
+
+EOF;
+
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        // parser options
+        $parserOptions = array();
+        if ($root && $path) {
+            $parserOptions['paths'] = array(dirname($root.'/'.$path));
+            $parserOptions['filename'] = basename($path);
+        }
+        foreach ($this->loadPaths as $loadPath) {
+            $parserOptions['paths'][] = $loadPath;
+        }
+
+        // tree options
+        $treeOptions = array();
+        if (null !== $this->compress) {
+            $treeOptions['compress'] = $this->compress;
+        }
+
+        $pb = new ProcessBuilder();
+        $pb->inheritEnvironmentVariables();
+
+        // node.js configuration
+        if (0 < count($this->nodePaths)) {
+            $pb->setEnv('NODE_PATH', implode(':', $this->nodePaths));
+        }
+
+        $pb->add($this->nodeBin)->add($input = tempnam(sys_get_temp_dir(), 'assetic_less'));
+        file_put_contents($input, sprintf($format,
+            json_encode($parserOptions),
+            json_encode($asset->getContent()),
+            json_encode($treeOptions)
+        ));
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegtranFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegtranFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JpegtranFilter.php	(revision 7265)
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Runs assets through jpegtran.
+ *
+ * @link http://jpegclub.org/jpegtran/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JpegtranFilter implements FilterInterface
+{
+    const COPY_NONE = 'none';
+    const COPY_COMMENTS = 'comments';
+    const COPY_ALL = 'all';
+
+    private $jpegtranBin;
+    private $optimize;
+    private $copy;
+    private $progressive;
+    private $restart;
+
+    /**
+     * Constructor.
+     *
+     * @param string $jpegtranBin Path to the jpegtran binary
+     */
+    public function __construct($jpegtranBin = '/usr/bin/jpegtran')
+    {
+        $this->jpegtranBin = $jpegtranBin;
+    }
+
+    public function setOptimize($optimize)
+    {
+        $this->optimize = $optimize;
+    }
+
+    public function setCopy($copy)
+    {
+        $this->copy = $copy;
+    }
+
+    public function setProgressive($progressive)
+    {
+        $this->progressive = $progressive;
+    }
+
+    public function setRestart($restart)
+    {
+        $this->restart = $restart;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $pb = new ProcessBuilder(array($this->jpegtranBin));
+
+        if ($this->optimize) {
+            $pb->add('-optimize');
+        }
+
+        if ($this->copy) {
+            $pb->add('-copy')->add($this->copy);
+        }
+
+        if ($this->progressive) {
+            $pb->add('-progressive');
+        }
+
+        if (null !== $this->restart) {
+            $pb->add('-restart')->add($this->restart);
+        }
+
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_jpegtran'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PngoutFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PngoutFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PngoutFilter.php	(revision 7265)
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Runs assets through pngout.
+ *
+ * @link http://advsys.net/ken/utils.htm#pngout
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class PngoutFilter implements FilterInterface
+{
+    // -c#
+    const COLOR_GREY       = '0';
+    const COLOR_RGB        = '2';
+    const COLOR_PAL        = '3';
+    const COLOR_GRAY_ALPHA = '4';
+    const COLOR_RGB_ALPHA  = '6';
+
+    // -f#
+    const FILTER_NONE  = '0';
+    const FILTER_X     = '1';
+    const FILTER_Y     = '2';
+    const FILTER_X_Y   = '3';
+    const FILTER_PAETH = '4';
+    const FILTER_MIXED = '5';
+
+    // -s#
+    const STRATEGY_XTREME        = '0';
+    const STRATEGY_INTENSE       = '1';
+    const STRATEGY_LONGEST_MATCH = '2';
+    const STRATEGY_HUFFMAN_ONLY  = '3';
+    const STRATEGY_UNCOMPRESSED  = '4';
+
+    private $pngoutBin;
+    private $color;
+    private $filter;
+    private $strategy;
+    private $blockSplitThreshold;
+
+    /**
+     * Constructor.
+     *
+     * @param string $pngoutBin Path to the pngout binary
+     */
+    public function __construct($pngoutBin = '/usr/bin/pngout')
+    {
+        $this->pngoutBin = $pngoutBin;
+    }
+
+    public function setColor($color)
+    {
+        $this->color = $color;
+    }
+
+    public function setFilter($filter)
+    {
+        $this->filter = $filter;
+    }
+
+    public function setStrategy($strategy)
+    {
+        $this->strategy = $strategy;
+    }
+
+    public function setBlockSplitThreshold($blockSplitThreshold)
+    {
+        $this->blockSplitThreshold = $blockSplitThreshold;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $pb = new ProcessBuilder(array($this->pngoutBin));
+
+        if (null !== $this->color) {
+            $pb->add('-c'.$this->color);
+        }
+
+        if (null !== $this->filter) {
+            $pb->add('-f'.$this->filter);
+        }
+
+        if (null !== $this->strategy) {
+            $pb->add('-s'.$this->strategy);
+        }
+
+        if (null !== $this->blockSplitThreshold) {
+            $pb->add('-b'.$this->blockSplitThreshold);
+        }
+
+        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_pngout'));
+        file_put_contents($input, $asset->getContent());
+
+        $output = tempnam(sys_get_temp_dir(), 'assetic_pngout');
+        unlink($output);
+        $pb->add($output .= '.png');
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+
+        if (0 < $code) {
+            unlink($input);
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent(file_get_contents($output));
+
+        unlink($input);
+        unlink($output);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerApiFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerApiFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerApiFilter.php	(revision 7265)
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filter for the Google Closure Compiler API.
+ *
+ * @link https://developers.google.com/closure/compiler/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CompilerApiFilter extends BaseCompilerFilter
+{
+    public function filterDump(AssetInterface $asset)
+    {
+        $query = array(
+            'js_code'       => $asset->getContent(),
+            'output_format' => 'json',
+            'output_info'   => 'compiled_code',
+        );
+
+        if (null !== $this->compilationLevel) {
+            $query['compilation_level'] = $this->compilationLevel;
+        }
+
+        if (null !== $this->jsExterns) {
+            $query['js_externs'] = $this->jsExterns;
+        }
+
+        if (null !== $this->externsUrl) {
+            $query['externs_url'] = $this->externsUrl;
+        }
+
+        if (null !== $this->excludeDefaultExterns) {
+            $query['exclude_default_externs'] = $this->excludeDefaultExterns ? 'true' : 'false';
+        }
+
+        if (null !== $this->formatting) {
+            $query['formatting'] = $this->formatting;
+        }
+
+        if (null !== $this->useClosureLibrary) {
+            $query['use_closure_library'] = $this->useClosureLibrary ? 'true' : 'false';
+        }
+
+        if (null !== $this->warningLevel) {
+            $query['warning_level'] = $this->warningLevel;
+        }
+
+        if (null !== $this->language) {
+            $query['language'] = $this->language;
+        }
+
+        if (preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'))) {
+            $context = stream_context_create(array('http' => array(
+                'method'  => 'POST',
+                'header'  => 'Content-Type: application/x-www-form-urlencoded',
+                'content' => http_build_query($query),
+            )));
+
+            $response = file_get_contents('http://closure-compiler.appspot.com/compile', false, $context);
+            $data = json_decode($response);
+
+         } elseif (defined('CURLOPT_POST') && !in_array('curl_init', explode(',', ini_get('disable_functions')))) {
+
+            $ch = curl_init('http://closure-compiler.appspot.com/compile');
+            curl_setopt($ch, CURLOPT_POST, true);
+            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
+            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+            $response = curl_exec($ch);
+            curl_close($ch);
+
+            $data = json_decode($response);
+        } else {
+            throw new \RuntimeException("There is no known way to contact closure compiler available");
+        }
+
+        if (isset($data->serverErrors) && 0 < count($data->serverErrors)) {
+            // @codeCoverageIgnoreStart
+            throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some server errors: '.print_r($data->serverErrors, true)));
+            // @codeCoverageIgnoreEnd
+        }
+
+        if (isset($data->errors) && 0 < count($data->errors)) {
+            // @codeCoverageIgnoreStart
+            throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some errors: '.print_r($data->errors, true)));
+            // @codeCoverageIgnoreEnd
+        }
+
+        $asset->setContent($data->compiledCode);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php	(revision 7265)
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Base filter for the Google Closure Compiler implementations.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCompilerFilter implements FilterInterface
+{
+    // compilation levels
+    const COMPILE_WHITESPACE_ONLY = 'WHITESPACE_ONLY';
+    const COMPILE_SIMPLE_OPTIMIZATIONS = 'SIMPLE_OPTIMIZATIONS';
+    const COMPILE_ADVANCED_OPTIMIZATIONS = 'ADVANCED_OPTIMIZATIONS';
+
+    // formatting modes
+    const FORMAT_PRETTY_PRINT = 'pretty_print';
+    const FORMAT_PRINT_INPUT_DELIMITER = 'print_input_delimiter';
+
+    // warning levels
+    const LEVEL_QUIET = 'QUIET';
+    const LEVEL_DEFAULT = 'DEFAULT';
+    const LEVEL_VERBOSE = 'VERBOSE';
+
+    // languages
+    const LANGUAGE_ECMASCRIPT3 = 'ECMASCRIPT3';
+    const LANGUAGE_ECMASCRIPT5 = 'ECMASCRIPT5';
+    const LANGUAGE_ECMASCRIPT5_STRICT = 'ECMASCRIPT5_STRICT';
+
+    protected $compilationLevel;
+    protected $jsExterns;
+    protected $externsUrl;
+    protected $excludeDefaultExterns;
+    protected $formatting;
+    protected $useClosureLibrary;
+    protected $warningLevel;
+    protected $language;
+
+    public function setCompilationLevel($compilationLevel)
+    {
+        $this->compilationLevel = $compilationLevel;
+    }
+
+    public function setJsExterns($jsExterns)
+    {
+        $this->jsExterns = $jsExterns;
+    }
+
+    public function setExternsUrl($externsUrl)
+    {
+        $this->externsUrl = $externsUrl;
+    }
+
+    public function setExcludeDefaultExterns($excludeDefaultExterns)
+    {
+        $this->excludeDefaultExterns = $excludeDefaultExterns;
+    }
+
+    public function setFormatting($formatting)
+    {
+        $this->formatting = $formatting;
+    }
+
+    public function setUseClosureLibrary($useClosureLibrary)
+    {
+        $this->useClosureLibrary = $useClosureLibrary;
+    }
+
+    public function setWarningLevel($warningLevel)
+    {
+        $this->warningLevel = $warningLevel;
+    }
+
+    public function setLanguage($language)
+    {
+        $this->language = $language;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerJarFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerJarFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/GoogleClosure/CompilerJarFilter.php	(revision 7265)
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Filter for the Google Closure Compiler JAR.
+ *
+ * @link https://developers.google.com/closure/compiler/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CompilerJarFilter extends BaseCompilerFilter
+{
+    private $jarPath;
+    private $javaPath;
+
+    public function __construct($jarPath, $javaPath = '/usr/bin/java')
+    {
+        $this->jarPath = $jarPath;
+        $this->javaPath = $javaPath;
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $cleanup = array();
+
+        $pb = new ProcessBuilder(array(
+            $this->javaPath,
+            '-jar',
+            $this->jarPath,
+        ));
+
+        if (null !== $this->compilationLevel) {
+            $pb->add('--compilation_level')->add($this->compilationLevel);
+        }
+
+        if (null !== $this->jsExterns) {
+            $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler');
+            file_put_contents($externs, $this->jsExterns);
+            $pb->add('--externs')->add($externs);
+        }
+
+        if (null !== $this->externsUrl) {
+            $cleanup[] = $externs = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler');
+            file_put_contents($externs, file_get_contents($this->externsUrl));
+            $pb->add('--externs')->add($externs);
+        }
+
+        if (null !== $this->excludeDefaultExterns) {
+            $pb->add('--use_only_custom_externs');
+        }
+
+        if (null !== $this->formatting) {
+            $pb->add('--formatting')->add($this->formatting);
+        }
+
+        if (null !== $this->useClosureLibrary) {
+            $pb->add('--manage_closure_dependencies');
+        }
+
+        if (null !== $this->warningLevel) {
+            $pb->add('--warning_level')->add($this->warningLevel);
+        }
+
+        if (null !== $this->language) {
+            $pb->add('--language_in')->add($this->language);
+        }
+
+        $pb->add('--js')->add($cleanup[] = $input = tempnam(sys_get_temp_dir(), 'assetic_google_closure_compiler'));
+        file_put_contents($input, $asset->getContent());
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        array_map('unlink', $cleanup);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackagerFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackagerFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/PackagerFilter.php	(revision 7265)
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Runs assets through Packager.
+ *
+ * @link https://github.com/kamicane/packager
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class PackagerFilter implements FilterInterface
+{
+    private $packages;
+
+    public function __construct(array $packages = array())
+    {
+        $this->packages = $packages;
+    }
+
+    public function addPackage($package)
+    {
+        $this->packages[] = $package;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        static $manifest = <<<EOF
+name: Application%s
+sources: [source.js]
+
+EOF;
+
+        $hash = substr(sha1(time().rand(11111, 99999)), 0, 7);
+        $package = sys_get_temp_dir().'/assetic_packager_'.$hash;
+
+        mkdir($package);
+        file_put_contents($package.'/package.yml', sprintf($manifest, $hash));
+        file_put_contents($package.'/source.js', $asset->getContent());
+
+        $packager = new \Packager(array_merge(array($package), $this->packages));
+        $content = $packager->build(array(), array(), array('Application'.$hash));
+
+        unlink($package.'/package.yml');
+        unlink($package.'/source.js');
+        rmdir($package);
+
+        $asset->setContent($content);
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/SprocketsFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/SprocketsFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/SprocketsFilter.php	(revision 7265)
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Runs assets through Sprockets.
+ *
+ * Requires Sprockets 1.0.x.
+ *
+ * @link http://getsprockets.org/
+ * @link http://github.com/sstephenson/sprockets/tree/1.0.x
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class SprocketsFilter implements FilterInterface
+{
+    private $sprocketsLib;
+    private $rubyBin;
+    private $includeDirs;
+    private $assetRoot;
+
+    /**
+     * Constructor.
+     *
+     * @param string $sprocketsLib Path to the Sprockets lib/ directory
+     * @param string $rubyBin      Path to the ruby binary
+     */
+    public function __construct($sprocketsLib = null, $rubyBin = '/usr/bin/ruby')
+    {
+        $this->sprocketsLib = $sprocketsLib;
+        $this->rubyBin = $rubyBin;
+        $this->includeDirs = array();
+    }
+
+    public function addIncludeDir($directory)
+    {
+        $this->includeDirs[] = $directory;
+    }
+
+    public function setAssetRoot($assetRoot)
+    {
+        $this->assetRoot = $assetRoot;
+    }
+
+    /**
+     * Hack around a bit, get the job done.
+     */
+    public function filterLoad(AssetInterface $asset)
+    {
+        static $format = <<<'EOF'
+#!/usr/bin/env ruby
+
+require %s
+%s
+options = { :load_path    => [],
+            :source_files => [%s],
+            :expand_paths => false }
+
+%ssecretary = Sprockets::Secretary.new(options)
+secretary.install_assets if options[:asset_root]
+print secretary.concatenation
+
+EOF;
+
+        $more = '';
+
+        foreach ($this->includeDirs as $directory) {
+            $more .= 'options[:load_path] << '.var_export($directory, true)."\n";
+        }
+
+        if (null !== $this->assetRoot) {
+            $more .= 'options[:asset_root] = '.var_export($this->assetRoot, true)."\n";
+        }
+
+        if ($more) {
+            $more .= "\n";
+        }
+
+        $tmpAsset = tempnam(sys_get_temp_dir(), 'assetic_sprockets');
+        file_put_contents($tmpAsset, $asset->getContent());
+
+        $input = tempnam(sys_get_temp_dir(), 'assetic_sprockets');
+        file_put_contents($input, sprintf($format,
+            $this->sprocketsLib
+                ? sprintf('File.join(%s, \'sprockets\')', var_export($this->sprocketsLib, true))
+                : '\'sprockets\'',
+            $this->getHack($asset),
+            var_export($tmpAsset, true),
+            $more
+        ));
+
+        $pb = new ProcessBuilder(array(
+            $this->rubyBin,
+            $input,
+        ));
+
+        $proc = $pb->getProcess();
+        $code = $proc->run();
+        unlink($tmpAsset);
+        unlink($input);
+
+        if (0 < $code) {
+            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+        }
+
+        $asset->setContent($proc->getOutput());
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+    }
+
+    private function getHack(AssetInterface $asset)
+    {
+        static $format = <<<'EOF'
+
+module Sprockets
+  class Preprocessor
+    protected
+    def pathname_for_relative_require_from(source_line)
+      Sprockets::Pathname.new(@environment, File.join(%s, location_from(source_line)))
+    end
+  end
+end
+
+EOF;
+
+        $root = $asset->getSourceRoot();
+        $path = $asset->getSourcePath();
+
+        if ($root && $path) {
+            return sprintf($format, var_export(dirname($root.'/'.$path), true));
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/JSMinFilter.php	(revision 7265)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through JsMin.
+ *
+ * All credit for the filter itself is mentioned in the file itself.
+ *
+ * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMin.php
+ * @author Brunoais <brunoaiss@gmail.com>
+ */
+class JSMinFilter implements FilterInterface
+{
+    public function filterLoad(AssetInterface $asset)
+    {
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        $asset->setContent(\JSMin::minify($asset->getContent()));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CallablesFilter.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CallablesFilter.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Filter/CallablesFilter.php	(revision 7265)
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A filter that wraps callables.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CallablesFilter implements FilterInterface
+{
+    private $loader;
+    private $dumper;
+
+    /**
+     * @param callable|null $loader
+     * @param callable|null $dumper
+     */
+    public function __construct($loader = null, $dumper = null)
+    {
+        $this->loader = $loader;
+        $this->dumper = $dumper;
+    }
+
+    public function filterLoad(AssetInterface $asset)
+    {
+        if (null !== $callable = $this->loader) {
+            $callable($asset);
+        }
+    }
+
+    public function filterDump(AssetInterface $asset)
+    {
+        if (null !== $callable = $this->dumper) {
+            $callable($asset);
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/FilterManager.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/FilterManager.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/FilterManager.php	(revision 7265)
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Manages the available filters.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilterManager
+{
+    private $filters = array();
+
+    public function set($alias, FilterInterface $filter)
+    {
+        $this->checkName($alias);
+
+        $this->filters[$alias] = $filter;
+    }
+
+    public function get($alias)
+    {
+        if (!isset($this->filters[$alias])) {
+            throw new \InvalidArgumentException(sprintf('There is no "%s" filter.', $alias));
+        }
+
+        return $this->filters[$alias];
+    }
+
+    public function has($alias)
+    {
+        return isset($this->filters[$alias]);
+    }
+
+    public function getNames()
+    {
+        return array_keys($this->filters);
+    }
+
+    /**
+     * Checks that a name is valid.
+     *
+     * @param string $name An asset name candidate
+     *
+     * @throws \InvalidArgumentException If the asset name is invalid
+     */
+    protected function checkName($name)
+    {
+        if (!ctype_alnum(str_replace('_', '', $name))) {
+            throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name));
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/LazyAssetManager.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/LazyAssetManager.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/LazyAssetManager.php	(revision 7265)
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory;
+
+use Assetic\AssetManager;
+use Assetic\Factory\Loader\FormulaLoaderInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * A lazy asset manager is a composition of a factory and many formula loaders.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LazyAssetManager extends AssetManager
+{
+    private $factory;
+    private $loaders;
+    private $resources;
+    private $formulae;
+    private $loaded;
+    private $loading;
+
+    /**
+     * Constructor.
+     *
+     * @param AssetFactory $factory The asset factory
+     * @param array        $loaders An array of loaders indexed by alias
+     */
+    public function __construct(AssetFactory $factory, $loaders = array())
+    {
+        $this->factory = $factory;
+        $this->loaders = array();
+        $this->resources = array();
+        $this->formulae = array();
+        $this->loaded = false;
+        $this->loading = false;
+
+        foreach ($loaders as $alias => $loader) {
+            $this->setLoader($alias, $loader);
+        }
+    }
+
+    /**
+     * Adds a loader to the asset manager.
+     *
+     * @param string                 $alias  An alias for the loader
+     * @param FormulaLoaderInterface $loader A loader
+     */
+    public function setLoader($alias, FormulaLoaderInterface $loader)
+    {
+        $this->loaders[$alias] = $loader;
+        $this->loaded = false;
+    }
+
+    /**
+     * Adds a resource to the asset manager.
+     *
+     * @param ResourceInterface $resource A resource
+     * @param string            $loader   The loader alias for this resource
+     */
+    public function addResource(ResourceInterface $resource, $loader)
+    {
+        $this->resources[$loader][] = $resource;
+        $this->loaded = false;
+    }
+
+    /**
+     * Returns an array of resources.
+     *
+     * @return array An array of resources
+     */
+    public function getResources()
+    {
+        $resources = array();
+        foreach ($this->resources as $r) {
+            $resources = array_merge($resources, $r);
+        }
+
+        return $resources;
+    }
+
+    /**
+     * Checks for an asset formula.
+     *
+     * @param string $name An asset name
+     *
+     * @return Boolean If there is a formula
+     */
+    public function hasFormula($name)
+    {
+        if (!$this->loaded) {
+            $this->load();
+        }
+
+        return isset($this->formulae[$name]);
+    }
+
+    /**
+     * Returns an asset's formula.
+     *
+     * @param string $name An asset name
+     *
+     * @return array The formula
+     *
+     * @throws \InvalidArgumentException If there is no formula by that name
+     */
+    public function getFormula($name)
+    {
+        if (!$this->loaded) {
+            $this->load();
+        }
+
+        if (!isset($this->formulae[$name])) {
+            throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name));
+        }
+
+        return $this->formulae[$name];
+    }
+
+    /**
+     * Sets a formula on the asset manager.
+     *
+     * @param string $name    An asset name
+     * @param array  $formula A formula
+     */
+    public function setFormula($name, array $formula)
+    {
+        $this->formulae[$name] = $formula;
+    }
+
+    /**
+     * Loads formulae from resources.
+     *
+     * @throws \LogicException If a resource has been added to an invalid loader
+     */
+    public function load()
+    {
+        if ($this->loading) {
+            return;
+        }
+
+        if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) {
+            throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff));
+        }
+
+        $this->loading = true;
+
+        foreach ($this->resources as $loader => $resources) {
+            foreach ($resources as $resource) {
+                $this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource));
+            }
+        }
+
+        $this->loaded = true;
+        $this->loading = false;
+    }
+
+    public function get($name)
+    {
+        if (!$this->loaded) {
+            $this->load();
+        }
+
+        if (!parent::has($name) && isset($this->formulae[$name])) {
+            list($inputs, $filters, $options) = $this->formulae[$name];
+            $options['name'] = $name;
+            parent::set($name, $this->factory->createAsset($inputs, $filters, $options));
+        }
+
+        return parent::get($name);
+    }
+
+    public function has($name)
+    {
+        if (!$this->loaded) {
+            $this->load();
+        }
+
+        return isset($this->formulae[$name]) || parent::has($name);
+    }
+
+    public function getNames()
+    {
+        if (!$this->loaded) {
+            $this->load();
+        }
+
+        return array_unique(array_merge(parent::getNames(), array_keys($this->formulae)));
+    }
+
+    public function isDebug()
+    {
+        return $this->factory->isDebug();
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FormulaLoaderInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FormulaLoaderInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FormulaLoaderInterface.php	(revision 7265)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Loads formulae.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface FormulaLoaderInterface
+{
+    /**
+     * Loads formulae from a resource.
+     *
+     * Formulae should be loaded the same regardless of the current debug
+     * mode. Debug considerations should happen downstream.
+     *
+     * @param ResourceInterface $resource A resource
+     *
+     * @return array An array of formulae
+     */
+    public function load(ResourceInterface $resource);
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/BasePhpFormulaLoader.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/BasePhpFormulaLoader.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/BasePhpFormulaLoader.php	(revision 7265)
@@ -0,0 +1,159 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Factory\AssetFactory;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Loads asset formulae from PHP files.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BasePhpFormulaLoader implements FormulaLoaderInterface
+{
+    protected $factory;
+    protected $prototypes;
+
+    public function __construct(AssetFactory $factory)
+    {
+        $this->factory = $factory;
+        $this->prototypes = array();
+
+        foreach ($this->registerPrototypes() as $prototype => $options) {
+            $this->addPrototype($prototype, $options);
+        }
+    }
+
+    public function addPrototype($prototype, array $options = array())
+    {
+        $tokens = token_get_all('<?php '.$prototype);
+        array_shift($tokens);
+
+        $this->prototypes[$prototype] = array($tokens, $options);
+    }
+
+    public function load(ResourceInterface $resource)
+    {
+        if (!$nbProtos = count($this->prototypes)) {
+            throw new \LogicException('There are no prototypes registered.');
+        }
+
+        $buffers = array_fill(0, $nbProtos, '');
+        $bufferLevels = array_fill(0, $nbProtos, 0);
+        $buffersInWildcard = array();
+
+        $tokens = token_get_all($resource->getContent());
+        $calls = array();
+
+        while ($token = array_shift($tokens)) {
+            $current = self::tokenToString($token);
+            // loop through each prototype (by reference)
+            foreach (array_keys($this->prototypes) as $i) {
+                $prototype =& $this->prototypes[$i][0];
+                $options = $this->prototypes[$i][1];
+                $buffer =& $buffers[$i];
+                $level =& $bufferLevels[$i];
+
+                if (isset($buffersInWildcard[$i])) {
+                    switch ($current) {
+                        case '(': ++$level; break;
+                        case ')': --$level; break;
+                    }
+
+                    $buffer .= $current;
+
+                    if (!$level) {
+                        $calls[] = array($buffer.';', $options);
+                        $buffer = '';
+                        unset($buffersInWildcard[$i]);
+                    }
+                } elseif ($current == self::tokenToString(current($prototype))) {
+                    $buffer .= $current;
+                    if ('*' == self::tokenToString(next($prototype))) {
+                        $buffersInWildcard[$i] = true;
+                        ++$level;
+                    }
+                } else {
+                    reset($prototype);
+                    unset($buffersInWildcard[$i]);
+                    $buffer = '';
+                }
+            }
+        }
+
+        $formulae = array();
+        foreach ($calls as $call) {
+            $formulae += call_user_func_array(array($this, 'processCall'), $call);
+        }
+
+        return $formulae;
+    }
+
+    private function processCall($call, array $protoOptions = array())
+    {
+        $tmp = tempnam(sys_get_temp_dir(), 'assetic');
+        file_put_contents($tmp, implode("\n", array(
+            '<?php',
+            $this->registerSetupCode(),
+            $call,
+            'echo serialize($_call);',
+        )));
+        $args = unserialize(shell_exec('php '.escapeshellarg($tmp)));
+        unlink($tmp);
+
+        $inputs  = isset($args[0]) ? self::argumentToArray($args[0]) : array();
+        $filters = isset($args[1]) ? self::argumentToArray($args[1]) : array();
+        $options = isset($args[2]) ? $args[2] : array();
+
+        if (!isset($options['debug'])) {
+            $options['debug'] = $this->factory->isDebug();
+        }
+
+        if (!is_array($options)) {
+            throw new \RuntimeException('The third argument must be omitted, null or an array.');
+        }
+
+        // apply the prototype options
+        $options += $protoOptions;
+
+        if (!isset($options['name'])) {
+            $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options);
+        }
+
+        return array($options['name'] => array($inputs, $filters, $options));
+    }
+
+    /**
+     * Returns an array of prototypical calls and options.
+     *
+     * @return array Prototypes and options
+     */
+    abstract protected function registerPrototypes();
+
+    /**
+     * Returns setup code for the reflection scriptlet.
+     *
+     * @return string Some PHP setup code
+     */
+    abstract protected function registerSetupCode();
+
+    protected static function tokenToString($token)
+    {
+        return is_array($token) ? $token[1] : $token;
+    }
+
+    protected static function argumentToArray($argument)
+    {
+        return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument)));
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php	(revision 7265)
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+/**
+ * Loads asset formulae from PHP files.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FunctionCallsFormulaLoader extends BasePhpFormulaLoader
+{
+    protected function registerPrototypes()
+    {
+        return array(
+            'assetic_javascripts(*)' => array('output' => 'js/*.js'),
+            'assetic_stylesheets(*)' => array('output' => 'css/*.css'),
+            'assetic_image(*)'       => array('output' => 'images/*'),
+        );
+    }
+
+    protected function registerSetupCode()
+    {
+        return <<<'EOF'
+function assetic_javascripts()
+{
+    global $_call;
+    $_call = func_get_args();
+}
+
+function assetic_stylesheets()
+{
+    global $_call;
+    $_call = func_get_args();
+}
+
+function assetic_image()
+{
+    global $_call;
+    $_call = func_get_args();
+}
+
+EOF;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/CachedFormulaLoader.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/CachedFormulaLoader.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Loader/CachedFormulaLoader.php	(revision 7265)
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Cache\ConfigCache;
+use Assetic\Factory\Resource\IteratorResourceInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Adds a caching layer to a loader.
+ *
+ * A cached formula loader is a composition of a formula loader and a cache.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CachedFormulaLoader implements FormulaLoaderInterface
+{
+    private $loader;
+    private $configCache;
+    private $debug;
+
+    /**
+     * Constructor.
+     *
+     * When the loader is in debug mode it will ensure the cached formulae
+     * are fresh before returning them.
+     *
+     * @param FormulaLoaderInterface $loader      A formula loader
+     * @param ConfigCache            $configCache A config cache
+     * @param Boolean                $debug       The debug mode
+     */
+    public function __construct(FormulaLoaderInterface $loader, ConfigCache $configCache, $debug = false)
+    {
+        $this->loader = $loader;
+        $this->configCache = $configCache;
+        $this->debug = $debug;
+    }
+
+    public function load(ResourceInterface $resources)
+    {
+        if (!$resources instanceof IteratorResourceInterface) {
+            $resources = array($resources);
+        }
+
+        $formulae = array();
+
+        foreach ($resources as $resource) {
+            $id = (string) $resource;
+            if (!$this->configCache->has($id) || ($this->debug && !$resource->isFresh($this->configCache->getTimestamp($id)))) {
+                $formulae += $this->loader->load($resource);
+                $this->configCache->set($id, $formulae);
+            } else {
+                $formulae += $this->configCache->get($id);
+            }
+        }
+
+        return $formulae;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/DirectoryResource.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/DirectoryResource.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/DirectoryResource.php	(revision 7265)
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class DirectoryResource implements IteratorResourceInterface
+{
+    private $path;
+    private $pattern;
+
+    /**
+     * Constructor.
+     *
+     * @param string $path    A directory path
+     * @param string $pattern A filename pattern
+     */
+    public function __construct($path, $pattern = null)
+    {
+        if (DIRECTORY_SEPARATOR != substr($path, -1)) {
+            $path .= DIRECTORY_SEPARATOR;
+        }
+
+        $this->path = $path;
+        $this->pattern = $pattern;
+    }
+
+    public function isFresh($timestamp)
+    {
+        if (!is_dir($this->path) || filemtime($this->path) > $timestamp) {
+            return false;
+        }
+
+        foreach ($this as $resource) {
+            if (!$resource->isFresh($timestamp)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the combined content of all inner resources.
+     */
+    public function getContent()
+    {
+        $content = array();
+        foreach ($this as $resource) {
+            $content[] = $resource->getContent();
+        }
+
+        return implode("\n", $content);
+    }
+
+    public function __toString()
+    {
+        return $this->path;
+    }
+
+    public function getIterator()
+    {
+        return is_dir($this->path)
+            ? new DirectoryResourceIterator($this->getInnerIterator())
+            : new \EmptyIterator();
+    }
+
+    protected function getInnerIterator()
+    {
+        return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern);
+    }
+}
+
+/**
+ * An iterator that converts file objects into file resources.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @access private
+ */
+class DirectoryResourceIterator extends \RecursiveIteratorIterator
+{
+    public function current()
+    {
+        return new FileResource(parent::current()->getPathname());
+    }
+}
+
+/**
+ * Filters files by a basename pattern.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @access private
+ */
+class DirectoryResourceFilterIterator extends \RecursiveFilterIterator
+{
+    protected $pattern;
+
+    public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null)
+    {
+        parent::__construct($iterator);
+
+        $this->pattern = $pattern;
+    }
+
+    public function accept()
+    {
+        $file = $this->current();
+        $name = $file->getBasename();
+
+        if ($file->isDir()) {
+            return '.' != $name[0];
+        }
+
+        return null === $this->pattern || 0 < preg_match($this->pattern, $name);
+    }
+
+    public function getChildren()
+    {
+        return new self(new \RecursiveDirectoryIterator($this->current()->getPathname(), \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/IteratorResourceInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/IteratorResourceInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/IteratorResourceInterface.php	(revision 7265)
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate
+{
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/CoalescingDirectoryResource.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/CoalescingDirectoryResource.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/CoalescingDirectoryResource.php	(revision 7265)
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * Coalesces multiple directories together into one merged resource.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CoalescingDirectoryResource implements IteratorResourceInterface
+{
+    private $directories;
+
+    public function __construct($directories)
+    {
+        $this->directories = array();
+
+        foreach ($directories as $directory) {
+            $this->addDirectory($directory);
+        }
+    }
+
+    public function addDirectory(IteratorResourceInterface $directory)
+    {
+        $this->directories[] = $directory;
+    }
+
+    public function isFresh($timestamp)
+    {
+        foreach ($this->getFileResources() as $file) {
+            if (!$file->isFresh($timestamp)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public function getContent()
+    {
+        $parts = array();
+        foreach ($this->getFileResources() as $file) {
+            $parts[] = $file->getContent();
+        }
+
+        return implode("\n", $parts);
+    }
+
+    /**
+     * Returns a string to uniquely identify the current resource.
+     *
+     * @return string An identifying string
+     */
+    public function __toString()
+    {
+        $parts = array();
+        foreach ($this->directories as $directory) {
+            $parts[] = (string) $directory;
+        }
+
+        return implode(',', $parts);
+    }
+
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->getFileResources());
+    }
+
+    /**
+     * Returns the relative version of a filename.
+     *
+     * @param ResourceInterface $file      The file
+     * @param ResourceInterface $directory The directory
+     *
+     * @return string The name to compare with files from other directories
+     */
+    protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory)
+    {
+        return substr((string) $file, strlen((string) $directory));
+    }
+
+    /**
+     * Performs the coalesce.
+     *
+     * @return array An array of file resources
+     */
+    private function getFileResources()
+    {
+        $paths = array();
+
+        foreach ($this->directories as $directory) {
+            foreach ($directory as $file) {
+                $relative = $this->getRelativeName($file, $directory);
+
+                if (!isset($paths[$relative])) {
+                    $paths[$relative] = $file;
+                }
+            }
+        }
+
+        return array_values($paths);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/FileResource.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/FileResource.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/FileResource.php	(revision 7265)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FileResource implements ResourceInterface
+{
+    private $path;
+
+    /**
+     * Constructor.
+     *
+     * @param string $path The path to a file
+     */
+    public function __construct($path)
+    {
+        $this->path = $path;
+    }
+
+    public function isFresh($timestamp)
+    {
+        return file_exists($this->path) && filemtime($this->path) <= $timestamp;
+    }
+
+    public function getContent()
+    {
+        return file_exists($this->path) ? file_get_contents($this->path) : '';
+    }
+
+    public function __toString()
+    {
+        return $this->path;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/ResourceInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/ResourceInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Resource/ResourceInterface.php	(revision 7265)
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface ResourceInterface
+{
+    /**
+     * Checks if a timestamp represents the latest resource.
+     *
+     * @param integer $timestamp A UNIX timestamp
+     *
+     * @return Boolean True if the timestamp is up to date
+     */
+    public function isFresh($timestamp);
+
+    /**
+     * Returns the content of the resource.
+     *
+     * @return string The content
+     */
+    public function getContent();
+
+    /**
+     * Returns a unique string for the current resource.
+     *
+     * @return string A unique string to identity the current resource
+     */
+    public function __toString();
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/CacheBustingWorker.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/CacheBustingWorker.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/CacheBustingWorker.php	(revision 7265)
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Adds cache busting code
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CacheBustingWorker implements WorkerInterface
+{
+    const STRATEGY_CONTENT = 1;
+    const STRATEGY_MODIFICATION = 2;
+
+    private $strategy;
+
+    public function __construct($strategy = self::STRATEGY_CONTENT)
+    {
+        $this->strategy = $strategy;
+    }
+
+    public function process(AssetInterface $asset)
+    {
+        $hash = hash_init('sha1');
+
+        switch($this->strategy) {
+            case self::STRATEGY_MODIFICATION:
+                hash_update($hash, $asset->getLastModified());
+                break;
+            case self::STRATEGY_CONTENT:
+                hash_update($hash, $asset->dump());
+                break;
+        }
+
+        foreach ($asset as $i => $leaf) {
+            if ($sourcePath = $leaf->getSourcePath()) {
+                hash_update($hash, $sourcePath);
+            } else {
+                hash_update($hash, $i);
+            }
+        }
+
+        $hash = substr(hash_final($hash), 0, 7);
+        $url = $asset->getTargetPath();
+
+        $oldExt = pathinfo($url, PATHINFO_EXTENSION);
+        $newExt = '-'.$hash.'.'.$oldExt;
+
+        if (!$oldExt || 0 < preg_match('/'.preg_quote($newExt, '/').'$/', $url)) {
+            return;
+        }
+
+        $asset->setTargetPath(substr($url, 0, (strlen($oldExt) + 1) * -1).$newExt);
+    }
+
+    public function getStrategy()
+    {
+        return $this->strategy;
+    }
+
+    public function setStrategy($strategy)
+    {
+        $this->strategy = $strategy;
+
+        return $this;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/WorkerInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/WorkerInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/WorkerInterface.php	(revision 7265)
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Assets are passed through factory workers before leaving the factory.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface WorkerInterface
+{
+    /**
+     * Processes an asset.
+     *
+     * @param AssetInterface $asset An asset
+     *
+     * @return AssetInterface|null May optionally return a replacement asset
+     */
+    public function process(AssetInterface $asset);
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/EnsureFilterWorker.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/EnsureFilterWorker.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/Worker/EnsureFilterWorker.php	(revision 7265)
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Applies a filter to an asset based on a source and/or target path match.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @todo A better asset-matcher mechanism
+ */
+class EnsureFilterWorker implements WorkerInterface
+{
+    const CHECK_SOURCE = 1;
+    const CHECK_TARGET = 2;
+
+    private $pattern;
+    private $filter;
+    private $flags;
+
+    /**
+     * Constructor.
+     *
+     * @param string          $pattern A regex for checking the asset's target URL
+     * @param FilterInterface $filter  A filter to apply if the regex matches
+     * @param integer         $flags   Flags for what to check
+     */
+    public function __construct($pattern, FilterInterface $filter, $flags = null)
+    {
+        if (null === $flags) {
+            $flags = self::CHECK_SOURCE | self::CHECK_TARGET;
+        }
+
+        $this->pattern = $pattern;
+        $this->filter = $filter;
+        $this->flags = $flags;
+    }
+
+    public function process(AssetInterface $asset)
+    {
+        if (
+            (self::CHECK_SOURCE === (self::CHECK_SOURCE & $this->flags) && preg_match($this->pattern, $asset->getSourcePath()))
+            ||
+            (self::CHECK_TARGET === (self::CHECK_TARGET & $this->flags) && preg_match($this->pattern, $asset->getTargetPath()))
+        ) {
+            $asset->ensureFilter($this->filter);
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/AssetFactory.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/AssetFactory.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Factory/AssetFactory.php	(revision 7265)
@@ -0,0 +1,388 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory;
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\AssetCollectionInterface;
+use Assetic\Asset\AssetInterface;
+use Assetic\Asset\AssetReference;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+use Assetic\Asset\HttpAsset;
+use Assetic\AssetManager;
+use Assetic\Factory\Worker\WorkerInterface;
+use Assetic\FilterManager;
+
+/**
+ * The asset factory creates asset objects.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetFactory
+{
+    private $root;
+    private $debug;
+    private $output;
+    private $workers;
+    private $am;
+    private $fm;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $root   The default root directory
+     * @param Boolean $debug  Filters prefixed with a "?" will be omitted in debug mode
+     */
+    public function __construct($root, $debug = false)
+    {
+        $this->root      = rtrim($root, '/');
+        $this->debug     = $debug;
+        $this->output    = 'assetic/*';
+        $this->workers   = array();
+    }
+
+    /**
+     * Sets debug mode for the current factory.
+     *
+     * @param Boolean $debug Debug mode
+     */
+    public function setDebug($debug)
+    {
+        $this->debug = $debug;
+    }
+
+    /**
+     * Checks if the factory is in debug mode.
+     *
+     * @return Boolean Debug mode
+     */
+    public function isDebug()
+    {
+        return $this->debug;
+    }
+
+    /**
+     * Sets the default output string.
+     *
+     * @param string $output The default output string
+     */
+    public function setDefaultOutput($output)
+    {
+        $this->output = $output;
+    }
+
+    /**
+     * Adds a factory worker.
+     *
+     * @param WorkerInterface $worker A worker
+     */
+    public function addWorker(WorkerInterface $worker)
+    {
+        $this->workers[] = $worker;
+    }
+
+    /**
+     * Returns the current asset manager.
+     *
+     * @return AssetManager|null The asset manager
+     */
+    public function getAssetManager()
+    {
+        return $this->am;
+    }
+
+    /**
+     * Sets the asset manager to use when creating asset references.
+     *
+     * @param AssetManager $am The asset manager
+     */
+    public function setAssetManager(AssetManager $am)
+    {
+        $this->am = $am;
+    }
+
+    /**
+     * Returns the current filter manager.
+     *
+     * @return FilterManager|null The filter manager
+     */
+    public function getFilterManager()
+    {
+        return $this->fm;
+    }
+
+    /**
+     * Sets the filter manager to use when adding filters.
+     *
+     * @param FilterManager $fm The filter manager
+     */
+    public function setFilterManager(FilterManager $fm)
+    {
+        $this->fm = $fm;
+    }
+
+    /**
+     * Creates a new asset.
+     *
+     * Prefixing a filter name with a question mark will cause it to be
+     * omitted when the factory is in debug mode.
+     *
+     * Available options:
+     *
+     *  * output: An output string
+     *  * name:   An asset name for interpolation in output patterns
+     *  * debug:  Forces debug mode on or off for this asset
+     *  * root:   An array or string of more root directories
+     *
+     * @param array|string $inputs  An array of input strings
+     * @param array|string $filters An array of filter names
+     * @param array        $options An array of options
+     *
+     * @return AssetCollection An asset collection
+     */
+    public function createAsset($inputs = array(), $filters = array(), array $options = array())
+    {
+        if (!is_array($inputs)) {
+            $inputs = array($inputs);
+        }
+
+        if (!is_array($filters)) {
+            $filters = array($filters);
+        }
+
+        if (!isset($options['output'])) {
+            $options['output'] = $this->output;
+        }
+
+        if (!isset($options['vars'])) {
+            $options['vars'] = array();
+        }
+
+        if (!isset($options['debug'])) {
+            $options['debug'] = $this->debug;
+        }
+
+        if (!isset($options['root'])) {
+            $options['root'] = array($this->root);
+        } else {
+            if (!is_array($options['root'])) {
+                $options['root'] = array($options['root']);
+            }
+
+            $options['root'][] = $this->root;
+        }
+
+        if (!isset($options['name'])) {
+            $options['name'] = $this->generateAssetName($inputs, $filters, $options);
+        }
+
+        $asset = $this->createAssetCollection(array(), $options);
+        $extensions = array();
+
+        // inner assets
+        foreach ($inputs as $input) {
+            if (is_array($input)) {
+                // nested formula
+                $asset->add(call_user_func_array(array($this, 'createAsset'), $input));
+            } else {
+                $asset->add($this->parseInput($input, $options));
+                $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true;
+            }
+        }
+
+        // filters
+        foreach ($filters as $filter) {
+            if ('?' != $filter[0]) {
+                $asset->ensureFilter($this->getFilter($filter));
+            } elseif (!$options['debug']) {
+                $asset->ensureFilter($this->getFilter(substr($filter, 1)));
+            }
+        }
+
+        // append variables
+        if (!empty($options['vars'])) {
+            $toAdd = array();
+            foreach ($options['vars'] as $var) {
+                if (false !== strpos($options['output'], '{'.$var.'}')) {
+                    continue;
+                }
+
+                $toAdd[] = '{'.$var.'}';
+            }
+
+            if ($toAdd) {
+                $options['output'] = str_replace('*', '*.'.implode('.', $toAdd), $options['output']);
+            }
+        }
+
+        // append consensus extension if missing
+        if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) {
+            $options['output'] .= '.'.$extension;
+        }
+
+        // output --> target url
+        $asset->setTargetPath(str_replace('*', $options['name'], $options['output']));
+
+        // apply workers and return
+        return $this->applyWorkers($asset);
+    }
+
+    public function generateAssetName($inputs, $filters, $options = array())
+    {
+        foreach (array_diff(array_keys($options), array('output', 'debug', 'root')) as $key) {
+            unset($options[$key]);
+        }
+
+        ksort($options);
+
+        return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7);
+    }
+
+    /**
+     * Parses an input string string into an asset.
+     *
+     * The input string can be one of the following:
+     *
+     *  * A reference:     If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager
+     *  * An absolute URL: If the string contains "://" or starts with "//" it will be interpreted as an HTTP asset
+     *  * A glob:          If the string contains a "*" it will be interpreted as a glob
+     *  * A path:          Otherwise the string is interpreted as a filesystem path
+     *
+     * Both globs and paths will be absolutized using the current root directory.
+     *
+     * @param string $input   An input string
+     * @param array  $options An array of options
+     *
+     * @return AssetInterface An asset
+     */
+    protected function parseInput($input, array $options = array())
+    {
+        if ('@' == $input[0]) {
+            return $this->createAssetReference(substr($input, 1));
+        }
+
+        if (false !== strpos($input, '://') || 0 === strpos($input, '//')) {
+            return $this->createHttpAsset($input, $options['vars']);
+        }
+
+        if (self::isAbsolutePath($input)) {
+            if ($root = self::findRootDir($input, $options['root'])) {
+                $path = ltrim(substr($input, strlen($root)), '/');
+            } else {
+                $path = null;
+            }
+        } else {
+            $root  = $this->root;
+            $path  = $input;
+            $input = $this->root.'/'.$path;
+        }
+
+        if (false !== strpos($input, '*')) {
+            return $this->createGlobAsset($input, $root, $options['vars']);
+        }
+
+        return $this->createFileAsset($input, $root, $path, $options['vars']);
+    }
+
+    protected function createAssetCollection(array $assets = array(), array $options = array())
+    {
+        return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array());
+    }
+
+    protected function createAssetReference($name)
+    {
+        if (!$this->am) {
+            throw new \LogicException('There is no asset manager.');
+        }
+
+        return new AssetReference($this->am, $name);
+    }
+
+    protected function createHttpAsset($sourceUrl, $vars)
+    {
+        return new HttpAsset($sourceUrl, array(), false, $vars);
+    }
+
+    protected function createGlobAsset($glob, $root = null, $vars)
+    {
+        return new GlobAsset($glob, array(), $root, $vars);
+    }
+
+    protected function createFileAsset($source, $root = null, $path = null, $vars)
+    {
+        return new FileAsset($source, array(), $root, $path, $vars);
+    }
+
+    protected function getFilter($name)
+    {
+        if (!$this->fm) {
+            throw new \LogicException('There is no filter manager.');
+        }
+
+        return $this->fm->get($name);
+    }
+
+    /**
+     * Filters an asset collection through the factory workers.
+     *
+     * Each leaf asset will be processed first, followed by the asset
+     * collection itself.
+     *
+     * @param AssetCollectionInterface $asset An asset collection
+     *
+     * @return AssetCollectionInterface
+     */
+    private function applyWorkers(AssetCollectionInterface $asset)
+    {
+        foreach ($asset as $leaf) {
+            foreach ($this->workers as $worker) {
+                $retval = $worker->process($leaf);
+
+                if ($retval instanceof AssetInterface && $leaf !== $retval) {
+                    $asset->replaceLeaf($leaf, $retval);
+                }
+            }
+        }
+
+        foreach ($this->workers as $worker) {
+            $retval = $worker->process($asset);
+
+            if ($retval instanceof AssetInterface) {
+                $asset = $retval;
+            }
+        }
+
+        return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset));
+    }
+
+    private static function isAbsolutePath($path)
+    {
+        return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2]));
+    }
+
+    /**
+     * Loops through the root directories and returns the first match.
+     *
+     * @param string $path  An absolute path
+     * @param array  $roots An array of root directories
+     *
+     * @return string|null The matching root directory, if found
+     */
+    private static function findRootDir($path, array $roots)
+    {
+        foreach ($roots as $root) {
+            if (0 === strpos($path, $root)) {
+                return $root;
+            }
+        }
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/ValueSupplierInterface.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/ValueSupplierInterface.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/ValueSupplierInterface.php	(revision 7265)
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+/**
+ * Value Supplier Interface.
+ *
+ * Implementations determine runtime values for compile-time variables.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface ValueSupplierInterface
+{
+    /**
+     * Returns a map of values.
+     *
+     * @return array
+     */
+    public function getValues();
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticTokenParser.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticTokenParser.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticTokenParser.php	(revision 7265)
@@ -0,0 +1,153 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+class AsseticTokenParser extends \Twig_TokenParser
+{
+    private $factory;
+    private $tag;
+    private $output;
+    private $single;
+    private $extensions;
+
+    /**
+     * Constructor.
+     *
+     * Attributes can be added to the tag by passing names as the options
+     * array. These values, if found, will be passed to the factory and node.
+     *
+     * @param AssetFactory $factory    The asset factory
+     * @param string       $tag        The tag name
+     * @param string       $output     The default output string
+     * @param Boolean      $single     Whether to force a single asset
+     * @param array        $extensions Additional attribute names to look for
+     */
+    public function __construct(AssetFactory $factory, $tag, $output, $single = false, array $extensions = array())
+    {
+        $this->factory    = $factory;
+        $this->tag        = $tag;
+        $this->output     = $output;
+        $this->single     = $single;
+        $this->extensions = $extensions;
+    }
+
+    public function parse(\Twig_Token $token)
+    {
+        $inputs = array();
+        $filters = array();
+        $name = null;
+        $attributes = array(
+            'output'   => $this->output,
+            'var_name' => 'asset_url',
+            'vars'     => array(),
+        );
+
+        $stream = $this->parser->getStream();
+        while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {
+            if ($stream->test(\Twig_Token::STRING_TYPE)) {
+                // '@jquery', 'js/src/core/*', 'js/src/extra.js'
+                $inputs[] = $stream->next()->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'filter')) {
+                // filter='yui_js'
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $filters = array_merge($filters, array_filter(array_map('trim', explode(',', $stream->expect(\Twig_Token::STRING_TYPE)->getValue()))));
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'output')) {
+                // output='js/packed/*.js' OR output='js/core.js'
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $attributes['output'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'name')) {
+                // name='core_js'
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $name = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'as')) {
+                // as='the_url'
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $attributes['var_name'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'debug')) {
+                // debug=true
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $attributes['debug'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'combine')) {
+                // combine=true
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $attributes['combine'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue();
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'vars')) {
+                // vars=['locale','browser']
+                $stream->next();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $stream->expect(\Twig_Token::PUNCTUATION_TYPE, '[');
+
+                while ($stream->test(\Twig_Token::STRING_TYPE)) {
+                    $attributes['vars'][] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+
+                    if (!$stream->test(\Twig_Token::PUNCTUATION_TYPE, ',')) {
+                        break;
+                    }
+
+                    $stream->next();
+                }
+
+                $stream->expect(\Twig_Token::PUNCTUATION_TYPE, ']');
+            } elseif ($stream->test(\Twig_Token::NAME_TYPE, $this->extensions)) {
+                // an arbitrary configured attribute
+                $key = $stream->next()->getValue();
+                $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+                $attributes[$key] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+            } else {
+                $token = $stream->getCurrent();
+                throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine());
+            }
+        }
+
+        $stream->expect(\Twig_Token::BLOCK_END_TYPE);
+
+        $body = $this->parser->subparse(array($this, 'testEndTag'), true);
+
+        $stream->expect(\Twig_Token::BLOCK_END_TYPE);
+
+        if ($this->single && 1 < count($inputs)) {
+            $inputs = array_slice($inputs, -1);
+        }
+
+        if (!$name) {
+            $name = $this->factory->generateAssetName($inputs, $filters, $attributes);
+        }
+
+        $asset = $this->factory->createAsset($inputs, $filters, $attributes + array('name' => $name));
+
+        return $this->createNode($asset, $body, $inputs, $filters, $name, $attributes, $token->getLine(), $this->getTag());
+    }
+
+    public function getTag()
+    {
+        return $this->tag;
+    }
+
+    public function testEndTag(\Twig_Token $token)
+    {
+        return $token->test(array('end'.$this->getTag()));
+    }
+
+    protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
+    {
+        return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterInvoker.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterInvoker.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterInvoker.php	(revision 7265)
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+/**
+ * Filters a single asset.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AsseticFilterInvoker
+{
+    private $factory;
+    private $filters;
+    private $options;
+
+    public function __construct($factory, $filter)
+    {
+        $this->factory = $factory;
+
+        if (is_array($filter) && isset($filter['filter'])) {
+            $this->filters = (array) $filter['filter'];
+            $this->options = isset($filter['options']) ? (array) $filter['options'] : array();
+        } else {
+            $this->filters = (array) $filter;
+            $this->options = array();
+        }
+    }
+
+    public function getFactory()
+    {
+        return $this->factory;
+    }
+
+    public function getFilters()
+    {
+        return $this->filters;
+    }
+
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    public function invoke($input, array $options = array())
+    {
+        $asset = $this->factory->createAsset($input, $this->filters, $options + $this->options);
+
+        return $asset->getTargetPath();
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticNode.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticNode.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticNode.php	(revision 7265)
@@ -0,0 +1,166 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Asset\AssetInterface;
+
+class AsseticNode extends \Twig_Node
+{
+    /**
+     * Constructor.
+     *
+     * Available attributes:
+     *
+     *  * debug:    The debug mode
+     *  * combine:  Whether to combine assets
+     *  * var_name: The name of the variable to expose to the body node
+     *
+     * @param AssetInterface      $asset      The asset
+     * @param \Twig_NodeInterface $body       The body node
+     * @param array               $inputs     An array of input strings
+     * @param array               $filters    An array of filter strings
+     * @param string              $name       The name of the asset
+     * @param array               $attributes An array of attributes
+     * @param integer             $lineno     The line number
+     * @param string              $tag        The tag name
+     */
+    public function __construct(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
+    {
+        $nodes = array('body' => $body);
+
+        $attributes = array_replace(
+            array('debug' => null, 'combine' => null, 'var_name' => 'asset_url'),
+            $attributes,
+            array('asset' => $asset, 'inputs' => $inputs, 'filters' => $filters, 'name' => $name)
+        );
+
+        parent::__construct($nodes, $attributes, $lineno, $tag);
+    }
+
+    public function compile(\Twig_Compiler $compiler)
+    {
+        $compiler->addDebugInfo($this);
+
+        $combine = $this->getAttribute('combine');
+        $debug = $this->getAttribute('debug');
+
+        if (null === $combine && null !== $debug) {
+            $combine = !$debug;
+        }
+
+        if (null === $combine) {
+            $compiler
+                ->write("if (isset(\$context['assetic']['debug']) && \$context['assetic']['debug']) {\n")
+                ->indent()
+            ;
+
+            $this->compileDebug($compiler);
+
+            $compiler
+                ->outdent()
+                ->write("} else {\n")
+                ->indent()
+            ;
+
+            $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name'));
+
+            $compiler
+                ->outdent()
+                ->write("}\n")
+            ;
+        } elseif ($combine) {
+            $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name'));
+        } else {
+            $this->compileDebug($compiler);
+        }
+
+        $compiler
+            ->write('unset($context[')
+            ->repr($this->getAttribute('var_name'))
+            ->raw("]);\n")
+        ;
+    }
+
+    protected function compileDebug(\Twig_Compiler $compiler)
+    {
+        $i = 0;
+        foreach ($this->getAttribute('asset') as $leaf) {
+            $leafName = $this->getAttribute('name').'_'.$i++;
+            $this->compileAsset($compiler, $leaf, $leafName);
+        }
+    }
+
+    protected function compileAsset(\Twig_Compiler $compiler, AssetInterface $asset, $name)
+    {
+        if ($vars = $asset->getVars()) {
+            $compiler->write("// check variable conditions\n");
+
+            foreach ($vars as $var) {
+                $compiler
+                    ->write("if (!isset(\$context['assetic']['vars']['$var'])) {\n")
+                    ->indent()
+                    ->write("throw new \RuntimeException(sprintf('The asset \"".$name."\" expected variable \"".$var."\" to be set, but got only these vars: %s. Did you set-up a value supplier?', isset(\$context['assetic']['vars']) && \$context['assetic']['vars'] ? implode(', ', \$context['assetic']['vars']) : '# none #'));\n")
+                    ->outdent()
+                    ->write("}\n")
+                ;
+            }
+
+            $compiler->raw("\n");
+        }
+
+        $compiler
+            ->write("// asset \"$name\"\n")
+            ->write('$context[')
+            ->repr($this->getAttribute('var_name'))
+            ->raw('] = ')
+        ;
+
+        $this->compileAssetUrl($compiler, $asset, $name);
+
+        $compiler
+            ->raw(";\n")
+            ->subcompile($this->getNode('body'))
+        ;
+    }
+
+    protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name)
+    {
+        if (!$vars = $asset->getVars()) {
+            $compiler->repr($asset->getTargetPath());
+
+            return;
+        }
+
+        $compiler
+            ->raw("strtr(")
+            ->string($asset->getTargetPath())
+            ->raw(", array(");
+        ;
+
+        $first = true;
+        foreach ($vars as $var) {
+            if (!$first) {
+                $compiler->raw(", ");
+            }
+            $first = false;
+
+            $compiler
+                ->string("{".$var."}")
+                ->raw(" => \$context['assetic']['vars']['$var']")
+            ;
+        }
+
+        $compiler
+            ->raw("))")
+        ;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigResource.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigResource.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigResource.php	(revision 7265)
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * A Twig template resource.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TwigResource implements ResourceInterface
+{
+    private $loader;
+    private $name;
+
+    public function __construct(\Twig_LoaderInterface $loader, $name)
+    {
+        $this->loader = $loader;
+        $this->name = $name;
+    }
+
+    public function getContent()
+    {
+        try {
+            return $this->loader->getSource($this->name);
+        } catch (\Twig_Error_Loader $e) {
+            return '';
+        }
+    }
+
+    public function isFresh($timestamp)
+    {
+        try {
+            return $this->loader->isFresh($this->name, $timestamp);
+        } catch (\Twig_Error_Loader $e) {
+            return false;
+        }
+    }
+
+    public function __toString()
+    {
+        return $this->name;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterFunction.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterFunction.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticFilterFunction.php	(revision 7265)
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+class AsseticFilterFunction extends \Twig_Function
+{
+    private $filter;
+
+    public function __construct($filter, $options = array())
+    {
+        $this->filter = $filter;
+
+        parent::__construct($options);
+    }
+
+    public function compile()
+    {
+        return sprintf('$this->env->getExtension(\'assetic\')->getFilterInvoker(\'%s\')->invoke', $this->filter);
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigFormulaLoader.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigFormulaLoader.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/TwigFormulaLoader.php	(revision 7265)
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Factory\Loader\FormulaLoaderInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Loads asset formulae from Twig templates.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TwigFormulaLoader implements FormulaLoaderInterface
+{
+    private $twig;
+
+    public function __construct(\Twig_Environment $twig)
+    {
+        $this->twig = $twig;
+    }
+
+    public function load(ResourceInterface $resource)
+    {
+        try {
+            $tokens = $this->twig->tokenize($resource->getContent(), (string) $resource);
+            $nodes  = $this->twig->parse($tokens);
+        } catch (\Exception $e) {
+            return array();
+        }
+
+        return $this->loadNode($nodes);
+    }
+
+    /**
+     * Loads assets from the supplied node.
+     *
+     * @param \Twig_Node $node
+     *
+     * @return array An array of asset formulae indexed by name
+     */
+    private function loadNode(\Twig_Node $node)
+    {
+        $formulae = array();
+
+        if ($node instanceof AsseticNode) {
+            $formulae[$node->getAttribute('name')] = array(
+                $node->getAttribute('inputs'),
+                $node->getAttribute('filters'),
+                array(
+                    'output'  => $node->getAttribute('asset')->getTargetPath(),
+                    'name'    => $node->getAttribute('name'),
+                    'debug'   => $node->getAttribute('debug'),
+                    'combine' => $node->getAttribute('combine'),
+                    'vars'    => $node->getAttribute('vars'),
+                ),
+            );
+        } elseif ($node instanceof \Twig_Node_Expression_Function) {
+            $name = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<')
+                ? $node->getNode('name')->getAttribute('name')
+                : $node->getAttribute('name');
+
+            if ($this->twig->getFunction($name) instanceof AsseticFilterFunction) {
+                $arguments = array();
+                foreach ($node->getNode('arguments') as $argument) {
+                    $arguments[] = eval('return '.$this->twig->compile($argument).';');
+                }
+
+                $invoker = $this->twig->getExtension('assetic')->getFilterInvoker($name);
+
+                $inputs  = isset($arguments[0]) ? (array) $arguments[0] : array();
+                $filters = $invoker->getFilters();
+                $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
+
+                if (!isset($options['name'])) {
+                    $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options);
+                }
+
+                $formulae[$options['name']] = array($inputs, $filters, $options);
+            }
+        }
+
+        foreach ($node as $child) {
+            if ($child instanceof \Twig_Node) {
+                $formulae += $this->loadNode($child);
+            }
+        }
+
+        return $formulae;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticExtension.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticExtension.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Extension/Twig/AsseticExtension.php	(revision 7265)
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\ValueSupplierInterface;
+use Assetic\Factory\AssetFactory;
+
+class AsseticExtension extends \Twig_Extension
+{
+    protected $factory;
+    protected $functions;
+    protected $valueSupplier;
+
+    public function __construct(AssetFactory $factory, $functions = array(), ValueSupplierInterface $valueSupplier = null)
+    {
+        $this->factory = $factory;
+        $this->functions = array();
+        $this->valueSupplier = $valueSupplier;
+
+        foreach ($functions as $function => $options) {
+            if (is_integer($function) && is_string($options)) {
+                $this->functions[$options] = array('filter' => $options);
+            } else {
+                $this->functions[$function] = $options + array('filter' => $function);
+            }
+        }
+    }
+
+    public function getTokenParsers()
+    {
+        return array(
+            new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js'),
+            new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css'),
+            new AsseticTokenParser($this->factory, 'image', 'images/*', true),
+        );
+    }
+
+    public function getFunctions()
+    {
+        $functions = array();
+        foreach ($this->functions as $function => $filter) {
+            $functions[$function] = new AsseticFilterFunction($function);
+        }
+
+        return $functions;
+    }
+
+    public function getGlobals()
+    {
+        return array(
+            'assetic' => array(
+                'debug' => $this->factory->isDebug(),
+                'vars'  => null !== $this->valueSupplier ? $this->valueSupplier->getValues() : array(),
+            ),
+        );
+    }
+
+    public function getFilterInvoker($function)
+    {
+        return new AsseticFilterInvoker($this->factory, $this->functions[$function]);
+    }
+
+    public function getName()
+    {
+        return 'assetic';
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Util/PathUtils.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Util/PathUtils.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Util/PathUtils.php	(revision 7265)
@@ -0,0 +1,31 @@
+<?php
+
+namespace Assetic\Util;
+
+/**
+ * Path Utils.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class PathUtils
+{
+    public static function resolvePath($path, array $vars, array $values)
+    {
+        $map = array();
+        foreach ($vars as $var) {
+            if (false === strpos($path, '{'.$var.'}')) {
+                continue;
+            }
+
+            if (!isset($values[$var])) {
+                throw new \InvalidArgumentException(sprintf('The path "%s" contains the variable "%s", but was not given any value for it.', $path, $var));
+            }
+
+            $map['{'.$var.'}'] = $values[$var];
+        }
+
+        return strtr($path, $map);
+    }
+
+    final private function __construct() { }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Util/TraversableString.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Util/TraversableString.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Util/TraversableString.php	(revision 7265)
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * An object that can be used as either a string or array.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TraversableString implements \IteratorAggregate, \Countable
+{
+    private $one;
+    private $many;
+
+    public function __construct($one, array $many)
+    {
+        $this->one = $one;
+        $this->many = $many;
+    }
+
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->many);
+    }
+
+    public function count()
+    {
+        return count($this->many);
+    }
+
+    public function __toString()
+    {
+        return (string) $this->one;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/Exception.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/Exception.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/Exception.php	(revision 7265)
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Exception;
+
+/**
+ * Marker.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface Exception
+{
+}
Index: sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/FilterException.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/FilterException.php	(revision 7265)
+++ sandbox/newExpressoMail/newExpressoMail/Assetic/Exception/FilterException.php	(revision 7265)
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2012 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Exception;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * Describes an exception that occurred within a filter.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class FilterException extends \RuntimeException implements Exception
+{
+    private $originalMessage;
+    private $input;
+
+    public static function fromProcess(Process $proc)
+    {
+        $message = sprintf("An error occurred while running:\n%s", $proc->getCommandLine());
+
+        $errorOutput = $proc->getErrorOutput();
+        if (!empty($errorOutput)) {
+            $message .= "\n\nError Output:\n".str_replace("\r", '', $errorOutput);
+        }
+
+        $output = $proc->getOutput();
+        if (!empty($output)) {
+            $message .= "\n\nOutput:\n".str_replace("\r", '', $output);
+        }
+
+        return new self($message);
+    }
+
+    public function __construct($message, $code = 0, \Exception $previous = null)
+    {
+        parent::__construct($message, $code, $previous);
+
+        $this->originalMessage = $message;
+    }
+
+    public function setInput($input)
+    {
+        $this->input = $input;
+        $this->updateMessage();
+
+        return $this;
+    }
+
+    public function getInput()
+    {
+        return $this->input;
+    }
+
+    private function updateMessage()
+    {
+        $message = $this->originalMessage;
+
+        if (!empty($this->input)) {
+            $message .= "\n\nInput:\n".$this->input;
+        }
+
+        $this->message = $message;
+    }
+}
Index: sandbox/newExpressoMail/newExpressoMail/index.php
===================================================================
--- sandbox/newExpressoMail/newExpressoMail/index.php	(revision 7212)
+++ sandbox/newExpressoMail/newExpressoMail/index.php	(revision 7265)
@@ -10,5 +10,5 @@
                                                    );
 						  
-        require_once( dirname(__FILE__).'/../prototype/api/config.php' );
+        //require_once( dirname(__FILE__).'/../prototype/api/config.php' );
         
         require_once (dirname(__FILE__).'/../header.inc.php');
@@ -26,4 +26,6 @@
         $imap_configs = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
 
+        include("inc/load_lang.php");
+
         define( 'MODULESURL' , '../prototype/modules/newMail' );
         define( 'PLUGINSURL' , '../prototype/plugins' );
Index: sandbox/newExpressoMail/prototype/services/ImapServiceAdapter.php
===================================================================
--- sandbox/newExpressoMail/prototype/services/ImapServiceAdapter.php	(revision 7209)
+++ sandbox/newExpressoMail/prototype/services/ImapServiceAdapter.php	(revision 7265)
@@ -76,6 +76,9 @@
 			case 'folder':
 			{
-				
-				$result = $this->getFolders();
+
+                if($context != '')
+                    $result = $this->getFolderInfo($context['folder']);
+                else
+                    $result = $this->getFolders();
 
 				foreach ($result as $res) {
@@ -86,5 +89,5 @@
 							'commonName' => mb_convert_encoding( $res['folder_name'], 'UTF-8' , 'UTF7-IMAP' ),
 							'parentFolder' => mb_convert_encoding( $res['folder_parent'], 'UTF-8' , 'UTF7-IMAP' ),
-							'messageCount' => array('unseen' => isset($res['folder_unseen']) ? $res['folder_unseen'] : null, 'total' => null)
+							'messageCount' => array('unseen' => isset($res['folder_unseen']) ? $res['folder_unseen'] : null, 'total' => $res['folder_total'])
 					);
 
@@ -104,9 +107,10 @@
 				$limit = isset($criteria['rows']) ? $criteria['rows'] : 10 ; //{10}   get how many rows we want to have into the grid
 				$sidx  = isset($criteria['sidx']) ? $criteria['sidx'] : 0; //{id}   get index row - i.e. user click to sort
-				$sord  = isset($criteria['sord']) ? $criteria['sord'] : ''; //{desc} get the direction
+				$sord  = $criteria['sord'] == "asc"? "0" : '1'; //{desc} get the direction
+                //$flag = $criteria['_search'] ? $criteria['_search'] : 'ALL';
 
 				$filter =  isset($criteria['filter']) ? $criteria['filter'] : '';
 
-				if( !$sidx ) $sidx = 1;
+				if( !$sidx ) $sidx = 'SORTARRIVAL';
 
 				$folder_name =  isset($URI['folder']) ?  $URI['folder'] : str_replace( '.', $this->imap_delimiter, isset($context['folder']) ?  $context['folder'] : 'INBOX');
@@ -207,7 +211,7 @@
 							'msg_range_begin' => $start + 1, //??
 							'msg_range_end' => $start + $limit, //$limit = $_GET['rows']; // get how many rows we want to have into the grid
-							'sort_box_type' => 'SORTARRIVAL', 
+							'sort_box_type' => $sidx,
 							'search_box_type' => 'ALL',
-							'sort_box_reverse' => 1 
+							'sort_box_reverse' => $sord
 						) 
 					);
@@ -698,6 +702,20 @@
 			case 'folder':
 			{
-
-			}
+                $mbox_stream = $this->open_mbox();
+                $path = ($data['path'] != "" ? $data['path'] : "INBOX") .$this->imap_delimiter;
+                $folders = explode($this->imap_delimiter,$data['name']);
+                $return = true;
+                for($i =0; $i < count($folders); $i++){
+                    $path .= $folders[$i] != "" ? $folders[$i] : 'Nova Pasta';
+                    $newFolder = mb_convert_encoding($path, "UTF7-IMAP","UTF-8");
+                    $serverString = "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$newFolder;
+                    if(imap_createmailbox($mbox_stream,$serverString))
+                    {
+                        $return = false;
+                    }
+                    $path .= $this->imap_delimiter;
+                }
+                return $return;
+            }
 		}
 	}
@@ -790,7 +808,17 @@
 						break;
 				}
-				
 				return $s;
 			}
+            case 'folder':{
+                $newFolder = mb_convert_encoding($URI['id'], "UTF7-IMAP","UTF-8");
+                $serverString = "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$newFolder;
+                $mbox_stream = $this->open_mbox();
+                if(imap_deletemailbox($mbox_stream,$serverString))
+                {
+                    return true;
+                }else{
+                    return false;
+                }
+            }
 		}
 
@@ -822,4 +850,20 @@
 		 * atributos gravados no banco de dados e nunca no IMAP.
 		 */
+        switch( $URI['concept'] )
+        {
+            case 'folder':
+            {
+                $mbox_stream = $this->open_mbox();
+                $oldFolderName = mb_convert_encoding($data['id'], "UTF7-IMAP","UTF-8");
+                $newFolderName = mb_convert_encoding($data['new'], "UTF7-IMAP","UTF-8");
+                $serverString = "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}";
+                if(imap_renamemailbox($mbox_stream,$serverString.$oldFolderName, $serverString.$newFolderName))
+                {
+                    return true;
+                }else{
+                    return false;
+                }
+            }
+        }
 	}
 
Index: sandbox/newExpressoMail/prototype/config/folder.ini
===================================================================
--- sandbox/newExpressoMail/prototype/config/folder.ini	(revision 5341)
+++ sandbox/newExpressoMail/prototype/config/folder.ini	(revision 7265)
@@ -1,1 +1,4 @@
 service = Imap
+
+[Imap.mapping]
+folderName = folder_name
Index: sandbox/newExpressoMail/prototype/modules/newMail/css/main.css
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/css/main.css	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/css/main.css	(revision 7265)
@@ -1178,5 +1178,5 @@
 
 .folders-loading {
-	background: url(../../../prototype/modules/mail/img/loader.gif) !important;
+	background: url(../../../modules/mail/img/loader.gif) !important;
 	background-position: 0 0 !important;
 	background-repeat : no-repeat !important;
@@ -1201,5 +1201,5 @@
 .draggin-mail{
 	float: left;
-	background-image: url(../../../prototype/modules/mail/img/move.png);
+	background-image: url(../img/move.png);
 	background-position: 0px 0px;
 	background-repeat:no-repeat;
@@ -1215,5 +1215,5 @@
 .draggin-folder{
 	float: left;
-	background-image: url(../../../prototype/modules/mail/img/folder.png);
+	background-image: url(../img/folder.png);
 	background-position: 0px 0px;
 	background-repeat:no-repeat;
@@ -1347,5 +1347,5 @@
 
 .loading {
-	background: url(../../../prototype/modules/mail/img/loader.gif) !important;
+	background: url(../../../modules/mail/img/loader.gif) !important;
 	background-position: 0 0 !important;
 	background-repeat : no-repeat !important;
@@ -1473,2 +1473,7 @@
 	margin: 5px 5px 0 -5px;
 }
+
+
+.ZebraDialog .ZebraDialog_Buttons .ZebraDialog_ButtonSelected{
+    border-color: #1B75BB;
+}
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/message.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/message.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/message.js	(revision 7265)
@@ -1,108 +1,108 @@
 function buildMessageButtons(content){
-	var data = getTabData();
-	//FLAGS BUTTON SET 
+    var data = getTabData();
+    //FLAGS BUTTON SET
     content.find(".message-flags").find(".message-important-flag").button({
-    	icons: {
-    		primary: "ui-icon-notice"
-    	},
+        icons: {
+            primary: "ui-icon-notice"
+        },
         text: false
     }).click(function(){
-    	var checked = $(this).attr("checked") == "checked" ? true : false;
-    	set_message_flag(data.id, checked ? "flagged" : "unflagged", undefined, data.folder);
-    	write_msg(get_lang('Message marked as ') + get_lang( checked ? "Important" : "Normal"));
-    	refresh();
-    }).end().find(".message-unread-flag").button({
-    	icons: {
-    		primary: "ui-icon-mail-closed"
-    	},
-        text: false
-    }).click(function(){
-    	var checked = $(this).attr("checked") == "checked" ? true : false;
-    	set_message_flag(data.id, checked ? "unseen" : "seen", undefined, data.folder);
-    	write_msg(get_lang('Message marked as ') + get_lang( checked ? "Unseen" : "Seen"));
-    	refresh();
-    }).end().find(".message-spam-flag").button({
-    	icons: {
-    		primary: "ui-icon-alert"
-    	},
-        text: false	
-    }).click(function(){
-    	var checked = $(this).attr("checked") == "checked" ? true : false;
-    	checked ? spam(data.folder, data.id,'null') : nospam(data.id,'null', data.folder);
-    	removeTab();
-    	refresh();
-    }).end().find(".message-followup-flag").button({
-    	icons: {
-    		primary: "ui-icon-flag"
-    	},
-        text: false
-    });
+            var checked = $(this).attr("checked") == "checked" ? true : false;
+            set_message_flag(data.id, checked ? "flagged" : "unflagged", undefined, data.folder);
+            write_msg(get_lang('Message marked as ') + get_lang( checked ? "Important" : "Normal"));
+            refresh();
+        }).end().find(".message-unread-flag").button({
+            icons: {
+                primary: "ui-icon-mail-closed"
+            },
+            text: false
+        }).click(function(){
+            var checked = $(this).attr("checked") == "checked" ? true : false;
+            set_message_flag(data.id, checked ? "unseen" : "seen", undefined, data.folder);
+            write_msg(get_lang('Message marked as ') + get_lang( checked ? "Unseen" : "Seen"));
+            refresh();
+        }).end().find(".message-spam-flag").button({
+            icons: {
+                primary: "ui-icon-alert"
+            },
+            text: false
+        }).click(function(){
+            var checked = $(this).attr("checked") == "checked" ? true : false;
+            checked ? spam(data.folder, data.id,'null') : nospam(data.id,'null', data.folder);
+            removeTab();
+            refresh();
+        }).end().find(".message-followup-flag").button({
+            icons: {
+                primary: "ui-icon-flag"
+            },
+            text: false
+        });
     content.find(".message-flags").buttonset();
 
     //MESSAGES ACTION NEXT PREV BUTTON SET
     content.find(".messages-controll").find(".message-prev").button({
-    	icons: {
-    		primary: "ui-icon-carat-1-w"
-    	},
+        icons: {
+            primary: "ui-icon-carat-1-w"
+        },
         text: false
     }).click(function(){
 
-    }).next().button({
-    	icons: {
-    		primary: "ui-icon-carat-1-e"
-    	},
-        text: false
-    });
+        }).next().button({
+            icons: {
+                primary: "ui-icon-carat-1-e"
+            },
+            text: false
+        });
     content.find(".messages-controll").buttonset();
 
     //
     content.find(".message-forward").button({
-    	icons:{
-    		primary: "ui-icon-arrowreturnthick-1-e"
-    	},
-    	text : false
-    });
-
-	var teste = content.find(".message-reply-menu-content").clone();
-	content.find(".message-reply-menu-content").remove();
+        icons:{
+            primary: "ui-icon-arrowreturnthick-1-e"
+        },
+        text : false
+    });
+
+    var teste = content.find(".message-reply-menu-content").clone();
+    content.find(".message-reply-menu-content").remove();
 
     content.find(".button.message-reply").button({
-    	icons:{
-    		primary: "ui-icon-arrowreturnthick-1-w"
-    	},
-    	text : false
+        icons:{
+            primary: "ui-icon-arrowreturnthick-1-w"
+        },
+        text : false
     }).next().button({
-    	icons:{
-    		primary: "ui-icon-triangle-1-s"
-    	},
-    	text : false
-    }).parent().buttonset();
-
-	content.find("span.message-reply").append(teste);
-
-	content.find(".message-reply").next().menuPlugin({
-		content : content.find(".message-reply-menu-content").html(),
-		positionOpts: {
-			posX: 'left', 
-			posY: 'bottom',
-			offsetX: -140,
-			offsetY: 0,
-			directionH: 'right',
-			directionV: 'down', 
-			detectH: true, // do horizontal collision detection  
-			detectV: true, // do vertical collision detection
-			linkToFront: false
-		},
-		flyOut: true,
-		showSpeed: 100,
-		crumbDefaultText: '>'
-	});
+            icons:{
+                primary: "ui-icon-triangle-1-s"
+            },
+            text : false
+        }).parent().buttonset();
+
+    content.find("span.message-reply").append(teste);
+
+    content.find(".message-reply").next().menuPlugin({
+        content : content.find(".message-reply-menu-content").html(),
+        positionOpts: {
+            posX: 'left',
+            posY: 'bottom',
+            offsetX: -140,
+            offsetY: 0,
+            directionH: 'right',
+            directionV: 'down',
+            detectH: true, // do horizontal collision detection
+            detectV: true, // do vertical collision detection
+            linkToFront: false
+        },
+        flyOut: true,
+        showSpeed: 100,
+        crumbDefaultText: '>'
+    });
 
 
     content.find(".button.message-edit").button({
-    	icons:{
-    		primary: "ui-icon-pencil"
-    	},
-    	text : false
+        icons:{
+            primary: "ui-icon-pencil"
+        },
+        text : false
     });
     //BUTTON MORE AND TAGS
@@ -114,53 +114,53 @@
         text: false
     }).next().next().button({
-        icons: {
-            secondary: "ui-icon-triangle-1-s"
-        },
-        text: true
- 	});
-
-	content.find(".message-more").menuPlugin({
-		content : content.find(".message-more-menu-content").html(),
-		flyOut: true,
-		positionOpts: {
-			posX: 'left', 
-			posY: 'bottom',
-			offsetX: -140,
-			offsetY: 0,
-			directionH: 'right',
-			directionV: 'down', 
-			detectH: true, // do horizontal collision detection  
-			detectV: true, // do vertical collision detection
-			linkToFront: false
-		},
-		showSpeed: 100,
-		crumbDefaultText: '>'
-	});
- 		
-	content.find(".message-tags-menu-content ul li").remove();
-	$.each(getLabels(), function(key,value){
-		content.find(".message-tags-menu-content ul")
-		.append("<li id='"+key+"'><a onclick='labeledMessages("+
-			(key.match(/label(.*)/) ? key.match(/label(.*)/)[1] : 'configureLabels({applyToSelectedMessages:true})')
-		+");' href='#'>"+value.name+"</a></li>").find("li:last");
-	});
-
-	content.find(".message-tags").menuPlugin({
-		content : content.find(".message-tags-menu-content").html(),
-		flyOut: true,
-		positionOpts: {
-			posX: 'left', 
-			posY: 'bottom',
-			offsetX: -140,
-			offsetY: 0,
-			directionH: 'right',
-			directionV: 'down', 
-			detectH: true, // do horizontal collision detection  
-			detectV: true, // do vertical collision detection
-			linkToFront: false
-		},
-		showSpeed: 100,
-		crumbDefaultText: '>'
-	});
+            icons: {
+                secondary: "ui-icon-triangle-1-s"
+            },
+            text: true
+        });
+
+    content.find(".message-more").menuPlugin({
+        content : content.find(".message-more-menu-content").html(),
+        flyOut: true,
+        positionOpts: {
+            posX: 'left',
+            posY: 'bottom',
+            offsetX: -140,
+            offsetY: 0,
+            directionH: 'right',
+            directionV: 'down',
+            detectH: true, // do horizontal collision detection
+            detectV: true, // do vertical collision detection
+            linkToFront: false
+        },
+        showSpeed: 100,
+        crumbDefaultText: '>'
+    });
+
+    content.find(".message-tags-menu-content ul li").remove();
+    $.each(getLabels(), function(key,value){
+        content.find(".message-tags-menu-content ul")
+            .append("<li id='"+key+"'><a onclick='labeledMessages("+
+            (key.match(/label(.*)/) ? key.match(/label(.*)/)[1] : 'configureLabels({applyToSelectedMessages:true})')
+            +");' href='#'>"+value.name+"</a></li>").find("li:last");
+    });
+
+    content.find(".message-tags").menuPlugin({
+        content : content.find(".message-tags-menu-content").html(),
+        flyOut: true,
+        positionOpts: {
+            posX: 'left',
+            posY: 'bottom',
+            offsetX: -140,
+            offsetY: 0,
+            directionH: 'right',
+            directionV: 'down',
+            detectH: true, // do horizontal collision detection
+            detectV: true, // do vertical collision detection
+            linkToFront: false
+        },
+        showSpeed: 100,
+        crumbDefaultText: '>'
+    });
     //REMOVE MESSAGE BUTTON
     content.find(".message-remove").button({
@@ -170,8 +170,8 @@
         text: false
     }).click(function(){
-    	proxy_mensagens.delete_msgs(data.folder,data.id,'null');
-    	removeTab();
-    	refresh();
-    });
+            proxy_mensagens.delete_msgs(data.folder,data.id,'null');
+            removeTab();
+            refresh();
+        });
 
     //PREFERENCES BUTTON
@@ -186,14 +186,56 @@
     //MESSAGE DETAILS 
     content.find(".message-hide-show-details").click(function(){
-    	$(this).find("span").toggle();
-    	content.find(".message-details").toggle("blind");
+        $(this).find("span").toggle();
+        content.find(".message-details").toggle("blind");
     }).hover(
-		function(){
-			$(this).addClass("message-detail-hover");
-		},
-		function(){
-			$(this).removeClass("message-detail-hover");
-		}
-	);
+        function(){
+            $(this).addClass("message-detail-hover");
+        },
+        function(){
+            $(this).removeClass("message-detail-hover");
+        }
+    );
 
 }
+
+var Message = {
+    open : function(id){
+
+    },
+
+    remove : function(ids){
+
+    },
+
+    flag : function(id, flag){
+
+    },
+
+    move : function(id){
+
+    },
+
+    print : function (){
+
+    },
+
+    report : function(id){
+
+    },
+
+    reply : function(id, type){
+
+    },
+
+    forward : function(id){
+
+    },
+
+    export : function(id){
+
+    },
+
+    create : function(id){
+
+    }
+}
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/newfoldertree.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/newfoldertree.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/newfoldertree.js	(revision 7265)
@@ -5,507 +5,467 @@
 var cp_tree2;
 function unorphanize(root, element) {
-	var ok = false;
-	var f = 0;
-	for (var i=0; i<root.length; i++) {
-		if (root[i].id == element.parentFolder) {
-			element.children = new Array(); 
-			root[i].children.push(element);
-			return true;
-		} else if (ok = unorphanize(root[i].children, element)) {
-			break;
-		}
-	}
-	return ok;
+    var ok = false;
+    var f = 0;
+    for (var i=0; i<root.length; i++) {
+        if (root[i].id == element.parentFolder) {
+            element.children = new Array();
+            root[i].children.push(element);
+            return true;
+        } else if (ok = unorphanize(root[i].children, element)) {
+            break;
+        }
+    }
+    return ok;
 }
 
 function count_unseen_children(folder){
-	if(folder.children.length){
-		for(var i=0; i< folder.children.length; i++){
-			if(folder.children[i].children.length)
-				folder.children[i]['children_unseen'] = (folder.children[i]['children_unseen'] ? folder.children[i]['children_unseen'] : 0) + count_unseen_children(folder.children[i]);
-			
-			folder['children_unseen'] = (folder['children_unseen'] ? folder['children_unseen'] : 0)+ (folder.children[i]['children_unseen'] ? folder.children[i]['children_unseen'] : 0) + parseInt(folder.children[i].messageCount.unseen);			
-		}
-		return folder['children_unseen'];
-	}else{
-		return parseInt(folder.messageCount.unseen);
-	}
+    if(folder.children.length){
+        for(var i=0; i< folder.children.length; i++){
+            if(folder.children[i].children.length)
+                folder.children[i]['children_unseen'] = (folder.children[i]['children_unseen'] ? folder.children[i]['children_unseen'] : 0) + count_unseen_children(folder.children[i]);
+
+            folder['children_unseen'] = (folder['children_unseen'] ? folder['children_unseen'] : 0)+ (folder.children[i]['children_unseen'] ? folder.children[i]['children_unseen'] : 0) + parseInt(folder.children[i].messageCount.unseen);
+        }
+        return folder['children_unseen'];
+    }else{
+        return parseInt(folder.messageCount.unseen);
+    }
 }
 
 function valid_tabs(children_of_this_folder, folder_to_move){
-	var borders_open = $("#border_tr").children();
-
-	var error = false;
-	for(var i = 1; i <= borders_open.length -2; i ++){
-		//VERIFICA A CADA FILHO DA PASTA SE ESTA eventNSAGEM E DESTA PASTA
-		$.each(children_of_this_folder, function(index, value){
-			if($(children_of_this_folder[index]).attr('id') == openTab.imapBox[$(borders_open[i]).find("input[type=hidden]").attr("name")]){
-				error = true;
-				write_msg(get_lang("One or more messages from any sub-folder are open"));
-				return error;
-				
-			}
-		});
-		if(error){
-			return error;
-		}
-		//VERIFICA SE EXISTE NA PASTA A SER MOVIDA
-		if(openTab.imapBox[$(borders_open[i]).find("input[type=hidden]").attr("name")] == folder_to_move){
-			error = true;
-			write_msg(get_lang("One or more messages from this folder are open"));
-			return error;
-		}
-	}
+    var borders_open = $("#border_tr").children();
+
+    var error = false;
+    for(var i = 1; i <= borders_open.length -2; i ++){
+        //VERIFICA A CADA FILHO DA PASTA SE ESTA eventNSAGEM E DESTA PASTA
+        $.each(children_of_this_folder, function(index, value){
+            if($(children_of_this_folder[index]).attr('id') == openTab.imapBox[$(borders_open[i]).find("input[type=hidden]").attr("name")]){
+                error = true;
+                alert(("One or more messages from any sub-folder are open"));
+                return error;
+
+            }
+        });
+        if(error){
+            return error;
+        }
+        //VERIFICA SE EXISTE NA PASTA A SER MOVIDA
+        if(openTab.imapBox[$(borders_open[i]).find("input[type=hidden]").attr("name")] == folder_to_move){
+            error = true;
+            alert(("One or more messages from this folder are open"));
+            return error;
+        }
+    }
 }
 
 function draw_new_tree_folder(callback){
-	
-	var folders = DataLayer.get("folder", true);
-	
-	if(!selected){
-		selected = "INBOX";
-	}
-	/*
-	if( folders )
-	{
-	    folders = $.map( folders, function( folder ){
-		  return {
-		    id: folder.folder_id,
-		    commonName: folder.folder_name,
-		    parentFolder: folder.folder_parent === "root" ? "" : folder.folder_parent,
-		    messageCount: { total : '', unseen : '0' }
-		  };
-	    });
-	}
-	else
-	    folders = DataLayer.get("folder", true);
-	*/
-	var tree1 = new Array();
-	var tree2 = new Array();
-	var tree3 = new Array();
-	for (var i=0; i<folders.length; i++) {
-		if (/^INBOX/.test(folders[i].id)) {
-			if (!unorphanize(tree1, folders[i])) {
-				folders[i].children = new Array();
-				tree1.push(folders[i]);
-			}
-		}
-		else if (/^user/.test(folders[i].id)) {
-			if (!unorphanize(tree2, folders[i])) {
-				folders[i].children = new Array();
-				tree2.push(folders[i]);
-			}
-		}
-		else if (/^local_messages/.test(folders[i].id)) {
-			if (!unorphanize(tree3, folders[i])) {
-				folders[i].children = new Array();
-				tree3.push(folders[i]);
-			}
-		}
-	}
-	
-	for(var i =0; i<tree1.length; i++){
-		count_unseen_children(tree1[i]);
-	}
-	for(var i =0; i<tree2.length; i++){
-		count_unseen_children(tree2[i]);
-	}
-	for(var i =0; i<tree3.length; i++){
-		count_unseen_children(tree3[i]);
-	}
-	cp_tree1 = tree1;
-	cp_tree2 = tree2;
-	var shared_acls = {};
-
-	$.each(cp_tree2, function(index, value){
-		shared_acls[value.id] = value.acl_share;
-	});
-
-	var html = DataLayer.render('templates/detailedfoldertree.ejs', {folders: [tree1, tree2, tree3]});
-	var folders_html = $(".imap-folders").html(html).find(".mainfoldertree").treeview({
-			persist: "cookie",
-			animated: "fast"
-	}).find(".folder").unbind("click").click(function(event){
-		
-		// MUDANÃA DE PASTAS!
-		var target = $(this);	
-		
-		if($(".folders-loading").length)
-			return;
-		
-		if($(event.target).parent().is(".float-menu"))
-			return;
-			
-		if( target.is('.collapsable-hitarea, .expandable-hitarea, .lastCollapsable-hitarea, .lastExpandable-hitarea, .treeview ,.folder_unseen,.ui-icon, .float-menu, .new_folder, .folders-loading, .head_folder, .shared-folders') )
-			return;
-		
-		if( target.parent().find(".new_folder").length)
-			return;
-			
-		if( !target.attr('id') )
-			target = target.parent();
-		if (target[0] == $(".mainfoldertree")[0]) return;
-		var uiId = target.attr('id');
-		var child = target.find('.folder');
-		  
-		if(!target.is('.mainfoldertree > .expandable-hitarea, .mainfoldertree > .collapsable-hitarea')){
-			$('.filetree span.folder.selected').removeClass('selected');
-			$(target).children('.folder').addClass('selected');
-		}
-		$(this).addClass("folders-loading");
-		selected = target.attr('id');
-
-		changeFolder(target.attr('id'), child.attr('title'));	
-
-		/*$.ajax({
-			  url : "controller.php?"+ $.param( { action: "$this.imap_functions.get_folders_list", folder: target.attr('id') } ),
-			  success : function(data){
-				  data = connector.unserialize(data);
-
-				  if(data)
-				    build_quota(data);
-			  }
-		});*/
-		$(".folders-loading").removeClass("folders-loading");
-
-	}).filter('.followup-messages').click(function(event, ui){
-		search_emails("UNDELETED KEYWORD \"$Followupflagged\"");
-	}).end().end();
-	
-	folders_html.find('[id="'+selected+'"]').children().addClass("selected");
-	$(".folder").not(".head_folder").not(".shared-folders").parent().find(".folder").not(".head_folder,.inbox,.drafts,.sent,.spam,.trash").draggable({
-		// DRAG DE PASTAS
-		start : function(){
-			$(this).css("color", "gray");
-		},
-		stop : function(){
-			$(this).css("color", "");
-		},
-		revert: "invalid",
-		helper: function(event){
-			if($.trim(($(this).text().split("["))[0]).length > 18)
-				return $(DataLayer.render('../prototype/modules/mail/templates/draggin_box.ejs', {texto : (($(this).text().split("["))[0]).substring(0,18) + "...", type: "folder"}));
-			return $(DataLayer.render('../prototype/modules/mail/templates/draggin_box.ejs', {texto : (($(this).text().split("["))[0]), type: "folder"}));
-		},
-		delay: 150,
-		refreshPositions: true,
-		zIndex : 2700,
-		//scroll: true, 
-		//scrollSensitivity: 100,
-		//scrollSpeed: 100,
-		containment: "#divAppbox" 
-	}).end().droppable({
-		//DROP DE PASTAS
-		over : function(a, b){
-			//INICIO : SE A PASTA CONTER FILHAS EXPANDE 
-			over = $(this);
-			$(this).addClass("folder-over");
-			if(($(this)[0] != $(this).parent().find(".head_folder")[0]))
-				if($(this).prev()[0])
-					if($(this).parent().find(".expandable-hitarea")[0] == $(this).prev()[0]){
-						setTimeout(function(){
-							if(over.hasClass("folder-over"))
-								over.prev().trigger("click");
-						}, 500);
-						
-					}
-			//FIM : SE A PASTA CONTER FILHAS EXPANDE
-			
-			//SETA BORDA EM VOLTA DA PASTA
-		},
-		out : function(){
-			//RETIRA BORDA EM VOLTA DA PASTA
-			$(this).removeClass("folder-over");
-		},
-		drop : function(event, ui){
-			$(this).removeClass("folder-over");
-			if($(this).parent().attr('id') == undefined){
-				var folder_to = 'INBOX';
-				var to_folder_title = get_lang("Inbox");
-			}else{
-				var folder_to = $(this).parent().attr('id');
-				var to_folder_title = $(this).attr('title');
-			}		
-			var folder_to_move = ui.draggable.parent().attr('id');
-			var border_id = ui.draggable.find("input[type=hidden]").attr("name");
-			// eventnsagens : SE O DROP VIER DA LISTA DE eventNSAGENS :
-			if(folder_to_move == "tbody_box"){
-				move_msgs2(get_current_folder(), 'selected', 0, folder_to, to_folder_title,true);
-				return refresh();
-			}
-			//SE FOR DE UMA PESQUISA RAPIDA
-			else if(ui.draggable.parents('[id^="content_id_"]')[0]){
-				move_search_msgs("content_id_"+border_id, folder_to, to_folder_title);
-				return refresh();
-			}
-			// eventnsagens : SE O DROP VIER DE UMA ABA ABERTA
-			else if(folder_to_move == "border_tr"){
-				var id_msg = border_id.split("_")[0];
-				folder = $("#input_folder_"+border_id+"_r")[0] ? $("#input_folder_"+border_id+"_r").val() : (openTab.imapBox[border_id] ? openTab.imapBox[border_id]:get_current_folder());
-				alternate_border(border_id);
-				move_msgs2(folder, id_msg, border_id, folder_to, to_folder_title,true);
-				return refresh();
-			}
-			// SE O DROP VIER DA LISTA DE PASTAS
-			else{
-				var folder_to_exist = folder_to_move.split(imap_configs.imapDelimiter);	
-				folder_to_exist = folder_to+imap_configs.imapDelimiter+folder_to_exist[folder_to_exist.length-1];
-				
-				//VERIFICA SE EXISTE UMA eventNSAGENS ABERTA NESTA PASTA E NAS SUAS FILHAS
-
-				if(valid_tabs(ui.draggable.parent().find("li"), folder_to_move)){
-					return;
-				}
-				//FIM : VERIFICA SE EXISTE UMA eventNSAGENS ABERTA NESTA PASTA E NAS SUAS FILHAS;
-				
-				// VALIDA SE O USUARIO ESTA TENTANDO MOVER A PASTA PARA O eventSMO LOCAL
-				if(folder_to_exist == folder_to_move){
-					return write_msg(get_lang("Thie folder is already in this place"));
-				}
-				
-				// VALIDA SE O USUARIO ESTA TENTANDO MOVER A PASTA ABERTA NO momentO
-				if(folder_to_move == get_current_folder()){
-					return write_msg(get_lang("It's not possible move this folder, because it is being used in the moment!"));
-				}
-				
-				// VALIDA SE O USUARIO ESTA TENTANDO MOVER UMA PASTA FILHA DA PASTA ABERTA NO momentO
-				if(ui.draggable.parent().find(".selected")[0]){
-					return write_msg(get_lang("It's not possible move this folder, because its subfolder is being used in the moment!"));
-				}
-				
-				// VALIDA SE O USUARIO ESTA TENTANDO MOVER UMA PASTA PAI PARA DENTRO DE UMA FILHA
-				if(ui.draggable.parent().find('[id="'+folder_to+'"]')[0]){
-					return write_msg(get_lang("It's not possible to move this folder to its subfolders!"));
-				}					
-				
-				if($('[id="'+folder_to_exist+'"]').length){
-					return write_msg(get_lang("Can not move this folder to this location, because the target has already a folder with this name"));
-				}
-				
-				$(this).addClass("folders-loading");
-				
-				$.ajax({
-					url : "controller.php?"+ $.param( { action: "$this.imap_functions.move_folder", folder_to_move: folder_to_move, folder_to: folder_to } ),
-					success : function(data){
-						cExecute("$this.imap_functions.get_folders_list&onload=true", update_menu);
-						data = connector.unserialize(data);
-						if(data == "Permission denied"){
-							write_msg(get_lang("Permission denied"));
-						}else if(data){
-							write_msg(get_lang("The folder was successfully moved"));
-						}
-						else{
-							write_msg(get_lang("ERROR moving your folder."));
-						}
-					}
-				});
-			}
-		}
-	});
-	$(".folder").not(".shared-folders").parent().find(".folder").hover(
-		function(){
-			//CASO A LI NÃO TENHA UM eventNU FLUTUANTE AINDA, O eventNU Ã ADICIONADO!
-			if(!$(this).children(":last").hasClass("float-menu") && !$(this).children(":last").hasClass("new_folder")){
-				var folder_ = $(this);
-				var folder_name;
-				var shared = {
-					head : false,
-					valid : false
-				};
-				if(folder_.parent().attr('id')){
-					folder_name = folder_.parent().attr('id').split(imap_configs.imapDelimiter);
-					folder_name = folder_name[folder_name.length -1];
-					shared.valid = folder_.parent().attr('id').search("user/") == 0 ? true : false;
-				}else
-					folder_name = "Root";
-				
-				if(shared.valid){
-					shared.head = folder_.parent().attr('id').split(imap_configs.imapDelimiter).length == 2 ?  true : false;
-					var folder_name_parts = folder_.parent().attr('id').split(imap_configs.imapDelimiter);
-					var acls = shared_acls[folder_name_parts[0]+imap_configs.imapDelimiter+folder_name_parts[1]];
-
-				}
-
-				html = DataLayer.render("/templates/float_folder_menu.ejs", {name_folder : folder_name, flag : shared, acl : acls});					
-					//FUNÃÃO DO eventNU FLUTUANTE EDITAR < BEGIN
-				var esc = false;
-				$(folder_).append(html).find(".float-menu-edit").click(function(){
-					var folder_id = $(this).parents(".closed:first").attr('id');
-					var name = $.trim($(this).parents(".closed:first").find("span:first").text().split("[")[0]);
-					if($(this).parents(".closed:first").find("span:first").hasClass("selected"))
-						return write_msg(get_lang("It's not possible rename this folder, because it is being used in the moment!"));
-					if($(this).parents(".closed:first").find(".selected").length)
-						return write_msg(get_lang("It's not possible rename this folder, because its subfolder is being used in the moment!")); 
-					if(valid_tabs($(this).parents("li:first").find("li"), folder_id))
-						return;
-					$(this).parents(".closed:first").find("span:first").empty().append("<input class='new_folder folder' type='text' maxlength='100'></input>");
-					$(".new_folder").focus().keydown(function(event){
-						event.stopPropagation();
-						if(event.keyCode == 13){
-							if($(this).val() != ""){
-								if($(this).val().match(/[\/\`\~\^\<\>\|\\\"\!\@\#\$\%\&\*\+\(\)\[\]\{\}\?;:]/gi)){
-									return write_msg(get_lang("cannot create folder. try other folder name"));
-								}
-								var new_name = folder_id.replace(/[a-zA-Z0-9Ã¡-ÃºÃ-Ã^\s_-]+$/, $(this).val());
-								if($('[id="'+new_name+'"]').length){
-									$(".folders-loading").removeClass("folders-loading");
-									write_msg(get_lang("Mailbox already exists"));
-									return draw_new_tree_folder();
-								}
-								$(".new_folder").parent().addClass("folders-loading");
-								$.ajax({
-									url : "controller.php?action=$this.imap_functions.ren_mailbox",
-									type : "POST",
-									data : "current="+folder_id+"&rename="+new_name,
-									success : function(data){
-										data = connector.unserialize(data);
-										if(data == "Permission denied"){
-											$(".folders-loading").removeClass("folders-loading");
-											cExecute("$this.imap_functions.get_folders_list&onload=true", update_menu);
-											return write_msg(get_lang("Permission denied"));
-										}
-										write_msg(get_lang("The folder was successfully rename"));
-										cExecute("$this.imap_functions.get_folders_list&onload=true", update_menu);
-									}
-								});
-							}
-						}else if( event.keyCode == 27){
-							draw_new_tree_folder();
-						}
-					}).focusout(function(){
-						draw_new_tree_folder();
-					}).val(name);
-				})
-				//FUNÃÃO DO eventNU FLUTUANTE EDITAR < END
-				//FUNÃÃO DO eventNU FLUTUANTE EXCLUIR < BEGIN
-				.end().find(".float-menu-remove").click(function(){
-					
-					var folder_id = $(this).parents(".closed:first").attr('id');
-					var folder_name = "<strong>"+$.trim($(this).parents(".closed:first").find(".folder").text().split("[")[0])+"</strong>";
-					
-					if(valid_tabs($(this).parents("li:first").find("li"), folder_id))
-						return;
-					$(this).parents(".closed:first").find(".folder").addClass("folders-loading"); 
-					
-					if($(this).parents(".closed:first").find("ul").length){
-						$(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
-						return write_msg(get_lang("Delete/move subfolders first"));
-					}
-					if($(this).parents(".closed:first").find(".selected").length){
-						$(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
-						return write_msg(get_lang("It's not possible delete this folder, because it is being used in the moment!")); 
-					}
-					var folder_span = $(this);
-					var confirm_text = get_lang("Do you wish to exclude the folder ");
-					$.Zebra_Dialog(confirm_text+folder_name, {
-						'type':     'question',
-						'overlay_opacity': '0.5',
-						'buttons':  [get_lang('Yes'), get_lang('No')],
-						'onClose':  function(caption) {
-							if(caption == get_lang('Yes')){
-								$.ajax({
-									url : "controller.php?action=$this.imap_functions.delete_mailbox",
-									type: "POST",
-									data : "del_past="+folder_id,
-									success : function(data){
-										data = connector.unserialize(data);
-										if(data == "Mailbox does not exist"){
-											$(".folders-loading").removeClass("folders-loading");
-											return write_msg(get_lang("Mailbox does not exist"));
-										}else if(data == "Permission denied"){
-											$(".folders-loading").removeClass("folders-loading");
-											cExecute("$this.imap_functions.get_folders_list&onload=true", update_menu);
-											return write_msg(get_lang("Permission denied"));
-										}
-										write_msg(get_lang("The folder %1 was successfully removed", folder_name));
-										cExecute("$this.imap_functions.get_folders_list&onload=true", update_menu);
-									}
-								});
-							}else{
-								folder_span.parents(".closed:first").find(".folder").removeClass("folders-loading");
-								return;
-							}
-						}
-					});
-					/* if(!confirm(confirm_text + folder_name)){
-						$(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
-						return;
-					} */
-				})
-				//FUNÃÃO DO eventNU FLUTUANTE EXCLUIR < END
-				//FUNÃÃO DO eventNU FLUTUANTE NOVA PASTA < BEGIN
-				.end().find(".float-menu-new").click(function(){
-					$(this).parents(".float-menu").hide();
-					var selected_li = $(this).parents(".closed:first");
-					if(selected_li.find("ul:first").length){
-						var new_folder = $("<li><input class='new_folder folder' type='text' maxlength='100'></input></li>").appendTo(selected_li.find("ul:first"));								
-						if(selected_li.find(".expandable-hitarea").length){
-							selected_li.find(".expandable-hitarea").trigger('click');
-						}
-						selected_li.find("ul:first").treeview({
-							add: new_folder
-						});
-					}else if(selected_li.length){
-						var new_folder = $("<ul><li><input class='new_folder folder' type='text' maxlength='100'></input></li></ul>").appendTo(selected_li);								
-						selected_li.treeview({
-							add: new_folder
-						});
-					}else{
-						selected_li = $(this).parents(".head_folder").parent();
-						if($(this).parents(".head_folder").parent().find(".expandable-hitarea").length){
-							$(this).parents(".head_folder").parent().find(".expandable-hitarea").trigger('click');
-						}
-						var new_folder = $("<ul><li><input class='new_folder folder' type='text' maxlength='100'></input></li></ul>").appendTo(selected_li);								
-						selected_li.treeview({
-							add: new_folder
-						});
-					}
-					
-					selected_li.find(".new_folder").Watermark("Nova Pasta").focus().keydown(function(event){
-						event.stopPropagation();
-						if(event.keyCode == 13){
-							if($(this).val().match(/[\`\~\^\<\>\|\\\"\!\@\#\$\%\&\*\+\(\)\[\]\{\}\?;:]/gi)){
-								return write_msg(get_lang("cannot create folder. try other folder name"));
-							}
-							if($('[id="'+ (selected_li.attr('id')? selected_li.attr('id') : "INBOX") + imap_configs.imapDelimiter + $(this).val()+'"]').length){
-								$(".folders-loading").removeClass("folders-loading");
-								write_msg(get_lang("Mailbox already exists"));
-								return draw_new_tree_folder();
-							}
-							$(".new_folder").parent().addClass("folders-loading");
-							create_new_folder(($(this).val() != "" ? $(this).val() : get_lang("New Folder")), (selected_li.attr('id')? selected_li.attr('id') : "INBOX"));
-						}else if( event.keyCode == 27){
-							draw_new_tree_folder();
-						}
-					}).focusout(function(){
-						draw_new_tree_folder();
-					});
-				}).end().find(".float-menu-export").click(function(){
-					//proxy_mensagens.export_all_messages($(this).parents("li:first").attr("id"))
-
-					var name_box = $(this).parents("li:first").attr("id");
-					var name_folder = name_box.split(imap_configs.imapDelimiter)[name_box.split(imap_configs.imapDelimiter).length-1];
-
-					var hand_export = function(data){
-						if(!data){
-							write_msg(get_lang('Error compressing messages (ZIP). Contact the administrator.'))
-						}else if(data["empty_folder"]){
-							write_msg(get_lang("The selected folder is empty."));
-						}else
-						  download_attachments(null, null, data, null,null, name_folder +'.zip');
-					}
-					cExecute("$this.exporteml.export_all",hand_export,"folder="+name_box);	
-					write_msg(get_lang('You must wait while the messages will be exported...'));		
-				});
-				//FUNÃÃO DO eventNU FLUTUANTE NOVA PASTA < END
-			}
-			if(!$(".new_folder").length){
-				$(this).find(".float-menu:first").css("display", "");
-			}
-		},
-		function(){
-			$(this).find(".float-menu:first").hide();
-		}
-	);
+
+    /*
+    * Verificar atualizaÃ§Ã£o do conceito folder apÃ³s commit
+    * */
+    DataLayer.remove("folder", false);
+
+    var folders = DataLayer.get("folder");//, true);
+
+    if(!selected){
+        selected = "INBOX";
+    }
+
+    var tree1 = new Array();
+    var tree2 = new Array();
+    var tree3 = new Array();
+    for (var i=0; i<folders.length; i++) {
+        if (/^INBOX/.test(folders[i].id)) {
+            if (!unorphanize(tree1, folders[i])) {
+                folders[i].children = new Array();
+                tree1.push(folders[i]);
+            }
+        }
+        else if (/^user/.test(folders[i].id)) {
+            if (!unorphanize(tree2, folders[i])) {
+                folders[i].children = new Array();
+                tree2.push(folders[i]);
+            }
+        }
+        else if (/^local_messages/.test(folders[i].id)) {
+            if (!unorphanize(tree3, folders[i])) {
+                folders[i].children = new Array();
+                tree3.push(folders[i]);
+            }
+        }
+    }
+
+    for(var i =0; i<tree1.length; i++){
+        count_unseen_children(tree1[i]);
+    }
+    for(var i =0; i<tree2.length; i++){
+        count_unseen_children(tree2[i]);
+    }
+    for(var i =0; i<tree3.length; i++){
+        count_unseen_children(tree3[i]);
+    }
+    cp_tree1 = tree1;
+    cp_tree2 = tree2;
+    var shared_acls = {};
+
+    $.each(cp_tree2, function(index, value){
+        shared_acls[value.id] = value.acl_share;
+    });
+
+    var html = DataLayer.render('templates/detailedfoldertree.ejs', {folders: [tree1, tree2, tree3]});
+    var folders_html = $(".imap-folders").html(html).find(".mainfoldertree").treeview({
+        persist: "cookie",
+        animated: "fast"
+    }).find(".folder").unbind("click").click(function(event){
+
+            // MUDANÃA DE PASTAS!
+            var target = $(this);
+
+            if($(".folders-loading").length)
+                return;
+
+            if($(event.target).parent().is(".float-menu"))
+                return;
+
+            if( target.is('.collapsable-hitarea, .expandable-hitarea, .lastCollapsable-hitarea, .lastExpandable-hitarea, .treeview ,.folder_unseen,.ui-icon, .float-menu, .new_folder, .folders-loading, .head_folder, .shared-folders') )
+                return;
+
+            if( target.parent().find(".new_folder").length)
+                return;
+
+            if( !target.attr('id') )
+                target = target.parent();
+            if (target[0] == $(".mainfoldertree")[0]) return;
+            var uiId = target.attr('id');
+            var child = target.find('.folder');
+
+            if(!target.is('.mainfoldertree > .expandable-hitarea, .mainfoldertree > .collapsable-hitarea')){
+                $('.filetree span.folder.selected').removeClass('selected');
+                $(target).children('.folder').addClass('selected');
+            }
+            $(this).addClass("folders-loading");
+            selected = target.attr('id');
+
+            Folder.change(target.attr('id'), child.attr('title'));
+
+            /*$.ajax({
+             url : "controller.php?"+ $.param( { action: "$this.imap_functions.get_folders_list", folder: target.attr('id') } ),
+             success : function(data){
+             data = connector.unserialize(data);
+
+             if(data)
+             build_quota(data);
+             }
+             });*/
+            $(".folders-loading").removeClass("folders-loading");
+
+        }).filter('.followup-messages').click(function(event, ui){
+            search_emails("UNDELETED KEYWORD \"$Followupflagged\"");
+        }).end().end();
+
+    folders_html.find('[id="'+selected+'"]').children().addClass("selected");
+    $(".folder").not(".head_folder").not(".shared-folders").parent().find(".folder").not(".head_folder,.inbox,.drafts,.sent,.spam,.trash").draggable({
+        // DRAG DE PASTAS
+        start : function(){
+            $(this).css("color", "gray");
+        },
+        stop : function(){
+            $(this).css("color", "");
+        },
+        revert: "invalid",
+        helper: function(event){
+            if($.trim(($(this).text().split("["))[0]).length > 18)
+                return $(DataLayer.render('templates/draggin_box.ejs', {texto : (($(this).text().split("["))[0]).substring(0,18) + "...", type: "folder"}));
+            return $(DataLayer.render('templates/draggin_box.ejs', {texto : (($(this).text().split("["))[0]), type: "folder"}));
+        },
+        delay: 150,
+        refreshPositions: true,
+        zIndex : 2700,
+        //scroll: true,
+        //scrollSensitivity: 100,
+        //scrollSpeed: 100,
+        containment: "#divAppbox"
+    }).end().droppable({
+            //DROP DE PASTAS
+            over : function(a, b){
+                //INICIO : SE A PASTA CONTER FILHAS EXPANDE
+                over = $(this);
+                $(this).addClass("folder-over");
+                if(($(this)[0] != $(this).parent().find(".head_folder")[0]))
+                    if($(this).prev()[0])
+                        if($(this).parent().find(".expandable-hitarea")[0] == $(this).prev()[0]){
+                            setTimeout(function(){
+                                if(over.hasClass("folder-over"))
+                                    over.prev().trigger("click");
+                            }, 500);
+
+                        }
+                //FIM : SE A PASTA CONTER FILHAS EXPANDE
+
+                //SETA BORDA EM VOLTA DA PASTA
+            },
+            out : function(){
+                //RETIRA BORDA EM VOLTA DA PASTA
+                $(this).removeClass("folder-over");
+            },
+            drop : function(event, ui){
+                $(this).removeClass("folder-over");
+                if($(this).parent().attr('id') == undefined){
+                    var folder_to = 'INBOX';
+                    var to_folder_title = ("Inbox");
+                }else{
+                    var folder_to = $(this).parent().attr('id');
+                    var to_folder_title = $(this).attr('title');
+                }
+                var folder_to_move = ui.draggable.parent().attr('id');
+                var border_id = ui.draggable.find("input[type=hidden]").attr("name");
+                // eventnsagens : SE O DROP VIER DA LISTA DE eventNSAGENS :
+                if(folder_to_move == "tbody_box"){
+                    move_msgs2(get_current_folder(), 'selected', 0, folder_to, to_folder_title,true);
+                    return refresh();
+                }
+                //SE FOR DE UMA PESQUISA RAPIDA
+                else if(ui.draggable.parents('[id^="content_id_"]')[0]){
+                    move_search_msgs("content_id_"+border_id, folder_to, to_folder_title);
+                    return refresh();
+                }
+                // eventnsagens : SE O DROP VIER DE UMA ABA ABERTA
+                else if(folder_to_move == "border_tr"){
+                    var id_msg = border_id.split("_")[0];
+                    folder = $("#input_folder_"+border_id+"_r")[0] ? $("#input_folder_"+border_id+"_r").val() : (openTab.imapBox[border_id] ? openTab.imapBox[border_id]:get_current_folder());
+                    alternate_border(border_id);
+                    move_msgs2(folder, id_msg, border_id, folder_to, to_folder_title,true);
+                    return refresh();
+                }
+                // SE O DROP VIER DA LISTA DE PASTAS
+                else{
+                    var folder_to_exist = folder_to_move.split(imap_configs.imapDelimiter);
+                    folder_to_exist = folder_to+imap_configs.imapDelimiter+folder_to_exist[folder_to_exist.length-1];
+
+                    //VERIFICA SE EXISTE UMA eventNSAGENS ABERTA NESTA PASTA E NAS SUAS FILHAS
+
+                    if(valid_tabs(ui.draggable.parent().find("li"), folder_to_move)){
+                        return;
+                    }
+                    //FIM : VERIFICA SE EXISTE UMA eventNSAGENS ABERTA NESTA PASTA E NAS SUAS FILHAS;
+
+                    // VALIDA SE O USUARIO ESTA TENTANDO MOVER A PASTA PARA O eventSMO LOCAL
+                    if(folder_to_exist == folder_to_move){
+                        return alert("Thie folder is already in this place");
+                    }
+
+                    // VALIDA SE O USUARIO ESTA TENTANDO MOVER A PASTA ABERTA NO momentO
+                    if(folder_to_move == Folder.open){
+                        return alert("It's not possible move this folder, because it is being used in the moment!");
+                    }
+
+                    // VALIDA SE O USUARIO ESTA TENTANDO MOVER UMA PASTA FILHA DA PASTA ABERTA NO momentO
+                    if(ui.draggable.parent().find(".selected")[0]){
+                        return alert(("It's not possible move this folder, because its subfolder is being used in the moment!"));
+                    }
+
+                    // VALIDA SE O USUARIO ESTA TENTANDO MOVER UMA PASTA PAI PARA DENTRO DE UMA FILHA
+                    if(ui.draggable.parent().find('[id="'+folder_to+'"]')[0]){
+                        return alert(("It's not possible to move this folder to its subfolders!"));
+                    }
+
+                    if($('[id="'+folder_to_exist+'"]').length){
+                        return alert(("Can not move this folder to this location, because the target has already a folder with this name"));
+                    }
+
+                    $(this).addClass("folders-loading");
+
+                    $.ajax({
+                        url : "../expressoMail1_2/controller.php?"+ $.param( { action: "$this.imap_functions.move_folder", folder_to_move: folder_to_move, folder_to: folder_to } ),
+                        success : function(data){
+                            draw_new_tree_folder();
+                            data = connector.unserialize(data);
+                            if(data == "Permission denied"){
+                                alert(("Permission denied"));
+                            }else if(data){
+                                alert(("The folder was successfully moved"));
+                            }
+                            else{
+                                alert(("ERROR moving your folder."));
+                            }
+                        }
+                    });
+                }
+            }
+        });
+    $(".folder").not(".shared-folders").parent().find(".folder").hover(
+        function(){
+            //CASO A LI NÃO TENHA UM eventNU FLUTUANTE AINDA, O eventNU Ã ADICIONADO!
+            if(!$(this).children(":last").hasClass("float-menu") && !$(this).children(":last").hasClass("new_folder")){
+                var folder_ = $(this);
+                var folder_name;
+                var shared = {
+                    head : false,
+                    valid : false
+                };
+                if(folder_.parent().attr('id')){
+                    folder_name = folder_.parent().attr('id').split(imap_configs.imapDelimiter);
+                    folder_name = folder_name[folder_name.length -1];
+                    shared.valid = folder_.parent().attr('id').search("user/") == 0 ? true : false;
+                }else
+                    folder_name = "Root";
+
+                if(shared.valid){
+                    shared.head = folder_.parent().attr('id').split(imap_configs.imapDelimiter).length == 2 ?  true : false;
+                    var folder_name_parts = folder_.parent().attr('id').split(imap_configs.imapDelimiter);
+                    var acls = shared_acls[folder_name_parts[0]+imap_configs.imapDelimiter+folder_name_parts[1]];
+
+                }
+
+                html = DataLayer.render("/templates/float_folder_menu.ejs", {name_folder : folder_name, flag : shared, acl : acls});
+                //FUNÃÃO DO eventNU FLUTUANTE EDITAR < BEGIN
+                var esc = false;
+                $(folder_).append(html).find(".float-menu-edit").click(function(){
+                    var folder_id = $(this).parents(".closed:first").attr('id');
+                    var name = $.trim($(this).parents(".closed:first").find("span:first").text().split("[")[0]);
+                    if($(this).parents(".closed:first").find("span:first").hasClass("selected"))
+                        return alert(("It's not possible rename this folder, because it is being used in the moment!"));
+                    if($(this).parents(".closed:first").find(".selected").length)
+                        return alert(("It's not possible rename this folder, because its subfolder is being used in the moment!"));
+                    if(valid_tabs($(this).parents("li:first").find("li"), folder_id))
+                        return;
+                    $(this).parents(".closed:first").find("span:first").empty().append("<input class='new_folder folder' type='text' maxlength='100'></input>");
+                    $(".new_folder").focus().keydown(function(event){
+                        event.stopPropagation();
+                        if(event.keyCode == 13){
+                            if($(this).val() != ""){
+                                if($(this).val().match(/[\/\`\~\^\<\>\|\\\"\!\@\#\$\%\&\*\+\(\)\[\]\{\}\?;:]/gi)){
+                                    return alert(("cannot create folder. try other folder name"));
+                                }
+                                var new_name = folder_id.replace(/[a-zA-Z0-9Ã¡-ÃºÃ-Ã^\s_-]+$/, $(this).val());
+                                if($('[id="'+new_name+'"]').length){
+                                    $(".folders-loading").removeClass("folders-loading");
+                                    alert(("Mailbox already exists"));
+                                    return draw_new_tree_folder();
+                                }
+                                $(".new_folder").parent().addClass("folders-loading");
+                                Folder.rename(folder_id,new_name, function(){
+                                    draw_new_tree_folder();
+                                });
+                            }
+                        }else if( event.keyCode == 27){
+                            draw_new_tree_folder();
+                        }
+                    }).focusout(function(){
+                            draw_new_tree_folder();
+                        }).val(name);
+                })
+                    //FUNÃÃO DO eventNU FLUTUANTE EDITAR < END
+                    //FUNÃÃO DO eventNU FLUTUANTE EXCLUIR < BEGIN
+                    .end().find(".float-menu-remove").click(function(){
+                        var folder_id = $(this).parents(".closed:first").attr('id');
+                        var folder_name = "<strong>"+$.trim($(this).parents(".closed:first").find(".folder").text().split("[")[0])+"</strong>";
+
+                        if(valid_tabs($(this).parents("li:first").find("li"), folder_id))
+                            return;
+                        $(this).parents(".closed:first").find(".folder").addClass("folders-loading");
+
+                        if($(this).parents(".closed:first").find("ul").length){
+                            $(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
+                            return alert("Delete/move subfolders first");
+                        }
+                        if($(this).parents(".closed:first").find(".selected").length){
+                            $(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
+                            return alert("It's not possible delete this folder, because it is being used in the moment!");
+                        }
+                        var folder_span = $(this);
+                        confirm("Do you wish to exclude the folder "+folder_name,function(confirm){
+                            if(confirm){
+                                Folder.remove(folder_id, function(){
+                                    draw_new_tree_folder();
+                                });
+                            }else{
+                                folder_span.parents(".closed:first").find(".folder").removeClass("folders-loading");
+                                return;
+                            }
+                        });
+
+                        /* if(!confirm(confirm_text + folder_name)){
+                         $(this).parents(".closed:first").find(".folder").removeClass("folders-loading");
+                         return;
+                         } */
+                    })
+                    //FUNÃÃO DO eventNU FLUTUANTE EXCLUIR < END
+                    //FUNÃÃO DO eventNU FLUTUANTE NOVA PASTA < BEGIN
+                    .end().find(".float-menu-new").click(function(){
+                        $(this).parents(".float-menu").hide();
+                        var selected_li = $(this).parents(".closed:first");
+                        if(selected_li.find("ul:first").length){
+                            var new_folder = $("<li><input class='new_folder folder' type='text' maxlength='100'></input></li>").appendTo(selected_li.find("ul:first"));
+                            if(selected_li.find(".expandable-hitarea").length){
+                                selected_li.find(".expandable-hitarea").trigger('click');
+                            }
+                            selected_li.find("ul:first").treeview({
+                                add: new_folder
+                            });
+                        }else if(selected_li.length){
+                            var new_folder = $("<ul><li><input class='new_folder folder' type='text' maxlength='100'></input></li></ul>").appendTo(selected_li);
+                            selected_li.treeview({
+                                add: new_folder
+                            });
+                        }else{
+                            selected_li = $(this).parents(".head_folder").parent();
+                            if($(this).parents(".head_folder").parent().find(".expandable-hitarea").length){
+                                $(this).parents(".head_folder").parent().find(".expandable-hitarea").trigger('click');
+                            }
+                            var new_folder = $("<ul><li><input class='new_folder folder' type='text' maxlength='100'></input></li></ul>").appendTo(selected_li);
+                            selected_li.treeview({
+                                add: new_folder
+                            });
+                        }
+
+                        selected_li.find(".new_folder").Watermark("Nova Pasta").focus().keydown(function(event){
+                            event.stopPropagation();
+                            if(event.keyCode == 13){
+                                if($(this).val().match(/[\`\~\^\<\>\|\\\"\!\@\#\$\%\&\*\+\(\)\[\]\{\}\?;:]/gi)){
+                                    return alert(("cannot create folder. try other folder name"));
+                                }
+                                if($('[id="'+ (selected_li.attr('id')? selected_li.attr('id') : "INBOX") + imap_configs.imapDelimiter + $(this).val()+'"]').length){
+                                    $(".folders-loading").removeClass("folders-loading");
+                                    alert(("Mailbox already exists"));
+                                    return draw_new_tree_folder();
+                                }
+                                $(".new_folder").parent().addClass("folders-loading");
+                                Folder.create($(this).val(), selected_li.attr('id'), function(){
+                                    draw_new_tree_folder();
+                                });
+                            }else if( event.keyCode == 27){
+                                draw_new_tree_folder();
+                            }
+                        }).focusout(function(){
+                                draw_new_tree_folder();
+                            });
+                    }).end().find(".float-menu-export").click(function(){
+                        //proxy_mensagens.export_all_messages($(this).parents("li:first").attr("id"))
+
+                        var name_box = $(this).parents("li:first").attr("id");
+                        var name_folder = name_box.split(imap_configs.imapDelimiter)[name_box.split(imap_configs.imapDelimiter).length-1];
+
+                        var hand_export = function(data){
+                            if(!data){
+                                alert(('Error compressing messages (ZIP). Contact the administrator.'))
+                            }else if(data["empty_folder"]){
+                                alert(("The selected folder is empty."));
+                            }else
+                                download_attachments(null, null, data, null,null, name_folder +'.zip');
+                        }
+                        cExecute("$this.exporteml.export_all",hand_export,"folder="+name_box);
+                        alert(('You must wait while the messages will be exported...'));
+                    });
+                //FUNÃÃO DO eventNU FLUTUANTE NOVA PASTA < END
+            }
+            if(!$(".new_folder").length){
+                $(this).find(".float-menu:first").css("display", "");
+            }
+        },
+        function(){
+            $(this).find(".float-menu:first").hide();
+        }
+    );
 }
 
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/formatters.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/formatters.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/formatters.js	(revision 7265)
@@ -43,7 +43,58 @@
 	} else {
 		date = new Date(timestamp);
-		var b = date.toString().split("T")[0].split("-");
-		var c = b[2] + "/" + b[1] + "/" + b[0];
-		return '<span class="datable">' + c + '</span>';
+		var b = date.toString("dd/MM/yyyy");
+		return '<span class="datable">' + b + '</span>';
 	}
 }
+
+subjectFormatter = function(subject){
+    var formatted = subject ?
+        (subject.length > 40 ? subject.substring(0, 37)+"..." : subject) :
+        "(Rascunho)";
+    return '<span>' + formatted + '</span>';
+}
+
+flags2Class = function(cellvalue, options, rowObject) {
+    var classes = '';
+    cellvalue = cellvalue.split(',');
+    cell = {
+        Unseen: parseInt(cellvalue[0])  ? 'Unseen' : 'Seen',
+        Answered: parseInt(cellvalue[1]) ? 'Answered' : (parseInt(cellvalue[2]) ? 'Forwarded' : ''),
+        Flagged: parseInt(cellvalue[3]) ? 'Flagged' : '',
+        Recent: parseInt(cellvalue[4])  ? 'Recent' : '',
+        Draft: parseInt(cellvalue[5]) ? 'Draft' : ''
+    };
+    for(var flag in cell){
+        classes += '<span class="flags '+ (cell[flag]).toLowerCase() + '"' + (cell[flag] != "" ? 'title="'+ cell[flag]+'"' : '')+'> </span>';
+    }
+
+    // REFAZER LABELS E ACOMPANHAMENTO
+    /*if(rowObject.labels){
+        var titles = [];
+        var count = 0;
+        for(i in rowObject.labels){
+            titles[count] = " "+rowObject.labels[i].name;
+            count++;
+        }
+        titles = titles.join();
+        classes += '<span class="flags labeled" title="'+titles+'"> </span>';
+    }else{
+        classes += '<span class="flags"> </span>';
+    }
+
+    if(rowObject.followupflagged){
+        if(rowObject.followupflagged.followupflag.id < 7){
+            var nameFollowupflag = get_lang(rowObject.followupflagged.followupflag.name);
+        }else{
+            var nameFollowupflag = rowObject.followupflagged.followupflag.name;
+        }
+        if(rowObject.followupflagged.isDone == 1){
+            classes += '<span class="flags followupflagged" title="'+nameFollowupflag+'" style="background:'+rowObject.followupflagged.backgroundColor+';"><img style=" margin-left:-3px;" src="../prototype/modules/mail/img/flagChecked.png"></span>';
+        }else{
+            classes += '<span class="flags followupflagged" title="'+nameFollowupflag+'" style="background:'+rowObject.followupflagged.backgroundColor+';"><img src="../prototype/modules/mail/img/flagEditor.png"></span>';
+        }
+
+    }*/
+
+    return classes;
+}
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/tabs.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/tabs.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/tabs.js	(revision 7265)
@@ -1,129 +1,138 @@
-var countID = 2;
 var tab_content = "";
 var tab_role = "";
-var lastIndexSelected = 0;
-/* 
-	method : createTab
-	descrition : create a new tab
-	params : {
-		label : Label of the tab
-		* role : Tab type
-		* content : Content of the tab
-		* href : Tab id 
-		* callback : a function
-	}
-	comments : {
-		#1 : if the user just set the label, a tab with blank content and a dynamic id is created
-		#2 : if a tab with a set href already exists, don't duplicate, this function only select the tab 
-		#3 : if the role is 
-	* = Optional
-*/
 
-function createTab(label, role, content,href, callback){
-	if( !$("#tabs-"+href).length){
-		tab_content = content ? content : "";
-		tab_role = role ? role : "new";
-		countID++;
-		$tabs.wijtabs("add", "#tabs-"+(href ? href : countID), (label.length > 21 ? label.substring(0, 18)+"..." : label));
-		if(typeof(callback) == 'function') 
-			callback($("#ptabs_"+(href ? href : countID)));
-		else
-			return $("#tabs-"+(href ? href : countID));
-	}else{
-		$tabs.wijtabs( "select", indexTab("#tabs-"+href) );
-	}
+var Tab = {
+
+    /*
+     method : createTab
+     descrition : create a new tab
+     params : {
+     label : Label of the tab
+     * role : Tab type
+     * content : Content of the tab
+     * href : Tab id
+     * callback : a function
+     }
+     comments : {
+     #1 : if the user just set the label, a tab with blank content and a dynamic id is created
+     #2 : if a tab with a set href already exists, don't duplicate, this function only select the tab
+     #3 : if the role is
+     * = Optional
+     */
+    create : function(label, role, content,href, callback){
+        if( !$("#tabs-"+href).length){
+            tab_content = content ? content : "";
+            tab_role = role ? role : "new";
+            Tab.count++;
+            $tabs.wijtabs("add", "#tabs-"+(href ? href : Tab.count), (label.length > 21 ? label.substring(0, 18)+"..." : label));
+            if(typeof(callback) == 'function')
+                callback($("#ptabs_"+(href ? href : Tab.count)));
+            else
+                return $("#tabs-"+(href ? href : Tab.count));
+        }else{
+            $tabs.wijtabs( "select", Tab.index("#tabs-"+href) );
+        }
+    },
+
+
+    /*
+     method : removeTab
+     descrition : remove a tab
+     params : {
+     * href : Tab id
+     * callback : a function
+     }
+     comments : {
+     #1 : if the user doesn't set no parameter, this function just remove the open tab
+
+     * = Optional
+     */
+    remove : function(href, callback){
+        $tabs.wijtabs("remove",
+            (
+                href ?
+                    Tab.index(href) : Tab.lastIndexSelected
+                )
+        );
+        if(typeof(callback) == 'function')
+            callback();
+    },
+
+    /*
+     method : Tab.index
+     descrition : return a tab index
+     params : {
+     * href : Tab id
+     }
+     comments : {
+     #1 : if the user doesn't set no parameter, this function just return the index of the open tab
+
+     * = Optional
+     */
+
+    index : function(href){
+        return href ?
+            $( "li", $tabs ).index( $('[href="'+href+'"]').parent() ) : Tab.lastIndexSelected;
+    },
+
+    /*
+     method : idTab
+     descrition : remove a tab id
+     params : {
+     * index : Tab index
+     }
+     comments : {
+     #1 : if the user doesn't set no parameter, this function just return the id of the open tab
+
+     * = Optional
+     */
+
+    id : function(index){
+        return $( ".ui-tabs-panel", $tabs ).eq((index ? index : Tab.index())).attr("id");
+    },
+
+    getData : function(index){
+        return {
+            id : parseInt(Tab.id(index).substring(6).split("_r_")[0]),
+            folder : Base64.decode(idTab(index).substring(6).split("_r_")[1]),
+            role : Tab.getRole(index),
+            header : Tab.getHeader(index),
+            content : Tab.getContent(index)
+        };
+    },
+
+    getHeader : function(index){
+        return $( $tabs ).find('[href="#'+$( ".ui-tabs-panel", $tabs ).eq((index ? index : Tab.index())).attr("id")+'"]').parent();
+    },
+
+    getRole: function(index){
+        return Tab.getContent(index).attr("role");
+    },
+
+    getContent: function(index){
+        return $( ".ui-tabs-panel", $tabs ).eq((index ? index : Tab.index()));
+    },
+
+    setFolderTotal: function(value){
+        Tab.getHeader(0).find(".folder-tab-total-msgs-number").html(parseInt(value) ? value : 0);
+    },
+
+    setFolderUnread: function(value){
+        Tab.getHeader(0).find(".folder-tab-new-msgs-number").html(parseInt(value) ? value : 0);
+        if(parseInt(value))
+            $("title").html($("title").html() +" ("+value+")");
+    },
+
+    setFolderName: function(value){
+        Tab.getHeader(0).find(".folder-tab-name").html(value);
+        $("title").html(value);
+    },
+
+    lastIndexSelected : 0,
+
+    count: 2,
+
+    roles : [
+        "new", "draft", "search", "message", "folder"
+    ]
 }
-
-/* 
-	method : removeTab
-	descrition : remove a tab
-	params : {
-		* href : Tab id 
-		* callback : a function
-	}
-	comments : {
-		#1 : if the user doesn't set no parameter, this function just remove the open tab
-
-	* = Optional
-*/
-
-function removeTab(href, callback){
-	$tabs.wijtabs("remove", 
-		(
-			href ? 
-			indexTab(href) : lastIndexSelected
-		)
-	);
-	if(typeof(callback) == 'function') 
-		callback();
-}
-
-/* 
-	method : indexTab
-	descrition : return a tab index
-	params : {
-		* href : Tab id 
-	}
-	comments : {
-		#1 : if the user doesn't set no parameter, this function just return the index of the open tab
-
-	* = Optional
-*/
-
-function indexTab(href){
-	return href ? 
-		$( "li", $tabs ).index( $('[href="'+href+'"]').parent() ) : lastIndexSelected;
-}
-
-/*
- method : idTab
- descrition : remove a tab id
- params : {
- * index : Tab index
- }
- comments : {
- #1 : if the user doesn't set no parameter, this function just return the id of the open tab
-
- * = Optional
- */
-
-function idTab(index){
-    return $( ".ui-tabs-panel", $tabs ).eq((index ? index : indexTab())).attr("id");
-}
-
-function getTabData(index){
-	return {
-		id : parseInt(idTab(index).substring(6).split("_r_")[0]),
-		folder : Base64.decode(idTab(index).substring(6).split("_r_")[1]),
-		role : getTabRole(index),
-		header : getTabHeader(index),
-		content : getTabContent(index)
-	};
-}
-
-function getTabHeader(index){
-    return $( $tabs ).find('[href="#'+$( ".ui-tabs-panel", $tabs ).eq((index ? index : indexTab())).attr("id")+'"]').parent();
-}
-
-function getTabRole(index){
-	return getTabContent(index).attr("role");
-}
-
-function getTabContent(index){
-	return $( ".ui-tabs-panel", $tabs ).eq((index ? index : indexTab()));
-}
-
-function setFolderTabTotal(value){
-	getTabHeader(0).find(".folder-tab-total-msgs-number").html(parseInt(value) ? value : 0);
-}
-
-function setFolderTabTotalUnread(value){
-	getTabHeader(0).find(".folder-tab-new-msgs-number").html(parseInt(value) ? value : 0);	
-	if(parseInt(value))
-		$("title").html($("title").html() +" ("+value+")");
-}
-
-function setFolderTabName(value){
-	getTabHeader(0).find(".folder-tab-name").html(value);	
-	$("title").html(value);
-}
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/alerts.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/alerts.js	(revision 7265)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/alerts.js	(revision 7265)
@@ -0,0 +1,58 @@
+window.alert = function(message, strong, title, callback) {
+    $.Zebra_Dialog("<b>"+(strong ? strong : '')+ " </b>" + message,{
+        'type':     'error',
+        'title':    title ? title : '',
+        'overlay_opacity': '0.5',
+        'onClose': function(caption){
+            if(typeof(callback) == 'function')
+                callback();
+        }
+    });
+    zebraKeyboard();
+};
+
+window.confirm = function(message, callback, strong, title) {
+    if(typeof(callback) == 'function'){
+        $.Zebra_Dialog("<b>"+(strong ? strong : '')+ " </b>" + message,{
+            'type':     'question',
+            'title':    title ? title : '',
+            'buttons':  ['Sim', 'Não'],
+            'overlay_opacity': '0.5',
+            'onClose': function(caption){
+                callback(caption == "Sim" ? true : false);
+            }
+        });
+    }
+    zebraKeyboard();
+};
+
+window.warning = function(){
+
+};
+
+function zebraKeyboard(){
+    $(".ZebraDialog:last .ZebraDialog_Buttons").attr("tabindex", "0").focus().keydown(function(e){
+        var selected = $(".ZebraDialog:last .ZebraDialog_Buttons .ZebraDialog_ButtonSelected");
+        switch (e.keyCode){
+            case $.ui.keyCode.ENTER:{
+                selected.click();
+                break;
+            }
+            case $.ui.keyCode.LEFT:{
+                if(selected.next("a").length){
+                    selected.next().addClass("ZebraDialog_ButtonSelected");
+                    selected.removeClass("ZebraDialog_ButtonSelected");
+                }
+                break;
+            }
+            case $.ui.keyCode.RIGHT:{
+                if(selected.prev("a").length){
+                    selected.prev().addClass("ZebraDialog_ButtonSelected");
+                    selected.removeClass("ZebraDialog_ButtonSelected");
+                }
+                break;
+            }
+        };
+    }).find(".ZebraDialog_Button0").addClass("ZebraDialog_ButtonSelected");
+    $(".ZebraDialog:last").click(function(){$(".ZebraDialog:last .ZebraDialog_Buttons").focus();})
+}
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/folder.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/folder.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/folder.js	(revision 7265)
@@ -1,8 +1,64 @@
-function changeFolder(folder, name){
-	var messages = DataLayer.get("message", {criteria: {folder: folder, rows: 999999}}, true);
-	Grid.jqGrid('clearGridData').jqGrid('setGridParam',{data:messages.rows}).trigger("reloadGrid");
-	setFolderTabName(name);
-	setFolderTabTotal(messages.records);
-	//TO-DO:: TROCAR ESSE METODO POR ALGUM LUGAR MAIS SEGURO
-	setFolderTabTotalUnread($("[id='"+folder+"']").find(".folder_unseen").html());
+dashes = /\//gi;
+
+var Folder = {
+    open : 'INBOX',
+
+    remove : function(id, callback){
+        DataLayer.remove("folder", id);
+        DataLayer.commit(false, false, callback);
+    },
+
+    rename : function(id, value, callback){
+        DataLayer.put("folder", {id:id, new:value});
+        DataLayer.commit(false, false, callback);
+    },
+
+    create : function(id, path,callback){
+        DataLayer.put("folder", {name:id, path:path});
+        DataLayer.commit(false, false, callback);
+    },
+
+    move : function (id, value){
+
+    },
+
+    exportMessages : function(id, callback){
+
+    },
+
+    change : function(id, title){
+        var data = DataLayer.get("folder", {criteria:{folder:id} }, true)[0];
+        Tab.setFolderTotal(data.messageCount.total);
+        Tab.setFolderUnread(data.messageCount.unseen);
+        Tab.setFolderName(title ? title : data.commonName);
+        Folder.open = id;
+        Grid.jqGrid('clearGridData')
+            .jqGrid('setGridParam', {
+                url:  BASE_PATH+'REST.php?q=folder/'+id.replace(dashes, '.')+'/message'
+            })
+            .trigger('reloadGrid',
+            [{
+                page: 1
+            }]
+        );
+    },
+
+    acl : function(id){
+
+    },
+
+    info : function(id){
+        return DataLayer.get("folder", {criteria:{folder:(id ? id : Folder.open)} }, true)[0];
+    },
+    special : {},
+    init: function(){
+        this.special[imap_configs.imapDefaultDraftsFolder] = "Rascunhos";
+        this.special[imap_configs.imapDefaultSentFolder] = "Enviados";
+        this.special[imap_configs.imapDefaultSpamFolder] = "Spam";
+        this.special[imap_configs.imapDefaultTrashFolder] = "Lixeira";
+    },
+
+    delimiter : imap_configs.imapDelimiter
 }
+
+Folder.init();
Index: sandbox/newExpressoMail/prototype/modules/newMail/js/init.js
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/js/init.js	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/js/init.js	(revision 7265)
@@ -1,143 +1,166 @@
+var BASE_PATH = '../prototype/';
+
 $(document).ready(function() {
 
-	Layout = $('#wrap').layout({ 
-		applyDefaultStyles: true,
-		north__size:		'auto',
-		north__closable:	false, 
-		north__resizable:	false,
-		north__slidable:	false, 
-		west__resizable:	false,
-		west__slidable:	false,
-		center__maxSize : 0
-	});
+    Layout = $('#wrap').layout({
+        applyDefaultStyles: true,
+        north__size:		'auto',
+        north__closable:	false,
+        north__resizable:	false,
+        north__slidable:	false,
+        west__resizable:	false,
+        west__slidable:	false,
+        center__maxSize : 0
+    });
 
-	$tabs = $("#tabs").wijtabs({ 
-		tabTemplate: "<li role='tab' style='cursor: pointer;'><a href='#{href}'>#{label}</a><span class='ui-icon tab-close ui-icon-close close' title='Fechar Aba'>Fechar Aba</span></li>", 
-		panelTemplate: "<div id='{href}'></div>",
-		add: function( event, ui ) { 
-		        $tabs.wijtabs('select', '#' + $tabs.find("div:last").attr("id")); 
-	         	$tabs.find("span.tab-close:last").hover(function(){$(this).toggleClass("ui-icon-circle-close ui-icon-close");}, function(){$(this).toggleClass("ui-icon-circle-close ui-icon-close");})
-		        $tabs.find("div:last").addClass("conteudo").attr("role", tab_role).append(tab_content); 
-		},
-		show: function(event, ui){
-			switch($( ui.panel ).attr("role")){
-				case "new":
-				case "search":
-					$("#footer_menu").hide();
-					break;
-				case "message":
-				case "draft":
-				case "folder":
-					$("#footer_menu").show();
-					break;
-			}
-		},
-		select: function(event, ui) { 
-			lastIndexSelected = ui.index;
-		},
-		scrollable: true,
-		sortable: true,
-        hideOption: { 
-        	blind: true, 
-        	fade: false, 
-        	duration: 200
-       	},
-       	showOption: {
-       		blind: true, 
-       		fade: false, 
-       		duration: 200
-       	}
-	});	
+    $tabs = $("#tabs").wijtabs({
+        tabTemplate: "<li role='tab' style='cursor: pointer;'><a href='#{href}'>#{label}</a><span class='ui-icon tab-close ui-icon-close close' title='Fechar Aba'>Fechar Aba</span></li>",
+        panelTemplate: "<div id='{href}'></div>",
+        add: function( event, ui ) {
+            $tabs.wijtabs('select', '#' + $tabs.find("div:last").attr("id"));
+            $tabs.find("span.tab-close:last").hover(function(){$(this).toggleClass("ui-icon-circle-close ui-icon-close");}, function(){$(this).toggleClass("ui-icon-circle-close ui-icon-close");})
+            $tabs.find("div:last").addClass("conteudo").attr("role", tab_role).append(tab_content);
+        },
+        show: function(event, ui){
+            switch($( ui.panel ).attr("role")){
+                case "new":
+                case "search":
+                    $("#footer_menu").hide();
+                    break;
+                case "message":
+                case "draft":
+                case "folder":
+                    $("#footer_menu").show();
+                    break;
+            }
+        },
+        select: function(event, ui) {
+            lastIndexSelected = ui.index;
+        },
+        scrollable: true,
+        sortable: true,
+        hideOption: {
+            blind: true,
+            fade: false,
+            duration: 200
+        },
+        showOption: {
+            blind: true,
+            fade: false,
+            duration: 200
+        }
+    });
 
-	draw_new_tree_folder();
+    draw_new_tree_folder();
 
-	$(".new-message-button").button({
-		icons: {
-			secondary : "ui-icon-plusthick"
-		}
-	});
+    $(".new-message-button").button({
+        icons: {
+            secondary : "ui-icon-plusthick"
+        }
+    });
 
-	var messages = DataLayer.get("message", {criteria : {folder: 'INBOX', rows: 999999}}, true);
+    var messages = DataLayer.get("message", {criteria : {folder: 'INBOX', rows: 999999}});
 
-	$('.button.config-menu').button({
-	    icons: {
-			primary: "ui-icon-gear",
-			secondary: "ui-icon-triangle-1-s"
-	    },
-	    text: false
-	});
+    $('.button.config-menu').button({
+        icons: {
+            primary: "ui-icon-gear",
+            secondary: "ui-icon-triangle-1-s"
+        },
+        text: false
+    });
 
-	var menus = $(".main-menus-content").clone();
-	$(".main-menus-content").remove();
+    var menus = $(".main-menus-content").clone();
+    $(".main-menus-content").remove();
 
-	$(".this-module").button().next().button({
-		icons :{
-			primary: "ui-icon-triangle-1-s"
-		},
-		text: false
-	}).parent().buttonset();
+    $(".this-module").button().next().button({
+        icons :{
+            primary: "ui-icon-triangle-1-s"
+        },
+        text: false
+    }).parent().buttonset();
 
-	$(".this-module").parent().append(menus);
+    $(".this-module").parent().append(menus);
 
-	$('.this-module').next().menu({
-		content: $('.main-menus-content').html(),
-		positionOpts: {
-			posX: 'left', 
-			posY: 'bottom',
-			offsetX: -140,
-			offsetY: 0,
-			directionH: 'right',
-			directionV: 'down', 
-			detectH: true, // do horizontal collision detection  
-			detectV: true, // do vertical collision detection
-			linkToFront: false
-		},
-		flyOut: true,
-		showSpeed: 100,
-		crumbDefaultText: '>'
-	});
+    $('.this-module').next().menu({
+        content: $('.main-menus-content').html(),
+        positionOpts: {
+            posX: 'left',
+            posY: 'bottom',
+            offsetX: -140,
+            offsetY: 0,
+            directionH: 'right',
+            directionV: 'down',
+            detectH: true, // do horizontal collision detection
+            detectV: true, // do vertical collision detection
+            linkToFront: false
+        },
+        flyOut: true,
+        showSpeed: 100,
+        crumbDefaultText: '>'
+    });
 
-	$('.block-horizontal-toolbox .main-config-menu').menu({
-		content: $('.main-config-menu-content').html(),
-		positionOpts: {
-			posX: 'left', 
-			posY: 'bottom',
-			offsetX: -140,
-			offsetY: 0,
-			directionH: 'right',
-			directionV: 'down', 
-			detectH: true, // do horizontal collision detection  
-			detectV: true, // do vertical collision detection
-			linkToFront: false
-		},
-		flyOut: true,
-		showSpeed: 100,
-		crumbDefaultText: '>'
-	});
-	setFolderTabName("Caixa de Entrada");
-	$(".folder-tab-total-msgs-number").html(messages.records);
-	setFolderTabTotalUnread($("#INBOX").find(".folder_unseen").html());
-	Grid = $("#imap-folder-table-messages").jqGrid({
-		datatype: "local",
-		data: messages.rows,
-		colNames:['#',' ', 'De', 'Assunto', 'Data', 'Tamanho'],
-		colModel:[
-			{name:'msg_number',index:'msg_number', width:45, hidden:true, sortable:false},
-			{name:'flags',index:'msg_number',edittype: 'image', width:60, sortable:false, title :false},
-			{name:'from.name',index:'msg_number', width:100, sortable:true},
-			{name:'subject',index:'subject', width:245, sortable:true},
-			{name:'timestamp',index:'timestamp', width:65, align:"center", sortable:true},
-			{name:'size',index:'size', width:55, align:"center", sortable:true, formatter: bytes2Size}
-		],
-		rowNum:50,
-		rowList:[10,25,50],
-		pager: "#imap-folder-table-pager",
-		sortorder: "desc",
-		multiselect: true,
-		autowidth: true,
-		height : '85.5%',
-		emptyrecords: 'A pasta nao contem nenhuma mensagem.',
-		viewrecords: true
-	});
-	Grid.jqGrid('bindKeys', {"onEnter":function( rowid ) { alert("You enter a row with id:"+rowid)} });
+    $('.block-horizontal-toolbox .main-config-menu').menu({
+        content: $('.main-config-menu-content').html(),
+        positionOpts: {
+            posX: 'left',
+            posY: 'bottom',
+            offsetX: -140,
+            offsetY: 0,
+            directionH: 'right',
+            directionV: 'down',
+            detectH: true, // do horizontal collision detection
+            detectV: true, // do vertical collision detection
+            linkToFront: false
+        },
+        flyOut: true,
+        showSpeed: 100,
+        crumbDefaultText: '>'
+    });
+    Tab.setFolderName("Caixa de Entrada");
+    $(".folder-tab-total-msgs-number").html(messages.records);
+    Tab.setFolderUnread($("#INBOX").find(".folder_unseen").html());
+    Grid = $("#imap-folder-table-messages").jqGrid({
+        url:BASE_PATH + 'REST.php?q=folder/INBOX/message',
+        datatype: "json",
+        colNames:['#',' ', 'De', 'Assunto', 'Data', 'Tamanho'],
+        colModel:[
+            {name:'msg_number',index:'msg_number', width:45, hidden:true, sortable:false},
+            {name:'flags',index:'msg_number',edittype: 'image', width:60, formatter:flags2Class, sortable:false, title :false},
+            {name:'from.name',index:'SORTFROM', width:100, sortable:true, formatter:subjectFormatter},
+            {name:'subject',index:'SORTSUBJECT', width:245, sortable:true},
+            {name:'timestamp',index:'SORTARRIVAL', width:65, align:"center", sortable:true, formatter: date2Time},
+            {name:'size',index:'SORTSIZE', width:55, align:"center", sortable:true, formatter: bytes2Size}
+        ],
+        jsonReader : {
+            root:"rows",
+            page: "page",
+            total: "total",
+            records: "records",
+            repeatitems: false,
+            id: "0"
+        },
+        rowNum:50,
+        rowList:[10,25,50],
+        pager: "#imap-folder-table-pager",
+        sortorder: "desc",
+        multiselect: true,
+        autowidth: true,
+        height : '85.5%',
+        emptyrecords: 'A pasta nao contem nenhuma mensagem.',
+        viewrecords: true,
+        loadComplete: function(data) {
+            lastLoadedMessages = data.rows;
+
+            // aplica o contador
+            $('.timable').each(function (i) {
+                $(this).countdown({
+                    since: new Date(parseInt(this.title)),
+                    significant: 1,
+                    layout: 'h&aacute; {d<}{dn} {dl} {d>}{h<}{hn} {hl} {h>}{m<}{mn} {ml} {m>}{s<}{sn} {sl}{s>}',
+                    description: ' atr&aacute;s'
+                });
+            });
+        }
+    });
+    Grid.jqGrid('bindKeys', {"onEnter":function( rowid ) { alert("You enter a row with id:"+rowid)} });
 });
Index: sandbox/newExpressoMail/prototype/modules/newMail/templates/index.ejs
===================================================================
--- sandbox/newExpressoMail/prototype/modules/newMail/templates/index.ejs	(revision 7210)
+++ sandbox/newExpressoMail/prototype/modules/newMail/templates/index.ejs	(revision 7265)
@@ -9,6 +9,4 @@
 
 <link rel="stylesheet" type="text/css" href="<?= MODULESURL ?>/css/reset.css" />
-<link rel='stylesheet' type='text/css' href='<?= PLUGINSURL ?>/fullcalendar/fullcalendar.css' />
-<link rel='stylesheet' type='text/css' href='<?= PLUGINSURL ?>/fullcalendar/fullcalendar.print.css' media='print' />
 
 <link rel='stylesheet' type='text/css' href='<?= PLUGINSURL ?>/jquery/jquery-ui.css'/>
@@ -20,6 +18,4 @@
 
 <link rel='stylesheet' type='text/css' href='<?= PLUGINSURL ?>/fileupload/jquery.fileupload-ui.css'/>
-<link rel="stylesheet" type='text/css' href="<?= PLUGINSURL ?>/jquery.pagination/pagination.css" />
-
 <!-- JPicker -->
 <link rel="Stylesheet" type="text/css" href="<?= PLUGINSURL ?>/jpicker/css/jPicker-1.1.6.min.css" />
@@ -39,5 +35,4 @@
 <link rel="stylesheet" type="text/css" href="<?= MODULESURL ?>/css/main.css" />
 
-
 <script type='text/javascript' src='<?= PLUGINSURL ?>/datejs/date-pt-BR.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/jquery/jquery.min.js'></script>
@@ -49,49 +44,16 @@
 <script type='text/javascript' src='<?= PLUGINSURL ?>/json2/json2.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/store/jquery.store.js'></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/fileupload/jquery.fileupload.js'></script>
-<!--<script type='text/javascript' src='<?= PLUGINSURL ?>/fileupload/jquery.fileupload-ui.js'></script>-->
-<script type='text/javascript' src='<?= PLUGINSURL ?>/fileupload/jquery.iframe-transport.js'></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/store/jquery.store.js'></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/jquery.pagination/jquery.pagination.js"></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/mask/jquery.maskedinput.js'></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/alphanumeric/jquery.alphanumeric.js'></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/watermark/jquery.watermarkinput.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/encoder/encoder.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/../api/datalayer.js'></script>
 <script type="text/javascript" src='<?= PLUGINSURL ?>/dateFormat/dateFormat.js'></script>
 
-<!-- Datejs -->    
-<!-- <script type='text/javascript' src='<?= ROOTPATH ?>datejs/core.js'></script>
-<!-- <script type='text/javascript' src='<?= PLUGINSURL ?>/datejs/date-pt-BR.js'></script>-->
-<!-- <script type='text/javascript' src='<?= PLUGINSURL ?>/datejs/globalization/pt-BR.js'></script> -->
+<!-- Datejs -->
 <script type='text/javascript' src='<?= PLUGINSURL ?>/datejs/sugarpak.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/datejs/parser.js'></script>
 
-<!--  <script type='text/javascript' src='<?= ROOTPATH ?>datejs/time.js'></script>  -->
-<script type='text/javascript' src='<?= PLUGINSURL ?>/dateFormat/dateFormat.js'></script>
-<!--<script type='text/javascript' src='../fullcalendar/fullcalendar.min.js'></script>-->
-<script type='text/javascript' src='<?= PLUGINSURL ?>/fullcalendar/fullcalendar.js'></script>
-<script type='text/javascript' src='<?= PLUGINSURL ?>/fullcalendar/gcal.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/jquery.dateFormat/jquery.dateFormat.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/zebradialog/javascript/zebra_dialog.js'></script>
 <script type='text/javascript' src='<?= PLUGINSURL ?>/scrollto/jquery.scrollTo.js'></script>
 <!-- <script type='text/javascript' src='<?= PLUGINSURL ?>/view/jquerymx-1.0.custom.min.js'></script> -->
-<script type='text/javascript' src='<?= PLUGINSURL ?>/ejs/ejs.js'></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/fgmenu/fg.menu.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/qtip/jquery.qtip-1.0.0-rc3.min.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/contextmenu/jquery.contextMenu.js"></script>
-
-<!-- JPicker -->
-<script type="text/javascript" src="<?= PLUGINSURL ?>/jpicker/jpicker-1.1.6.min.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/farbtastic/farbtastic.js"></script>
-
-<!-- TREEVIEW -->
-<script type="text/javascript" src="<?= PLUGINSURL ?>/treeview/jquery.treeview.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/treeview/lib/jquery.cookie.js"></script>
-
-<script type="text/javascript" src="<?= PLUGINSURL ?>/wijmo/jquery.wijmo-open.all.2.2.0.min.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/layout/jquery.layout.min.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/jqgrid/js/i18n/grid.locale-pt-br.js"></script>
-<script type="text/javascript" src="<?= PLUGINSURL ?>/jqgrid/js/jquery.jqGrid.min.js"></script>
 
 <script type="text/javascript">
@@ -107,9 +69,5 @@
 </script>
 
-<script type="text/javascript" src="<?= MODULESURL ?>/js/formatters.js"></script>
-<script type="text/javascript" src="<?= MODULESURL ?>/js/init.js"></script>
-<script type="text/javascript" src="<?= MODULESURL ?>/js/newfoldertree.js"></script>
-<script type="text/javascript" src="<?= MODULESURL ?>/js/tabs.js"></script>
-<script type="text/javascript" src="<?= MODULESURL ?>/js/folder.js"></script>
+<script type='text/javascript' src='../newExpressoMail/inc/core.php'></script>
 
 </head>
