<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>README</filename>
    </added>
    <added>
      <filename>public/images/rails.png</filename>
    </added>
    <added>
      <filename>test/performance/browsing_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,50 +1,59 @@
 development:
-  # Sqlite3 Settings
+  # Sqlite Settings
   adapter: sqlite3
   database: db/development.sqlite3
+  pool: 5
   timeout: 5000
-  
+
   # Mysql Settings
   # adapter: mysql
   # encoding: utf8
-  # database: test_development
+  # database: bort_development
   # username: root
   # password:
-
+  # pool: 5
+  
 test:
-  # Sqlite3 Settings
+  # Sqlite Settings
   adapter: sqlite3
   database: db/test.sqlite3
+  pool: 5
   timeout: 5000
-  
+
   # Mysql Settings
   # adapter: mysql
   # encoding: utf8
-  # database: test_development
+  # database: bort_test
   # username: root
   # password:
-
+  # pool: 5
+  
 staging:
-  # Sqlite3 Settings    
+  # Sqlite Settings
   adapter: sqlite3
   database: db/staging.sqlite3
+  pool: 5
   timeout: 5000
+
   # Mysql Settings
   # adapter: mysql
   # encoding: utf8
-  # database: test_development
+  # database: bort_staging
   # username: root
-  # password:  
-
+  # password:
+  # pool: 5
+  
 production:
-  # Sqlite3 Settings
+  # Sqlite Settings
   adapter: sqlite3
   database: db/production.sqlite3
+  pool: 5
   timeout: 5000
-  
+
   # Mysql Settings
   # adapter: mysql
   # encoding: utf8
-  # database: test_development
+  # database: bort_production
   # username: root
   # password:
+  # pool: 5
\ No newline at end of file</diff>
      <filename>config/database.yml</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@
 # ENV['RAILS_ENV'] ||= 'production'
 
 # Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.1.1' unless defined? RAILS_GEM_VERSION
+RAILS_GEM_VERSION = '2.2.0' unless defined? RAILS_GEM_VERSION
 
 # Bootstrap the Rails environment, frameworks, and default configuration
 require File.join(File.dirname(__FILE__), 'boot')
@@ -22,9 +22,12 @@ Rails::Initializer.run do |config|
 
   # Specify gems that this application depends on. 
   # They can then be installed with &quot;rake gems:install&quot; on new installations.
+  # You have to specify the &lt;tt&gt;:lib&lt;/tt&gt; option for libraries, where the Gem name (&lt;em&gt;sqlite3-ruby&lt;/em&gt;) differs from the file itself (_sqlite3_)
+  # config.gem &quot;bj&quot;
   # config.gem &quot;hpricot&quot;, :version =&gt; '0.6', :source =&gt; &quot;http://code.whytheluckystiff.net&quot;
+  # config.gem &quot;sqlite3-ruby&quot;, :lib =&gt; &quot;sqlite3&quot;
   # config.gem &quot;aws-s3&quot;, :lib =&gt; &quot;aws/s3&quot;
-config.gem &quot;capistrano-ext&quot;, :lib =&gt; &quot;capistrano&quot;
+  config.gem &quot;capistrano-ext&quot;, :lib =&gt; &quot;capistrano&quot;
 
   # Only load the plugins named here, in the order given. By default, all plugins 
   # in vendor/plugins are loaded in alphabetical order.
@@ -49,7 +52,7 @@ config.gem &quot;capistrano-ext&quot;, :lib =&gt; &quot;capistrano&quot;
   # no regular words or you'll be exposed to dictionary attacks.
   config.action_controller.session = {
     :session_key =&gt; '_bort_session',
-    :secret      =&gt; 'c9ba017060e99fd4e23621a963dfe5d05e7975c732e622924b4a9b86a6b6d60ca6c067429f937c06675480f3181fc39f0d5328a73b559c3879cc2d9bee662c9d'
+    :secret      =&gt; 'a3e2a51a371bb964a4250c21f8d083f9ddb224d455171dcba55518e74af43366e52e3f239773f90aed0ab6caf6554f051504ce7232599d066150dbabff0f1654'
   }
 
   # Use the database for sessions instead of the cookie-based default,
@@ -63,5 +66,6 @@ config.gem &quot;capistrano-ext&quot;, :lib =&gt; &quot;capistrano&quot;
   # config.active_record.schema_format = :sql
 
   # Activate observers that should always be running
+  # Please note that observers generated using script/generate observer need to have an _observer suffix
   config.active_record.observers = :user_observer
-end
\ No newline at end of file
+end</diff>
      <filename>config/environment.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,13 +4,15 @@
 # Code is not reloaded between requests
 config.cache_classes = true
 
+# Enable threaded mode
+# config.threadsafe!
+
 # Use a different logger for distributed setups
 # config.logger = SyslogLogger.new
 
 # Full error reports are disabled and caching is turned on
 config.action_controller.consider_all_requests_local = false
 config.action_controller.perform_caching             = true
-config.action_view.cache_template_loading            = true
 
 # Use a different cache store in production
 # config.cache_store = :mem_cache_store
@@ -23,4 +25,4 @@ config.action_view.cache_template_loading            = true
 
 # Restful Authentication
 REST_AUTH_SITE_KEY = 'f5945d1c74d3502f8a3de8562e5bf21fe3fec887'
-REST_AUTH_DIGEST_STRETCHES = 10
+REST_AUTH_DIGEST_STRETCHES = 10
\ No newline at end of file</diff>
      <filename>config/environments/production.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,13 +4,15 @@
 # Code is not reloaded between requests
 config.cache_classes = true
 
+# Enable threaded mode
+# config.threadsafe!
+
 # Use a different logger for distributed setups
 # config.logger = SyslogLogger.new
 
 # Full error reports are disabled and caching is turned on
 config.action_controller.consider_all_requests_local = false
 config.action_controller.perform_caching             = true
-config.action_view.cache_template_loading            = true
 
 # Use a different cache store in production
 # config.cache_store = :mem_cache_store
@@ -23,4 +25,4 @@ config.action_view.cache_template_loading            = true
 
 # Restful Authentication
 REST_AUTH_SITE_KEY = 'f5945d1c74d3502f8a3de8562e5bf21fe3fec887'
-REST_AUTH_DIGEST_STRETCHES = 10
+REST_AUTH_DIGEST_STRETCHES = 10
\ No newline at end of file</diff>
      <filename>config/environments/staging.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,4 +23,4 @@ config.action_mailer.delivery_method = :test
 
 # Restful Authentication
 REST_AUTH_SITE_KEY = 'f5945d1c74d3502f8a3de8562e5bf21fe3fec887'
-REST_AUTH_DIGEST_STRETCHES = 10
+REST_AUTH_DIGEST_STRETCHES = 10
\ No newline at end of file</diff>
      <filename>config/environments/test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -62,7 +62,7 @@ ActiveRecord::Schema.define(:version =&gt; 20080929171348) do
     t.string   &quot;salt&quot;,                      :limit =&gt; 40
     t.string   &quot;remember_token&quot;,            :limit =&gt; 40
     t.string   &quot;activation_code&quot;,           :limit =&gt; 40
-    t.string   &quot;state&quot;,                                    :default =&gt; &quot;passive&quot;
+    t.string   &quot;state&quot;,                                    :default =&gt; &quot;passive&quot;, :null =&gt; false
     t.datetime &quot;remember_token_expires_at&quot;
     t.datetime &quot;activated_at&quot;
     t.datetime &quot;deleted_at&quot;</diff>
      <filename>db/schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,9 @@
   &lt;div class=&quot;dialog&quot;&gt;
     &lt;h1&gt;We're sorry, but something went wrong.&lt;/h1&gt;
     &lt;p&gt;We've been notified about this issue and we'll take a look at it shortly.&lt;/p&gt;
+    &lt;p&gt;&lt;small&gt;(If you're the administrator of this website, then please read
+    the log file &quot;&lt;%=h RAILS_ENV %&gt;.log&quot;
+    to find out what went wrong.)&lt;/small&gt;&lt;/p&gt;
   &lt;/div&gt;
 &lt;/body&gt;
-&lt;/html&gt;
\ No newline at end of file
+&lt;/html&gt;</diff>
      <filename>public/500.html</filename>
    </modified>
    <modified>
      <diff>@@ -7,4 +7,4 @@ require File.dirname(__FILE__) + &quot;/../config/environment&quot; unless defined?(RAILS_
 require &quot;dispatcher&quot;
 
 ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
\ No newline at end of file
+Dispatcher.dispatch</diff>
      <filename>public/dispatch.cgi</filename>
    </modified>
    <modified>
      <diff>@@ -7,4 +7,4 @@ require File.dirname(__FILE__) + &quot;/../config/environment&quot; unless defined?(RAILS_
 require &quot;dispatcher&quot;
 
 ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
\ No newline at end of file
+Dispatcher.dispatch</diff>
      <filename>public/dispatch.rb</filename>
    </modified>
    <modified>
      <diff>@@ -0,0 +1,2 @@
+// Place your application-specific JavaScript functions and classes here
+// This file is automatically included by javascript_include_tag :defaults</diff>
      <filename>public/javascripts/application.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
-/*  Prototype JavaScript framework, version 1.6.0.1
- *  (c) 2005-2007 Sam Stephenson
+/*  Prototype JavaScript framework, version 1.6.0.2
+ *  (c) 2005-2008 Sam Stephenson
  *
  *  Prototype is freely distributable under the terms of an MIT-style license.
  *  For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,7 +7,7 @@
  *--------------------------------------------------------------------------*/
 
 var Prototype = {
-  Version: '1.6.0.1',
+  Version: '1.6.0.2',
 
   Browser: {
     IE:     !!(window.attachEvent &amp;&amp; !window.opera),
@@ -110,7 +110,7 @@ Object.extend(Object, {
     try {
       if (Object.isUndefined(object)) return 'undefined';
       if (object === null) return 'null';
-      return object.inspect ? object.inspect() : object.toString();
+      return object.inspect ? object.inspect() : String(object);
     } catch (e) {
       if (e instanceof RangeError) return '...';
       throw e;
@@ -171,7 +171,8 @@ Object.extend(Object, {
   },
 
   isArray: function(object) {
-    return object &amp;&amp; object.constructor === Array;
+    return object != null &amp;&amp; typeof object == &quot;object&quot; &amp;&amp;
+      'splice' in object &amp;&amp; 'join' in object;
   },
 
   isHash: function(object) {
@@ -578,7 +579,7 @@ var Template = Class.create({
       }
 
       return before + String.interpret(ctx);
-    }.bind(this));
+    });
   }
 });
 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
@@ -806,20 +807,20 @@ Object.extend(Enumerable, {
 function $A(iterable) {
   if (!iterable) return [];
   if (iterable.toArray) return iterable.toArray();
-  var length = iterable.length, results = new Array(length);
+  var length = iterable.length || 0, results = new Array(length);
   while (length--) results[length] = iterable[length];
   return results;
 }
 
 if (Prototype.Browser.WebKit) {
-  function $A(iterable) {
+  $A = function(iterable) {
     if (!iterable) return [];
     if (!(Object.isFunction(iterable) &amp;&amp; iterable == '[object NodeList]') &amp;&amp;
         iterable.toArray) return iterable.toArray();
-    var length = iterable.length, results = new Array(length);
+    var length = iterable.length || 0, results = new Array(length);
     while (length--) results[length] = iterable[length];
     return results;
-  }
+  };
 }
 
 Array.from = $A;
@@ -1298,7 +1299,7 @@ Ajax.Request = Class.create(Ajax.Base, {
 
       var contentType = response.getHeader('Content-type');
       if (this.options.evalJS == 'force'
-          || (this.options.evalJS &amp;&amp; contentType
+          || (this.options.evalJS &amp;&amp; this.isSameOrigin() &amp;&amp; contentType
           &amp;&amp; contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
         this.evalResponse();
     }
@@ -1316,9 +1317,18 @@ Ajax.Request = Class.create(Ajax.Base, {
     }
   },
 
+  isSameOrigin: function() {
+    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+      protocol: location.protocol,
+      domain: document.domain,
+      port: location.port ? ':' + location.port : ''
+    }));
+  },
+
   getHeader: function(name) {
     try {
-      return this.transport.getResponseHeader(name);
+      return this.transport.getResponseHeader(name) || null;
     } catch (e) { return null }
   },
 
@@ -1391,7 +1401,8 @@ Ajax.Response = Class.create({
     if (!json) return null;
     json = decodeURIComponent(escape(json));
     try {
-      return json.evalJSON(this.request.options.sanitizeJSON);
+      return json.evalJSON(this.request.options.sanitizeJSON ||
+        !this.request.isSameOrigin());
     } catch (e) {
       this.request.dispatchException(e);
     }
@@ -1404,7 +1415,8 @@ Ajax.Response = Class.create({
         this.responseText.blank())
           return null;
     try {
-      return this.responseText.evalJSON(options.sanitizeJSON);
+      return this.responseText.evalJSON(options.sanitizeJSON ||
+        !this.request.isSameOrigin());
     } catch (e) {
       this.request.dispatchException(e);
     }
@@ -1608,24 +1620,28 @@ Element.Methods = {
         Object.isElement(insertions) || (insertions &amp;&amp; (insertions.toElement || insertions.toHTML)))
           insertions = {bottom:insertions};
 
-    var content, t, range;
+    var content, insert, tagName, childNodes;
 
-    for (position in insertions) {
+    for (var position in insertions) {
       content  = insertions[position];
       position = position.toLowerCase();
-      t = Element._insertionTranslations[position];
+      insert = Element._insertionTranslations[position];
 
       if (content &amp;&amp; content.toElement) content = content.toElement();
       if (Object.isElement(content)) {
-        t.insert(element, content);
+        insert(element, content);
         continue;
       }
 
       content = Object.toHTML(content);
 
-      range = element.ownerDocument.createRange();
-      t.initializeRange(element, range);
-      t.insert(element, range.createContextualFragment(content.stripScripts()));
+      tagName = ((position == 'before' || position == 'after')
+        ? element.parentNode : element).tagName.toUpperCase();
+
+      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+      if (position == 'top' || position == 'after') childNodes.reverse();
+      childNodes.each(insert.curry(element));
 
       content.evalScripts.bind(content).defer();
     }
@@ -1670,7 +1686,7 @@ Element.Methods = {
   },
 
   descendants: function(element) {
-    return $(element).getElementsBySelector(&quot;*&quot;);
+    return $(element).select(&quot;*&quot;);
   },
 
   firstDescendant: function(element) {
@@ -1709,32 +1725,31 @@ Element.Methods = {
     element = $(element);
     if (arguments.length == 1) return $(element.parentNode);
     var ancestors = element.ancestors();
-    return expression ? Selector.findElement(ancestors, expression, index) :
-      ancestors[index || 0];
+    return Object.isNumber(expression) ? ancestors[expression] :
+      Selector.findElement(ancestors, expression, index);
   },
 
   down: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return element.firstDescendant();
-    var descendants = element.descendants();
-    return expression ? Selector.findElement(descendants, expression, index) :
-      descendants[index || 0];
+    return Object.isNumber(expression) ? element.descendants()[expression] :
+      element.select(expression)[index || 0];
   },
 
   previous: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
     var previousSiblings = element.previousSiblings();
-    return expression ? Selector.findElement(previousSiblings, expression, index) :
-      previousSiblings[index || 0];
+    return Object.isNumber(expression) ? previousSiblings[expression] :
+      Selector.findElement(previousSiblings, expression, index);
   },
 
   next: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
     var nextSiblings = element.nextSiblings();
-    return expression ? Selector.findElement(nextSiblings, expression, index) :
-      nextSiblings[index || 0];
+    return Object.isNumber(expression) ? nextSiblings[expression] :
+      Selector.findElement(nextSiblings, expression, index);
   },
 
   select: function() {
@@ -1860,7 +1875,8 @@ Element.Methods = {
         do { ancestor = ancestor.parentNode; }
         while (!(nextAncestor = ancestor.nextSibling) &amp;&amp; ancestor.parentNode);
       }
-      if (nextAncestor) return (e &gt; a &amp;&amp; e &lt; nextAncestor.sourceIndex);
+      if (nextAncestor &amp;&amp; nextAncestor.sourceIndex)
+       return (e &gt; a &amp;&amp; e &lt; nextAncestor.sourceIndex);
     }
 
     while (element = element.parentNode)
@@ -2004,7 +2020,7 @@ Element.Methods = {
       if (element) {
         if (element.tagName == 'BODY') break;
         var p = Element.getStyle(element, 'position');
-        if (p == 'relative' || p == 'absolute') break;
+        if (p !== 'static') break;
       }
     } while (element);
     return Element._returnOffset(valueL, valueT);
@@ -2153,46 +2169,6 @@ Element._attributeTranslations = {
   }
 };
 
-
-if (!document.createRange || Prototype.Browser.Opera) {
-  Element.Methods.insert = function(element, insertions) {
-    element = $(element);
-
-    if (Object.isString(insertions) || Object.isNumber(insertions) ||
-        Object.isElement(insertions) || (insertions &amp;&amp; (insertions.toElement || insertions.toHTML)))
-          insertions = { bottom: insertions };
-
-    var t = Element._insertionTranslations, content, position, pos, tagName;
-
-    for (position in insertions) {
-      content  = insertions[position];
-      position = position.toLowerCase();
-      pos      = t[position];
-
-      if (content &amp;&amp; content.toElement) content = content.toElement();
-      if (Object.isElement(content)) {
-        pos.insert(element, content);
-        continue;
-      }
-
-      content = Object.toHTML(content);
-      tagName = ((position == 'before' || position == 'after')
-        ? element.parentNode : element).tagName.toUpperCase();
-
-      if (t.tags[tagName]) {
-        var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
-        if (position == 'top' || position == 'after') fragments.reverse();
-        fragments.each(pos.insert.curry(element));
-      }
-      else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
-
-      content.evalScripts.bind(content).defer();
-    }
-
-    return element;
-  };
-}
-
 if (Prototype.Browser.Opera) {
   Element.Methods.getStyle = Element.Methods.getStyle.wrap(
     function(proceed, element, style) {
@@ -2237,12 +2213,31 @@ if (Prototype.Browser.Opera) {
 }
 
 else if (Prototype.Browser.IE) {
-  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
+  // IE doesn't report offsets correctly for static elements, so we change them
+  // to &quot;relative&quot; to get the values, then change them back.
+  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+    function(proceed, element) {
+      element = $(element);
+      var position = element.getStyle('position');
+      if (position !== 'static') return proceed(element);
+      element.setStyle({ position: 'relative' });
+      var value = proceed(element);
+      element.setStyle({ position: position });
+      return value;
+    }
+  );
+
+  $w('positionedOffset viewportOffset').each(function(method) {
     Element.Methods[method] = Element.Methods[method].wrap(
       function(proceed, element) {
         element = $(element);
         var position = element.getStyle('position');
-        if (position != 'static') return proceed(element);
+        if (position !== 'static') return proceed(element);
+        // Trigger hasLayout on the offset parent so that IE6 reports
+        // accurate offsetTop and offsetLeft values for position: fixed.
+        var offsetParent = element.getOffsetParent();
+        if (offsetParent &amp;&amp; offsetParent.getStyle('position') === 'fixed')
+          offsetParent.setStyle({ zoom: 1 });
         element.setStyle({ position: 'relative' });
         var value = proceed(element);
         element.setStyle({ position: position });
@@ -2324,7 +2319,10 @@ else if (Prototype.Browser.IE) {
   };
 
   Element._attributeTranslations.write = {
-    names: Object.clone(Element._attributeTranslations.read.names),
+    names: Object.extend({
+      cellpadding: 'cellPadding',
+      cellspacing: 'cellSpacing'
+    }, Element._attributeTranslations.read.names),
     values: {
       checked: function(element, value) {
         element.checked = !!value;
@@ -2444,7 +2442,7 @@ if (Prototype.Browser.IE || Prototype.Browser.Opera) {
   };
 }
 
-if (document.createElement('div').outerHTML) {
+if ('outerHTML' in document.createElement('div')) {
   Element.Methods.replace = function(element, content) {
     element = $(element);
 
@@ -2482,45 +2480,25 @@ Element._returnOffset = function(l, t) {
 
 Element._getContentFromAnonymousElement = function(tagName, html) {
   var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
-  div.innerHTML = t[0] + html + t[1];
-  t[2].times(function() { div = div.firstChild });
+  if (t) {
+    div.innerHTML = t[0] + html + t[1];
+    t[2].times(function() { div = div.firstChild });
+  } else div.innerHTML = html;
   return $A(div.childNodes);
 };
 
 Element._insertionTranslations = {
-  before: {
-    adjacency: 'beforeBegin',
-    insert: function(element, node) {
-      element.parentNode.insertBefore(node, element);
-    },
-    initializeRange: function(element, range) {
-      range.setStartBefore(element);
-    }
+  before: function(element, node) {
+    element.parentNode.insertBefore(node, element);
   },
-  top: {
-    adjacency: 'afterBegin',
-    insert: function(element, node) {
-      element.insertBefore(node, element.firstChild);
-    },
-    initializeRange: function(element, range) {
-      range.selectNodeContents(element);
-      range.collapse(true);
-    }
+  top: function(element, node) {
+    element.insertBefore(node, element.firstChild);
   },
-  bottom: {
-    adjacency: 'beforeEnd',
-    insert: function(element, node) {
-      element.appendChild(node);
-    }
+  bottom: function(element, node) {
+    element.appendChild(node);
   },
-  after: {
-    adjacency: 'afterEnd',
-    insert: function(element, node) {
-      element.parentNode.insertBefore(node, element.nextSibling);
-    },
-    initializeRange: function(element, range) {
-      range.setStartAfter(element);
-    }
+  after: function(element, node) {
+    element.parentNode.insertBefore(node, element.nextSibling);
   },
   tags: {
     TABLE:  ['&lt;table&gt;',                '&lt;/table&gt;',                   1],
@@ -2532,7 +2510,6 @@ Element._insertionTranslations = {
 };
 
 (function() {
-  this.bottom.initializeRange = this.top.initializeRange;
   Object.extend(this.tags, {
     THEAD: this.tags.TBODY,
     TFOOT: this.tags.TBODY,
@@ -2716,7 +2693,7 @@ document.viewport = {
       window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
   }
 };
-/* Portions of the Selector class are derived from Jack Slocum&#8217;s DomQuery,
+/* Portions of the Selector class are derived from Jack Slocum&#226;&#8364;&#8482;s DomQuery,
  * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
  * license.  Please see http://www.yui-ext.com/ for more information. */
 
@@ -2959,13 +2936,13 @@ Object.extend(Selector, {
   },
 
   criteria: {
-    tagName:      'n = h.tagName(n, r, &quot;#{1}&quot;, c);   c = false;',
-    className:    'n = h.className(n, r, &quot;#{1}&quot;, c); c = false;',
-    id:           'n = h.id(n, r, &quot;#{1}&quot;, c);        c = false;',
-    attrPresence: 'n = h.attrPresence(n, r, &quot;#{1}&quot;); c = false;',
+    tagName:      'n = h.tagName(n, r, &quot;#{1}&quot;, c);      c = false;',
+    className:    'n = h.className(n, r, &quot;#{1}&quot;, c);    c = false;',
+    id:           'n = h.id(n, r, &quot;#{1}&quot;, c);           c = false;',
+    attrPresence: 'n = h.attrPresence(n, r, &quot;#{1}&quot;, c); c = false;',
     attr: function(m) {
       m[3] = (m[5] || m[6]);
-      return new Template('n = h.attr(n, r, &quot;#{1}&quot;, &quot;#{3}&quot;, &quot;#{2}&quot;); c = false;').evaluate(m);
+      return new Template('n = h.attr(n, r, &quot;#{1}&quot;, &quot;#{3}&quot;, &quot;#{2}&quot;, c); c = false;').evaluate(m);
     },
     pseudo: function(m) {
       if (m[6]) m[6] = m[6].replace(/&quot;/g, '\\&quot;');
@@ -2989,7 +2966,8 @@ Object.extend(Selector, {
     tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
     id:           /^#([\w\-\*]+)(\b|$)/,
     className:    /^\.([\w\-\*]+)(\b|$)/,
-    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
+    pseudo:
+/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~&gt;]))/,
     attrPresence: /^\[([\w]+)\]/,
     attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['&quot;])([^\4]*?)\4|([^'&quot;][^\]]*?)))?\]/
   },
@@ -3014,7 +2992,7 @@ Object.extend(Selector, {
 
     attr: function(element, matches) {
       var nodeValue = Element.readAttribute(element, matches[1]);
-      return Selector.operators[matches[2]](nodeValue, matches[3]);
+      return nodeValue &amp;&amp; Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
     }
   },
 
@@ -3029,14 +3007,15 @@ Object.extend(Selector, {
 
     // marks an array of nodes for counting
     mark: function(nodes) {
+      var _true = Prototype.emptyFunction;
       for (var i = 0, node; node = nodes[i]; i++)
-        node._counted = true;
+        node._countedByPrototype = _true;
       return nodes;
     },
 
     unmark: function(nodes) {
       for (var i = 0, node; node = nodes[i]; i++)
-        node._counted = undefined;
+        node._countedByPrototype = undefined;
       return nodes;
     },
 
@@ -3044,15 +3023,15 @@ Object.extend(Selector, {
     // &quot;ofType&quot; flag indicates whether we're indexing for nth-of-type
     // rather than nth-child
     index: function(parentNode, reverse, ofType) {
-      parentNode._counted = true;
+      parentNode._countedByPrototype = Prototype.emptyFunction;
       if (reverse) {
         for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i &gt;= 0; i--) {
           var node = nodes[i];
-          if (node.nodeType == 1 &amp;&amp; (!ofType || node._counted)) node.nodeIndex = j++;
+          if (node.nodeType == 1 &amp;&amp; (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
         }
       } else {
         for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
-          if (node.nodeType == 1 &amp;&amp; (!ofType || node._counted)) node.nodeIndex = j++;
+          if (node.nodeType == 1 &amp;&amp; (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
       }
     },
 
@@ -3061,8 +3040,8 @@ Object.extend(Selector, {
       if (nodes.length == 0) return nodes;
       var results = [], n;
       for (var i = 0, l = nodes.length; i &lt; l; i++)
-        if (!(n = nodes[i])._counted) {
-          n._counted = true;
+        if (!(n = nodes[i])._countedByPrototype) {
+          n._countedByPrototype = Prototype.emptyFunction;
           results.push(Element.extend(n));
         }
       return Selector.handlers.unmark(results);
@@ -3114,7 +3093,7 @@ Object.extend(Selector, {
 
     // TOKEN FUNCTIONS
     tagName: function(nodes, root, tagName, combinator) {
-      tagName = tagName.toUpperCase();
+      var uTagName = tagName.toUpperCase();
       var results = [], h = Selector.handlers;
       if (nodes) {
         if (combinator) {
@@ -3127,7 +3106,7 @@ Object.extend(Selector, {
           if (tagName == &quot;*&quot;) return nodes;
         }
         for (var i = 0, node; node = nodes[i]; i++)
-          if (node.tagName.toUpperCase() == tagName) results.push(node);
+          if (node.tagName.toUpperCase() === uTagName) results.push(node);
         return results;
       } else return root.getElementsByTagName(tagName);
     },
@@ -3174,16 +3153,18 @@ Object.extend(Selector, {
       return results;
     },
 
-    attrPresence: function(nodes, root, attr) {
+    attrPresence: function(nodes, root, attr, combinator) {
       if (!nodes) nodes = root.getElementsByTagName(&quot;*&quot;);
+      if (nodes &amp;&amp; combinator) nodes = this[combinator](nodes);
       var results = [];
       for (var i = 0, node; node = nodes[i]; i++)
         if (Element.hasAttribute(node, attr)) results.push(node);
       return results;
     },
 
-    attr: function(nodes, root, attr, value, operator) {
+    attr: function(nodes, root, attr, value, operator, combinator) {
       if (!nodes) nodes = root.getElementsByTagName(&quot;*&quot;);
+      if (nodes &amp;&amp; combinator) nodes = this[combinator](nodes);
       var handler = Selector.operators[operator], results = [];
       for (var i = 0, node; node = nodes[i]; i++) {
         var nodeValue = Element.readAttribute(node, attr);
@@ -3262,7 +3243,7 @@ Object.extend(Selector, {
       var h = Selector.handlers, results = [], indexed = [], m;
       h.mark(nodes);
       for (var i = 0, node; node = nodes[i]; i++) {
-        if (!node.parentNode._counted) {
+        if (!node.parentNode._countedByPrototype) {
           h.index(node.parentNode, reverse, ofType);
           indexed.push(node.parentNode);
         }
@@ -3300,7 +3281,7 @@ Object.extend(Selector, {
       var exclusions = new Selector(selector).findElements(root);
       h.mark(exclusions);
       for (var i = 0, results = [], node; node = nodes[i]; i++)
-        if (!node._counted) results.push(node);
+        if (!node._countedByPrototype) results.push(node);
       h.unmark(exclusions);
       return results;
     },
@@ -3334,11 +3315,19 @@ Object.extend(Selector, {
     '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
   },
 
+  split: function(expression) {
+    var expressions = [];
+    expression.scan(/(([\w#:.~&gt;+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+      expressions.push(m[1].strip());
+    });
+    return expressions;
+  },
+
   matchElements: function(elements, expression) {
-    var matches = new Selector(expression).findElements(), h = Selector.handlers;
+    var matches = $$(expression), h = Selector.handlers;
     h.mark(matches);
     for (var i = 0, results = [], element; element = elements[i]; i++)
-      if (element._counted) results.push(element);
+      if (element._countedByPrototype) results.push(element);
     h.unmark(matches);
     return results;
   },
@@ -3351,11 +3340,7 @@ Object.extend(Selector, {
   },
 
   findChildElements: function(element, expressions) {
-    var exprs = expressions.join(',');
-    expressions = [];
-    exprs.scan(/(([\w#:.~&gt;+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
-      expressions.push(m[1].strip());
-    });
+    expressions = Selector.split(expressions.join(','));
     var results = [], h = Selector.handlers;
     for (var i = 0, l = expressions.length, selector; i &lt; l; i++) {
       selector = new Selector(expressions[i].strip());
@@ -3366,13 +3351,22 @@ Object.extend(Selector, {
 });
 
 if (Prototype.Browser.IE) {
-  // IE returns comment nodes on getElementsByTagName(&quot;*&quot;).
-  // Filter them out.
-  Selector.handlers.concat = function(a, b) {
-    for (var i = 0, node; node = b[i]; i++)
-      if (node.tagName !== &quot;!&quot;) a.push(node);
-    return a;
-  };
+  Object.extend(Selector.handlers, {
+    // IE returns comment nodes on getElementsByTagName(&quot;*&quot;).
+    // Filter them out.
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        if (node.tagName !== &quot;!&quot;) a.push(node);
+      return a;
+    },
+
+    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
+    unmark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node.removeAttribute('_countedByPrototype');
+      return nodes;
+    }
+  });
 }
 
 function $$() {
@@ -3850,9 +3844,9 @@ Object.extend(Event, (function() {
   var cache = Event.cache;
 
   function getEventID(element) {
-    if (element._eventID) return element._eventID;
+    if (element._prototypeEventID) return element._prototypeEventID[0];
     arguments.callee.id = arguments.callee.id || 1;
-    return element._eventID = ++arguments.callee.id;
+    return element._prototypeEventID = [++arguments.callee.id];
   }
 
   function getDOMEventName(eventName) {
@@ -3880,7 +3874,7 @@ Object.extend(Event, (function() {
           return false;
 
       Event.extend(event);
-      handler.call(element, event)
+      handler.call(element, event);
     };
 
     wrapper.handler = handler;
@@ -3962,11 +3956,12 @@ Object.extend(Event, (function() {
       if (element == document &amp;&amp; document.createEvent &amp;&amp; !element.dispatchEvent)
         element = document.documentElement;
 
+      var event;
       if (document.createEvent) {
-        var event = document.createEvent(&quot;HTMLEvents&quot;);
+        event = document.createEvent(&quot;HTMLEvents&quot;);
         event.initEvent(&quot;dataavailable&quot;, true, true);
       } else {
-        var event = document.createEventObject();
+        event = document.createEventObject();
         event.eventType = &quot;ondataavailable&quot;;
       }
 
@@ -3995,20 +3990,21 @@ Element.addMethods({
 Object.extend(document, {
   fire:          Element.Methods.fire.methodize(),
   observe:       Element.Methods.observe.methodize(),
-  stopObserving: Element.Methods.stopObserving.methodize()
+  stopObserving: Element.Methods.stopObserving.methodize(),
+  loaded:        false
 });
 
 (function() {
   /* Support for the DOMContentLoaded event is based on work by Dan Webb,
      Matthias Miller, Dean Edwards and John Resig. */
 
-  var timer, fired = false;
+  var timer;
 
   function fireContentLoadedEvent() {
-    if (fired) return;
+    if (document.loaded) return;
     if (timer) window.clearInterval(timer);
     document.fire(&quot;dom:loaded&quot;);
-    fired = true;
+    document.loaded = true;
   }
 
   if (document.addEventListener) {</diff>
      <filename>public/javascripts/prototype.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>f8f1a1969affb95eaf682d318e26609e76886c74</id>
    </parent>
  </parents>
  <author>
    <name>Jim Neath</name>
    <email>jim@virtuaffinity.net</email>
  </author>
  <url>http://github.com/laktek/extended-bort/commit/c259d9d811793311e95d54219c23258ba034de90</url>
  <id>c259d9d811793311e95d54219c23258ba034de90</id>
  <committed-date>2008-11-06T03:52:44-08:00</committed-date>
  <authored-date>2008-11-06T03:52:44-08:00</authored-date>
  <message>Updated to Rails 2.2</message>
  <tree>75a51e14e8fb63269cdbdee11b0fbcc055a8a6da</tree>
  <committer>
    <name>Jim Neath</name>
    <email>jim@virtuaffinity.net</email>
  </committer>
</commit>
