Updated the system to Rails 1.2.
author<mako@atdot.cc> <>
Wed, 18 Jul 2007 20:57:49 +0000 (16:57 -0400)
committer<mako@atdot.cc> <>
Wed, 18 Jul 2007 20:57:49 +0000 (16:57 -0400)
In the process, I had to completely gut the login engine which means
that parts of the site that require logins will not work at all. This
should be fixed ASAP.

101 files changed:
README [changed mode: 0755->0644]
Rakefile [changed mode: 0755->0644]
app/controllers/application.rb [changed mode: 0755->0644]
app/controllers/election_controller.rb [changed mode: 0755->0644]
app/controllers/quickvote_controller.rb [changed mode: 0755->0644]
app/controllers/site_controller.rb [changed mode: 0755->0644]
app/controllers/user_controller.rb [changed mode: 0755->0644]
app/controllers/voter_controller.rb [changed mode: 0755->0644]
app/models/user.rb
app/views/layouts/hc.rhtml
config/boot.rb [changed mode: 0755->0644]
config/environment.rb [changed mode: 0755->0644]
config/environments/development.rb [changed mode: 0755->0644]
config/environments/production.rb [changed mode: 0755->0644]
config/environments/test.rb [changed mode: 0755->0644]
config/routes.rb [changed mode: 0755->0644]
doc/api [deleted symlink]
public/404.html
public/500.html
public/dispatch.cgi
public/dispatch.fcgi
public/dispatch.rb [changed mode: 0644->0755]
public/javascripts/controls.js
public/javascripts/dragdrop.js
public/javascripts/effects.js
public/javascripts/prototype.js
script/process/inspector [new file with mode: 0755]
script/process/spinner [deleted file]
vendor/actionmailer [deleted symlink]
vendor/actionpack [deleted symlink]
vendor/actionwebservice [deleted symlink]
vendor/activerecord [deleted symlink]
vendor/activesupport [deleted symlink]
vendor/plugins/engines/CHANGELOG [deleted file]
vendor/plugins/engines/MIT-LICENSE [deleted file]
vendor/plugins/engines/README [deleted file]
vendor/plugins/engines/generators/engine/USAGE [deleted file]
vendor/plugins/engines/generators/engine/engine_generator.rb [deleted file]
vendor/plugins/engines/generators/engine/templates/README [deleted file]
vendor/plugins/engines/generators/engine/templates/init_engine.erb [deleted file]
vendor/plugins/engines/generators/engine/templates/install.erb [deleted file]
vendor/plugins/engines/generators/engine/templates/lib/engine.erb [deleted file]
vendor/plugins/engines/generators/engine/templates/licenses/GPL [deleted file]
vendor/plugins/engines/generators/engine/templates/licenses/LGPL [deleted file]
vendor/plugins/engines/generators/engine/templates/licenses/MIT [deleted file]
vendor/plugins/engines/generators/engine/templates/licenses/None [deleted file]
vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js [deleted file]
vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css [deleted file]
vendor/plugins/engines/generators/engine/templates/tasks/engine.rake [deleted file]
vendor/plugins/engines/generators/engine/templates/test/test_helper.erb [deleted file]
vendor/plugins/engines/init.rb [deleted file]
vendor/plugins/engines/lib/bundles.rb [deleted file]
vendor/plugins/engines/lib/bundles/require_resource.rb [deleted file]
vendor/plugins/engines/lib/engines.rb [deleted file]
vendor/plugins/engines/lib/engines/action_mailer_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/action_view_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/active_record_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/dependencies_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/migration_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/routing_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/ruby_extensions.rb [deleted file]
vendor/plugins/engines/lib/engines/testing_extensions.rb [deleted file]
vendor/plugins/engines/tasks/deprecated_engines.rake [deleted file]
vendor/plugins/engines/tasks/engines.rake [deleted file]
vendor/plugins/engines/test/action_view_extensions_test.rb [deleted file]
vendor/plugins/engines/test/ruby_extensions_test.rb [deleted file]
vendor/plugins/login_engine/CHANGELOG [deleted file]
vendor/plugins/login_engine/README [deleted file]
vendor/plugins/login_engine/app/controllers/user_controller.rb [deleted file]
vendor/plugins/login_engine/app/helpers/user_helper.rb [deleted file]
vendor/plugins/login_engine/app/models/user.rb [deleted file]
vendor/plugins/login_engine/app/models/user_notify.rb [deleted file]
vendor/plugins/login_engine/app/views/user/_edit.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/_password.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/change_password.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/edit.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/forgot_password.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/home.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/login.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/logout.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user/signup.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user_notify/delete.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml [deleted file]
vendor/plugins/login_engine/app/views/user_notify/signup.rhtml [deleted file]
vendor/plugins/login_engine/db/migrate/001_initial_schema.rb [deleted file]
vendor/plugins/login_engine/init_engine.rb [deleted file]
vendor/plugins/login_engine/install.rb [deleted file]
vendor/plugins/login_engine/lib/login_engine.rb [deleted file]
vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb [deleted file]
vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb [deleted file]
vendor/plugins/login_engine/public/stylesheets/login_engine.css [deleted file]
vendor/plugins/login_engine/test/fixtures/users.yml [deleted file]
vendor/plugins/login_engine/test/functional/user_controller_test.rb [deleted file]
vendor/plugins/login_engine/test/mocks/mail.rb [deleted file]
vendor/plugins/login_engine/test/mocks/time.rb [deleted file]
vendor/plugins/login_engine/test/test_helper.rb [deleted file]
vendor/plugins/login_engine/test/unit/user_test.rb [deleted file]
vendor/rails [deleted symlink]
vendor/railties [deleted symlink]

diff --git a/README b/README
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 7462619..d92ab97
@@ -1,9 +1,7 @@
 # Filters added to this controller will be run for all controllers in the application.
 # Likewise, all the methods added will be available for all controllers.
-require 'login_engine'
 
 class ApplicationController < ActionController::Base
-  include LoginEngine
   helper :user
   model :user
 end
old mode 100755 (executable)
new mode 100644 (file)
index 3a43c8e..a418c49
@@ -2,7 +2,7 @@ class ElectionController < ApplicationController
   model :raw_voter_list, :voter, :vote, :candidate
   layout 'hc'
 
-  before_filter :login_required
+  #before_filter :login_required
 
   ## methods for displaying, creating,
   ## and manipulating election overview data
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 4f25e06983a24065464f2a320e7d820f04f95ea9..17f58a1b16c9947843a806390486ca1d19c434f7 100755 (executable)
@@ -1,6 +1,4 @@
 class User < ActiveRecord::Base
-  include LoginEngine::AuthenticatedUser
-
   has_many :elections
 
   def name
index b090bf181433dead747e15bc9351463fdbf019ba..860992a4dbd25a495ac247035a25aa807b7a4a40 100755 (executable)
@@ -3,7 +3,6 @@
     <head>
         <title><%= @page_title || "Selectricity" %></title>
         <%= stylesheet_link_tag "hc", :media => "all" %>
-        <% #engine_stylesheet 'login_engine' %>
  
         <%= javascript_include_tag "prototype", "effects", "dragdrop", "controls" %>
     </head>
old mode 100755 (executable)
new mode 100644 (file)
index 9a094cb..b7af0c3
@@ -3,7 +3,7 @@
 unless defined?(RAILS_ROOT)
   root_path = File.join(File.dirname(__FILE__), '..')
 
-  unless RUBY_PLATFORM =~ /mswin32/
+  unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
     require 'pathname'
     root_path = Pathname.new(root_path).cleanpath(true).to_s
   end
@@ -22,23 +22,24 @@ unless defined?(Rails::Initializer)
     rails_gem_version = $1
 
     if version = defined?(RAILS_GEM_VERSION) ? RAILS_GEM_VERSION : rails_gem_version
-      rails_gem = Gem.cache.search('rails', "=#{version}").first
+      # Asking for 1.1.6 will give you 1.1.6.5206, if available -- makes it easier to use beta gems
+      rails_gem = Gem.cache.search('rails', "~>#{version}.0").sort_by { |g| g.version.version }.last
 
       if rails_gem
-        require_gem "rails", "=#{version}"
+        gem "rails", "=#{rails_gem.version.version}"
         require rails_gem.full_gem_path + '/lib/initializer'
       else
-        STDERR.puts %(Cannot find gem for Rails =#{version}:
+        STDERR.puts %(Cannot find gem for Rails ~>#{version}.0:
     Install the missing gem with 'gem install -v=#{version} rails', or
     change environment.rb to define RAILS_GEM_VERSION with your desired version.
   )
         exit 1
       end
     else
-      require_gem "rails"
+      gem "rails"
       require 'initializer'
     end
   end
 
   Rails::Initializer.run(:set_load_path)
-end
\ No newline at end of file
+end
old mode 100755 (executable)
new mode 100644 (file)
index 7159e1f..7d3657e
@@ -5,17 +5,20 @@
 # ENV['RAILS_ENV'] ||= 'production'
 
 # Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '1.1.6'
+RAILS_GEM_VERSION = '1.2.3' unless defined? RAILS_GEM_VERSION
 
 # Bootstrap the Rails environment, frameworks, and default configuration
 require File.join(File.dirname(__FILE__), 'boot')
 
 Rails::Initializer.run do |config|
-  # Settings in config/environments/* take precedence those specified here
+  # Settings in config/environments/* take precedence over those specified here
   
   # Skip frameworks you're not going to use (only works if using vendor/rails)
   # config.frameworks -= [ :action_web_service, :action_mailer ]
 
+  # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
+  # config.plugins = %W( exception_notification ssl_requirement )
+
   # Add additional load paths for your own custom dirs
   # config.load_paths += %W( #{RAILS_ROOT}/extras )
 
@@ -36,7 +39,7 @@ Rails::Initializer.run do |config|
   # config.active_record.observers = :cacher, :garbage_collector
 
   # Make Active Record use UTC-base instead of local time
-  config.active_record.default_timezone = :utc
+  config.active_record.default_timezone = :utc
   
   # See Rails::Configuration for more options
 end
@@ -50,9 +53,14 @@ end
 #   inflect.uncountable %w( fish sheep )
 # end
 
-MAIL_CONFIG = { :from => 'Selectricity <info@selectricity.media.mit.edu>'} 
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register "application/x-mobile", :mobile
 
 # Include your application configuration below
+
+MAIL_CONFIG = { :from => 'Selectricity <info@selectricity.media.mit.edu>'} 
+
 require 'uniq_token'
 require 'randarray'
 require 'rubyvote'
@@ -75,17 +83,6 @@ class String
   end
 end
 
-module LoginEngine
-  config :salt, "voothingboat"
-  config :email_from, MAIL_CONFIG[:from]
-  config :admin_email, MAIL_CONFIG[:from]
-  config :app_name, 'Selectricity'
-  config :changeable_fields, []
-  config :use_email_notification, true
-  config :confirm_account, false
-end
-Engines.start :login
-
 # action mailer configuration
 ActionMailer::Base.delivery_method = :sendmail
 ActionMailer::Base.default_charset = "utf-8"
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 5a4e2b1..cb295b8
@@ -14,5 +14,5 @@ config.action_controller.perform_caching             = true
 # Enable serving of images, stylesheets, and javascripts from an asset server
 # config.action_controller.asset_host                  = "http://assets.example.com"
 
-# Disable delivery errors if you bad email addresses should just be ignored
+# Disable delivery errors, bad email addresses will be ignored
 # config.action_mailer.raise_delivery_errors = false
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index e400b5d..7a7b101
@@ -1,4 +1,4 @@
-ActionController::Routing::Routes.draw do |map|
+ActionController::Routing::Routes.draw do |map|  
   # The priority is based upon order of creation: first created -> highest priority.
   
   # Sample of regular route:
@@ -14,21 +14,21 @@ ActionController::Routing::Routes.draw do |map|
   map.connect '', :controller => "site"
  
   map.connect 'quickvote/:action/:id',
-              :controller => 'quickvote',
-             :requirements => { :action => /(create|add_candidate|sort_candidates)/ }
+               :controller => 'quickvote',
+               :requirements => { :action => /(create|add_candidate|sort_candidates)/ }
 
   map.quickaction 'quickvote/:votename/:action',
                   :controller => 'quickvote',
-                 :requirements => { :action => /(change|confirm|results)/ }
+                       :requirements => { :action => /(change|confirm|results)/ }
 
   map.quickvote 'quickvote/:votename',
-                :controller => 'quickvote',
-               :action => 'index'
+                :controller => 'quickvote', :action => 'index'
 
   # Allow downloading Web Service WSDL as a file with an extension
   # instead of a file named 'wsdl'
   map.connect ':controller/service.wsdl', :action => 'wsdl'
 
   # Install the default route as the lowest priority.
+  map.connect ':controller/:action/:id.:format'
   map.connect ':controller/:action/:id'
 end
diff --git a/doc/api b/doc/api
deleted file mode 120000 (symlink)
index 8808e40..0000000
--- a/doc/api
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/doc/rails/html
\ No newline at end of file
index 0e1845619d8d06bf998b2b2aff7c2241c7abd009..eff660b90c3e514c9ed1d8ca788e688fecf5e519 100644 (file)
@@ -1,8 +1,30 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+  <title>The page you were looking for doesn't exist (404)</title>
+       <style type="text/css">
+               body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+               div.dialog {
+                       width: 25em;
+                       padding: 0 4em;
+                       margin: 4em auto 0 auto;
+                       border: 1px solid #ccc;
+                       border-right-color: #999;
+                       border-bottom-color: #999;
+               }
+               h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+       </style>
+</head>
+
 <body>
-  <h1>File not found</h1>
-  <p>Change this error message for pages not found in public/404.html</p>
+  <!-- This file lives in public/404.html -->
+  <div class="dialog">
+    <h1>The page you were looking for doesn't exist.</h1>
+    <p>You may have mistyped the address or the page may have moved.</p>
+  </div>
 </body>
 </html>
\ No newline at end of file
index ab95f74c4661b6ebc19908a47d1ce39f4b66087a..f0aee0e9f1f9a9e7c20977ee272f5b8760e03ea0 100644 (file)
@@ -1,8 +1,30 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+  <title>We're sorry, but something went wrong</title>
+       <style type="text/css">
+               body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+               div.dialog {
+                       width: 25em;
+                       padding: 0 4em;
+                       margin: 4em auto 0 auto;
+                       border: 1px solid #ccc;
+                       border-right-color: #999;
+                       border-bottom-color: #999;
+               }
+               h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+       </style>
+</head>
+
 <body>
-  <h1>Application error</h1>
-  <p>Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html</p>
+  <!-- This file lives in public/500.html -->
+  <div class="dialog">
+    <h1>We're sorry, but something went wrong.</h1>
+    <p>We've been notified about this issue and we'll take a look at it shortly.</p>
+  </div>
 </body>
 </html>
\ No newline at end of file
index dfe5dc30e73a4c922406095b7d3c44e54d3dad17..3848806db350e1d9269b2e038b1ddfd2818fd9fc 100755 (executable)
@@ -1,7 +1,5 @@
 #!/usr/bin/ruby1.8
 
-#!/usr/local/bin/ruby
-
 require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
 
 # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
index d02c35b8b873f13b560cdc6998847a8ed5b9aad3..3169ba26768334f7eae51d93900f2ff548223d2c 100755 (executable)
@@ -1,6 +1,4 @@
 #!/usr/bin/ruby1.8
-
-#!/usr/local/bin/ruby
 #
 # You may specify the path to the FastCGI crash log (a log of unhandled
 # exceptions which forced the FastCGI instance to exit, great for debugging)
old mode 100644 (file)
new mode 100755 (executable)
index dfe5dc3..3848806
@@ -1,7 +1,5 @@
 #!/usr/bin/ruby1.8
 
-#!/usr/local/bin/ruby
-
 require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
 
 # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
index de0261ed54843afa8dd651ffcce7fdeb685f23c4..8c273f874f91753b0ba78389f892e18cf6335e88 100755 (executable)
@@ -1,12 +1,13 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//           (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-//           (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+//           (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
 // Contributors:
 //  Richard Livsey
 //  Rahul Bhargava
 //  Rob Wills
 // 
-// See scriptaculous.js for full license.
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
 
 // Autocompleter.Base handles all the autocompletion functionality 
 // that's independent of the data source for autocompletion. This
@@ -33,6 +34,9 @@
 // useful when one of the tokens is \n (a newline), as it 
 // allows smart autocompletion after linebreaks.
 
+if(typeof Effect == 'undefined')
+  throw("controls.js requires including script.aculo.us' effects.js library");
+
 var Autocompleter = {}
 Autocompleter.Base = function() {};
 Autocompleter.Base.prototype = {
@@ -45,7 +49,7 @@ Autocompleter.Base.prototype = {
     this.index       = 0;     
     this.entryCount  = 0;
 
-    if (this.setOptions)
+    if(this.setOptions)
       this.setOptions(options);
     else
       this.options = options || {};
@@ -55,17 +59,20 @@ Autocompleter.Base.prototype = {
     this.options.frequency    = this.options.frequency || 0.4;
     this.options.minChars     = this.options.minChars || 1;
     this.options.onShow       = this.options.onShow || 
-    function(element, update){ 
-      if(!update.style.position || update.style.position=='absolute') {
-        update.style.position = 'absolute';
-        Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
-      }
-      Effect.Appear(update,{duration:0.15});
-    };
+      function(element, update){ 
+        if(!update.style.position || update.style.position=='absolute') {
+          update.style.position = 'absolute';
+          Position.clone(element, update, {
+            setHeight: false, 
+            offsetTop: element.offsetHeight
+          });
+        }
+        Effect.Appear(update,{duration:0.15});
+      };
     this.options.onHide = this.options.onHide || 
-    function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
 
-    if (typeof(this.options.tokens) == 'string') 
+    if(typeof(this.options.tokens) == 'string') 
       this.options.tokens = new Array(this.options.tokens);
 
     this.observer = null;
@@ -94,7 +101,7 @@ Autocompleter.Base.prototype = {
   },
   
   fixIEOverlapping: function() {
-    Position.clone(this.update, this.iefix);
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
     this.iefix.style.zIndex = 1;
     this.update.style.zIndex = 2;
     Element.show(this.iefix);
@@ -202,11 +209,13 @@ Autocompleter.Base.prototype = {
   markPrevious: function() {
     if(this.index > 0) this.index--
       else this.index = this.entryCount-1;
+    this.getEntry(this.index).scrollIntoView(true);
   },
   
   markNext: function() {
     if(this.index < this.entryCount-1) this.index++
       else this.index = 0;
+    this.getEntry(this.index).scrollIntoView(false);
   },
   
   getEntry: function(index) {
@@ -254,11 +263,11 @@ Autocompleter.Base.prototype = {
     if(!this.changed && this.hasFocus) {
       this.update.innerHTML = choices;
       Element.cleanWhitespace(this.update);
-      Element.cleanWhitespace(this.update.firstChild);
+      Element.cleanWhitespace(this.update.down());
 
-      if(this.update.firstChild && this.update.firstChild.childNodes) {
+      if(this.update.firstChild && this.update.down().childNodes) {
         this.entryCount = 
-          this.update.firstChild.childNodes.length;
+          this.update.down().childNodes.length;
         for (var i = 0; i < this.entryCount; i++) {
           var entry = this.getEntry(i);
           entry.autocompleteIndex = i;
@@ -269,9 +278,14 @@ Autocompleter.Base.prototype = {
       }
 
       this.stopIndicator();
-
       this.index = 0;
-      this.render();
+      
+      if(this.entryCount==1 && this.options.autoSelect) {
+        this.selectEntry();
+        this.hide();
+      } else {
+        this.render();
+      }
     }
   },
 
@@ -459,6 +473,7 @@ Ajax.InPlaceEditor.prototype = {
     this.element = $(element);
 
     this.options = Object.extend({
+      paramName: "value",
       okButton: true,
       okText: "ok",
       cancelLink: true,
@@ -531,7 +546,7 @@ Ajax.InPlaceEditor.prototype = {
     Element.hide(this.element);
     this.createForm();
     this.element.parentNode.insertBefore(this.form, this.element);
-    Field.scrollFreeActivate(this.editField);
+    if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
     // stop the event to avoid a page refresh in Safari
     if (evt) {
       Event.stop(evt);
@@ -590,7 +605,7 @@ Ajax.InPlaceEditor.prototype = {
       var textField = document.createElement("input");
       textField.obj = this;
       textField.type = "text";
-      textField.name = "value";
+      textField.name = this.options.paramName;
       textField.value = text;
       textField.style.backgroundColor = this.options.highlightcolor;
       textField.className = 'editor_field';
@@ -603,7 +618,7 @@ Ajax.InPlaceEditor.prototype = {
       this.options.textarea = true;
       var textArea = document.createElement("textarea");
       textArea.obj = this;
-      textArea.name = "value";
+      textArea.name = this.options.paramName;
       textArea.value = this.convertHTMLLineBreaks(text);
       textArea.rows = this.options.rows;
       textArea.cols = this.options.cols || 40;
@@ -636,6 +651,7 @@ Ajax.InPlaceEditor.prototype = {
     Element.removeClassName(this.form, this.options.loadingClassName);
     this.editField.disabled = false;
     this.editField.value = transport.responseText.stripTags();
+    Field.scrollFreeActivate(this.editField);
   },
   onclickCancel: function() {
     this.onComplete();
@@ -772,6 +788,8 @@ Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
       collection.each(function(e,i) {
         optionTag = document.createElement("option");
         optionTag.value = (e instanceof Array) ? e[0] : e;
+        if((typeof this.options.value == 'undefined') && 
+          ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
         if(this.options.value==optionTag.value) optionTag.selected = true;
         optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
         selectTag.appendChild(optionTag);
index a01b7be2077981531a10aad90173c0d774b7a819..c71ddb82746d45a97317a84ee50341cef87fb2c5 100755 (executable)
@@ -1,9 +1,11 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//           (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
 // 
-// See scriptaculous.js for full license.
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
 
-/*--------------------------------------------------------------------------*/
+if(typeof Effect == 'undefined')
+  throw("dragdrop.js requires including script.aculo.us' effects.js library");
 
 var Droppables = {
   drops: [],
@@ -145,8 +147,16 @@ var Draggables = {
   },
   
   activate: function(draggable) {
-    window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
-    this.activeDraggable = draggable;
+    if(draggable.options.delay) { 
+      this._timeout = setTimeout(function() { 
+        Draggables._timeout = null; 
+        window.focus(); 
+        Draggables.activeDraggable = draggable; 
+      }.bind(this), draggable.options.delay); 
+    } else {
+      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+      this.activeDraggable = draggable;
+    }
   },
   
   deactivate: function() {
@@ -160,10 +170,15 @@ var Draggables = {
     // the same coordinates, prevent needless redrawing (moz bug?)
     if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
     this._lastPointer = pointer;
+    
     this.activeDraggable.updateDrag(event, pointer);
   },
   
   endDrag: function(event) {
+    if(this._timeout) { 
+      clearTimeout(this._timeout); 
+      this._timeout = null; 
+    }
     if(!this.activeDraggable) return;
     this._lastPointer = null;
     this.activeDraggable.endDrag(event);
@@ -190,6 +205,7 @@ var Draggables = {
       this.observers.each( function(o) {
         if(o[eventName]) o[eventName](eventName, draggable, event);
       });
+    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
   },
   
   _cacheObserverCallbacks: function() {
@@ -204,39 +220,59 @@ var Draggables = {
 /*--------------------------------------------------------------------------*/
 
 var Draggable = Class.create();
+Draggable._dragging    = {};
+
 Draggable.prototype = {
   initialize: function(element) {
-    var options = Object.extend({
+    var defaults = {
       handle: false,
-      starteffect: function(element) { 
-        new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); 
-      },
       reverteffect: function(element, top_offset, left_offset) {
         var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
-        element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur});
+        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+          queue: {scope:'_draggable', position:'end'}
+        });
       },
-      endeffect: function(element) { 
-        new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); 
+      endeffect: function(element) {
+        var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 
+          queue: {scope:'_draggable', position:'end'},
+          afterFinish: function(){ 
+            Draggable._dragging[element] = false 
+          }
+        }); 
       },
       zindex: 1000,
       revert: false,
       scroll: false,
       scrollSensitivity: 20,
       scrollSpeed: 15,
-      snap: false   // false, or xy or [x,y] or function(x,y){ return [x,y] }
-    }, arguments[1] || {});
+      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
+      delay: 0
+    };
+    
+    if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
+      Object.extend(defaults, {
+        starteffect: function(element) {
+          element._opacity = Element.getOpacity(element);
+          Draggable._dragging[element] = true;
+          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 
+        }
+      });
+    
+    var options = Object.extend(defaults, arguments[1] || {});
 
     this.element = $(element);
     
-    if(options.handle && (typeof options.handle == 'string')) {
-      var h = Element.childrenWithClassName(this.element, options.handle, true);
-      if(h.length>0) this.handle = h[0];
-    }
+    if(options.handle && (typeof options.handle == 'string'))
+      this.handle = this.element.down('.'+options.handle, 0);
+    
     if(!this.handle) this.handle = $(options.handle);
     if(!this.handle) this.handle = this.element;
     
-    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML)
+    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
       options.scroll = $(options.scroll);
+      this._isScrollChild = Element.childOf(this.element, options.scroll);
+    }
 
     Element.makePositioned(this.element); // fix IE    
 
@@ -262,6 +298,8 @@ Draggable.prototype = {
   },
   
   initDrag: function(event) {
+    if(typeof Draggable._dragging[this.element] != 'undefined' &&
+      Draggable._dragging[this.element]) return;
     if(Event.isLeftClick(event)) {    
       // abort on form elements, fixes a Firefox issue
       var src = Event.element(event);
@@ -272,11 +310,6 @@ Draggable.prototype = {
         src.tagName=='BUTTON' ||
         src.tagName=='TEXTAREA')) return;
         
-      if(this.element._revert) {
-        this.element._revert.cancel();
-        this.element._revert = null;
-      }
-      
       var pointer = [Event.pointerX(event), Event.pointerY(event)];
       var pos     = Position.cumulativeOffset(this.element);
       this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
@@ -312,6 +345,7 @@ Draggable.prototype = {
     }
     
     Draggables.notify('onStart', this, event);
+        
     if(this.options.starteffect) this.options.starteffect(this.element);
   },
   
@@ -320,6 +354,7 @@ Draggable.prototype = {
     Position.prepare();
     Droppables.show(pointer, this.element);
     Draggables.notify('onDrag', this, event);
+    
     this.draw(pointer);
     if(this.options.change) this.options.change(this);
     
@@ -331,8 +366,8 @@ Draggable.prototype = {
         with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
       } else {
         p = Position.page(this.options.scroll);
-        p[0] += this.options.scroll.scrollLeft;
-        p[1] += this.options.scroll.scrollTop;
+        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
+        p[1] += this.options.scroll.scrollTop + Position.deltaY;
         p.push(p[0]+this.options.scroll.offsetWidth);
         p.push(p[1]+this.options.scroll.offsetHeight);
       }
@@ -378,7 +413,7 @@ Draggable.prototype = {
 
     if(this.options.endeffect) 
       this.options.endeffect(this.element);
-
+      
     Draggables.deactivate(this);
     Droppables.reset();
   },
@@ -398,10 +433,15 @@ Draggable.prototype = {
   
   draw: function(point) {
     var pos = Position.cumulativeOffset(this.element);
+    if(this.options.ghosting) {
+      var r   = Position.realOffset(this.element);
+      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
+    }
+    
     var d = this.currentDelta();
     pos[0] -= d[0]; pos[1] -= d[1];
     
-    if(this.options.scroll && (this.options.scroll != window)) {
+    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
       pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
       pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
     }
@@ -412,7 +452,7 @@ Draggable.prototype = {
     
     if(this.options.snap) {
       if(typeof this.options.snap == 'function') {
-        p = this.options.snap(p[0],p[1]);
+        p = this.options.snap(p[0],p[1],this);
       } else {
       if(this.options.snap instanceof Array) {
         p = p.map( function(v, i) {
@@ -428,6 +468,7 @@ Draggable.prototype = {
       style.left = p[0] + "px";
     if((!this.options.constraint) || (this.options.constraint=='vertical'))
       style.top  = p[1] + "px";
+    
     if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
   },
   
@@ -440,6 +481,7 @@ Draggable.prototype = {
   },
   
   startScrolling: function(speed) {
+    if(!(speed[0] || speed[1])) return;
     this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
     this.lastScrolled = new Date();
     this.scrollInterval = setInterval(this.scroll.bind(this), 10);
@@ -464,14 +506,16 @@ Draggable.prototype = {
     Position.prepare();
     Droppables.show(Draggables._lastPointer, this.element);
     Draggables.notify('onDrag', this);
-    Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
-    Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
-    Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
-    if (Draggables._lastScrollPointer[0] < 0)
-      Draggables._lastScrollPointer[0] = 0;
-    if (Draggables._lastScrollPointer[1] < 0)
-      Draggables._lastScrollPointer[1] = 0;
-    this.draw(Draggables._lastScrollPointer);
+    if (this._isScrollChild) {
+      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+      if (Draggables._lastScrollPointer[0] < 0)
+        Draggables._lastScrollPointer[0] = 0;
+      if (Draggables._lastScrollPointer[1] < 0)
+        Draggables._lastScrollPointer[1] = 0;
+      this.draw(Draggables._lastScrollPointer);
+    }
     
     if(this.options.change) this.options.change(this);
   },
@@ -523,6 +567,8 @@ SortableObserver.prototype = {
 }
 
 var Sortable = {
+  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+  
   sortables: {},
   
   _findRootElement: function(element) {
@@ -563,12 +609,13 @@ var Sortable = {
       containment: element,    // also takes array of elements (or id's); or false
       handle:      false,      // or a CSS class
       only:        false,
+      delay:       0,
       hoverclass:  null,
       ghosting:    false,
       scroll:      false,
       scrollSensitivity: 20,
       scrollSpeed: 15,
-      format:      /^[^_]*_(.*)$/,
+      format:      this.SERIALIZE_RULE,
       onChange:    Prototype.emptyFunction,
       onUpdate:    Prototype.emptyFunction
     }, arguments[1] || {});
@@ -582,6 +629,7 @@ var Sortable = {
       scroll:      options.scroll,
       scrollSpeed: options.scrollSpeed,
       scrollSensitivity: options.scrollSensitivity,
+      delay:       options.delay,
       ghosting:    options.ghosting,
       constraint:  options.constraint,
       handle:      options.handle };
@@ -610,7 +658,6 @@ var Sortable = {
       tree:        options.tree,
       hoverclass:  options.hoverclass,
       onHover:     Sortable.onHover
-      //greedy:      !options.dropOnEmpty
     }
     
     var options_for_tree = {
@@ -635,7 +682,7 @@ var Sortable = {
     (this.findElements(element, options) || []).each( function(e) {
       // handles are per-draggable
       var handle = options.handle ? 
-        Element.childrenWithClassName(e, options.handle)[0] : e;    
+        $(e).down('.'+options.handle,0) : e;    
       options.draggables.push(
         new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
       Droppables.add(e, options_for_droppable);
@@ -706,7 +753,7 @@ var Sortable = {
     if(!Element.isParent(dropon, element)) {
       var index;
       
-      var children = Sortable.findElements(dropon, {tag: droponOptions.tag});
+      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
       var child = null;
             
       if(children) {
@@ -733,7 +780,7 @@ var Sortable = {
   },
 
   unmark: function() {
-    if(Sortable._marker) Element.hide(Sortable._marker);
+    if(Sortable._marker) Sortable._marker.hide();
   },
 
   mark: function(dropon, position) {
@@ -742,23 +789,21 @@ var Sortable = {
     if(sortable && !sortable.ghosting) return; 
 
     if(!Sortable._marker) {
-      Sortable._marker = $('dropmarker') || document.createElement('DIV');
-      Element.hide(Sortable._marker);
-      Element.addClassName(Sortable._marker, 'dropmarker');
-      Sortable._marker.style.position = 'absolute';
+      Sortable._marker = 
+        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
+          hide().addClassName('dropmarker').setStyle({position:'absolute'});
       document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
     }    
     var offsets = Position.cumulativeOffset(dropon);
-    Sortable._marker.style.left = offsets[0] + 'px';
-    Sortable._marker.style.top = offsets[1] + 'px';
+    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
     
     if(position=='after')
       if(sortable.overlap == 'horizontal') 
-        Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
+        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
       else
-        Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
+        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
     
-    Element.show(Sortable._marker);
+    Sortable._marker.show();
   },
   
   _tree: function(element, options, parent) {
@@ -773,9 +818,9 @@ var Sortable = {
         id: encodeURIComponent(match ? match[1] : null),
         element: element,
         parent: parent,
-        children: new Array,
+        children: [],
         position: parent.children.length,
-        container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
+        container: $(children[i]).down(options.treeTag)
       }
       
       /* Get the element containing the children and recurse over it */
@@ -788,17 +833,6 @@ var Sortable = {
     return parent; 
   },
 
-  /* Finds the first element of the given tag type within a parent element.
-    Used for finding the first LI[ST] within a L[IST]I[TEM].*/
-  _findChildrenElement: function (element, containerTag) {
-    if (element && element.hasChildNodes)
-      for (var i = 0; i < element.childNodes.length; ++i)
-        if (element.childNodes[i].tagName == containerTag)
-          return element.childNodes[i];
-  
-    return null;
-  },
-
   tree: function(element) {
     element = $(element);
     var sortableOptions = this.options(element);
@@ -813,12 +847,12 @@ var Sortable = {
     var root = {
       id: null,
       parent: null,
-      children: new Array,
+      children: [],
       container: element,
       position: 0
     }
     
-    return Sortable._tree (element, options, root);
+    return Sortable._tree(element, options, root);
   },
 
   /* Construct a [i] index for a particular node */
@@ -867,7 +901,7 @@ var Sortable = {
     
     if (options.tree) {
       return Sortable.tree(element, arguments[1]).children.map( function (item) {
-        return [name + Sortable._constructIndex(item) + "=" + 
+        return [name + Sortable._constructIndex(item) + "[id]=" + 
                 encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
       }).flatten().join('&');
     } else {
@@ -878,12 +912,10 @@ var Sortable = {
   }
 }
 
-/* Returns true if child is contained within element */
+// Returns true if child is contained within element
 Element.isParent = function(child, element) {
   if (!child.parentNode || child == element) return false;
-
   if (child.parentNode == element) return true;
-
   return Element.isParent(child.parentNode, element);
 }
 
@@ -906,8 +938,5 @@ Element.findChildren = function(element, only, recursive, tagName) {
 }
 
 Element.offsetSize = function (element, type) {
-  if (type == 'vertical' || type == 'height')
-    return element.offsetHeight;
-  else
-    return element.offsetWidth;
-}
\ No newline at end of file
+  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
+}
index 927400502dd64a21198003e419b83d38c4ee6f80..3b02eda2b29ffd4d55fff72caa72d91b18a92551 100755 (executable)
@@ -1,15 +1,16 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
 // Contributors:
 //  Justin Palmer (http://encytemedia.com/)
 //  Mark Pilgrim (http://diveintomark.org/)
 //  Martin Bialasinki
 // 
-// See scriptaculous.js for full license.  
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/ 
 
 // converts rgb() and #xxx to #xxxxxx format,  
 // returns self (or first argument) if not convertable  
 String.prototype.parseColor = function() {  
-  var color = '#';  
+  var color = '#';
   if(this.slice(0,4) == 'rgb(') {  
     var cols = this.slice(4,this.length-1).split(',');  
     var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
@@ -41,15 +42,17 @@ Element.collectTextNodesIgnoreClass = function(element, className) {
 
 Element.setContentZoom = function(element, percent) {
   element = $(element);  
-  Element.setStyle(element, {fontSize: (percent/100) + 'em'});   
+  element.setStyle({fontSize: (percent/100) + 'em'});   
   if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+  return element;
 }
 
-Element.getOpacity = function(element){  
+Element.getOpacity = function(element){
+  element = $(element);
   var opacity;
-  if (opacity = Element.getStyle(element, 'opacity'))  
+  if (opacity = element.getStyle('opacity'))  
     return parseFloat(opacity);  
-  if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))  
+  if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))  
     if(opacity[1]) return parseFloat(opacity[1]) / 100;  
   return 1.0;  
 }
@@ -57,34 +60,26 @@ Element.getOpacity = function(element){
 Element.setOpacity = function(element, value){  
   element= $(element);  
   if (value == 1){
-    Element.setStyle(element, { opacity: 
+    element.setStyle({ opacity: 
       (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
-      0.999999 : null });
-    if(/MSIE/.test(navigator.userAgent))  
-      Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
+      0.999999 : 1.0 });
+    if(/MSIE/.test(navigator.userAgent) && !window.opera)  
+      element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
   } else {  
     if(value < 0.00001) value = 0;  
-    Element.setStyle(element, {opacity: value});
-    if(/MSIE/.test(navigator.userAgent))  
-     Element.setStyle(element, 
-       { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
-                 'alpha(opacity='+value*100+')' });  
+    element.setStyle({opacity: value});
+    if(/MSIE/.test(navigator.userAgent) && !window.opera)  
+      element.setStyle(
+        { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+            'alpha(opacity='+value*100+')' });  
   }
+  return element;
 }  
  
 Element.getInlineOpacity = function(element){  
   return $(element).style.opacity || '';
 }  
 
-Element.childrenWithClassName = function(element, className, findFirst) {
-  var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
-  var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { 
-    return (c.className && c.className.match(classNameRegExp));
-  });
-  if(!results) results = [];
-  return results;
-}
-
 Element.forceRerendering = function(element) {
   try {
     element = $(element);
@@ -104,9 +99,17 @@ Array.prototype.call = function() {
 /*--------------------------------------------------------------------------*/
 
 var Effect = {
+  _elementDoesNotExistError: {
+    name: 'ElementDoesNotExistError',
+    message: 'The specified DOM element does not exist, but is required for this effect to operate'
+  },
   tagifyText: function(element) {
+    if(typeof Builder == 'undefined')
+      throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+      
     var tagifyStyle = 'position:relative';
-    if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
+    if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+    
     element = $(element);
     $A(element.childNodes).each( function(child) {
       if(child.nodeType==3) {
@@ -159,33 +162,35 @@ var Effect2 = Effect; // deprecated
 
 /* ------------- transitions ------------- */
 
-Effect.Transitions = {}
-
-Effect.Transitions.linear = function(pos) {
-  return pos;
-}
-Effect.Transitions.sinoidal = function(pos) {
-  return (-Math.cos(pos*Math.PI)/2) + 0.5;
-}
-Effect.Transitions.reverse  = function(pos) {
-  return 1-pos;
-}
-Effect.Transitions.flicker = function(pos) {
-  return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-}
-Effect.Transitions.wobble = function(pos) {
-  return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-}
-Effect.Transitions.pulse = function(pos) {
-  return (Math.floor(pos*10) % 2 == 0 ? 
-    (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
-}
-Effect.Transitions.none = function(pos) {
-  return 0;
-}
-Effect.Transitions.full = function(pos) {
-  return 1;
-}
+Effect.Transitions = {
+  linear: Prototype.K,
+  sinoidal: function(pos) {
+    return (-Math.cos(pos*Math.PI)/2) + 0.5;
+  },
+  reverse: function(pos) {
+    return 1-pos;
+  },
+  flicker: function(pos) {
+    return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+  },
+  wobble: function(pos) {
+    return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+  },
+  pulse: function(pos, pulses) { 
+    pulses = pulses || 5; 
+    return (
+      Math.round((pos % (1/pulses)) * pulses) == 0 ? 
+            ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 
+        1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+      );
+  },
+  none: function(pos) {
+    return 0;
+  },
+  full: function(pos) {
+    return 1;
+  }
+};
 
 /* ------------- core effects ------------- */
 
@@ -212,6 +217,9 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
             e.finishOn += effect.finishOn;
           });
         break;
+      case 'with-last':
+        timestamp = this.effects.pluck('startOn').max() || timestamp;
+        break;
       case 'end':
         // start effect after last queued effect has finished
         timestamp = this.effects.pluck('finishOn').max() || timestamp;
@@ -348,12 +356,24 @@ Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
   }
 });
 
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+  initialize: function() {
+    var options = Object.extend({
+      duration: 0
+    }, arguments[0] || {});
+    this.start(options);
+  },
+  update: Prototype.emptyFunction
+});
+
 Effect.Opacity = Class.create();
 Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
   initialize: function(element) {
     this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
     // make this work on IE on elements without 'layout'
-    if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
+    if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
       this.element.setStyle({zoom: 1});
     var options = Object.extend({
       from: this.element.getOpacity() || 0.0,
@@ -370,6 +390,7 @@ Effect.Move = Class.create();
 Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
   initialize: function(element) {
     this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
     var options = Object.extend({
       x:    0,
       y:    0,
@@ -393,8 +414,8 @@ Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
   },
   update: function(position) {
     this.element.setStyle({
-      left: this.options.x  * position + this.originalLeft + 'px',
-      top:  this.options.y  * position + this.originalTop  + 'px'
+      left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
+      top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
     });
   }
 });
@@ -408,7 +429,8 @@ Effect.MoveBy = function(element, toTop, toLeft) {
 Effect.Scale = Class.create();
 Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
   initialize: function(element, percent) {
-    this.element = $(element)
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
     var options = Object.extend({
       scaleX: true,
       scaleY: true,
@@ -433,7 +455,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
     this.originalLeft = this.element.offsetLeft;
     
     var fontSize = this.element.getStyle('font-size') || '100%';
-    ['em','px','%'].each( function(fontSizeType) {
+    ['em','px','%','pt'].each( function(fontSizeType) {
       if(fontSize.indexOf(fontSizeType)>0) {
         this.fontSize     = parseFloat(fontSize);
         this.fontSizeType = fontSizeType;
@@ -458,12 +480,12 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
     this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
   },
   finish: function(position) {
-    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+    if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
   },
   setDimensions: function(height, width) {
     var d = {};
-    if(this.options.scaleX) d.width = width + 'px';
-    if(this.options.scaleY) d.height = height + 'px';
+    if(this.options.scaleX) d.width = Math.round(width) + 'px';
+    if(this.options.scaleY) d.height = Math.round(height) + 'px';
     if(this.options.scaleFromCenter) {
       var topd  = (height - this.dims[0])/2;
       var leftd = (width  - this.dims[1])/2;
@@ -483,6 +505,7 @@ Effect.Highlight = Class.create();
 Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
   initialize: function(element) {
     this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
     var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
     this.start(options);
   },
@@ -547,8 +570,7 @@ Effect.Fade = function(element) {
   to:   0.0,
   afterFinishInternal: function(effect) { 
     if(effect.options.to!=0) return;
-    effect.element.hide();
-    effect.element.setStyle({opacity: oldOpacity}); 
+    effect.element.hide().setStyle({opacity: oldOpacity}); 
   }}, arguments[1] || {});
   return new Effect.Opacity(element,options);
 }
@@ -563,25 +585,31 @@ Effect.Appear = function(element) {
     effect.element.forceRerendering();
   },
   beforeSetup: function(effect) {
-    effect.element.setOpacity(effect.options.from);
-    effect.element.show(); 
+    effect.element.setOpacity(effect.options.from).show(); 
   }}, arguments[1] || {});
   return new Effect.Opacity(element,options);
 }
 
 Effect.Puff = function(element) {
   element = $(element);
-  var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
+  var oldStyle = { 
+    opacity: element.getInlineOpacity(), 
+    position: element.getStyle('position'),
+    top:  element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height
+  };
   return new Effect.Parallel(
    [ new Effect.Scale(element, 200, 
       { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
      new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
      Object.extend({ duration: 1.0, 
       beforeSetupInternal: function(effect) {
-        effect.effects[0].element.setStyle({position: 'absolute'}); },
+        Position.absolutize(effect.effects[0].element)
+      },
       afterFinishInternal: function(effect) {
-         effect.effects[0].element.hide();
-         effect.effects[0].element.setStyle(oldStyle); }
+         effect.effects[0].element.hide().setStyle(oldStyle); }
      }, arguments[1] || {})
    );
 }
@@ -589,13 +617,12 @@ Effect.Puff = function(element) {
 Effect.BlindUp = function(element) {
   element = $(element);
   element.makeClipping();
-  return new Effect.Scale(element, 0, 
+  return new Effect.Scale(element, 0,
     Object.extend({ scaleContent: false, 
       scaleX: false, 
       restoreAfterFinish: true,
       afterFinishInternal: function(effect) {
-        effect.element.hide();
-        effect.element.undoClipping();
+        effect.element.hide().undoClipping();
       } 
     }, arguments[1] || {})
   );
@@ -604,28 +631,25 @@ Effect.BlindUp = function(element) {
 Effect.BlindDown = function(element) {
   element = $(element);
   var elementDimensions = element.getDimensions();
-  return new Effect.Scale(element, 100, 
-    Object.extend({ scaleContent: false, 
-      scaleX: false,
-      scaleFrom: 0,
-      scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
-      restoreAfterFinish: true,
-      afterSetup: function(effect) {
-        effect.element.makeClipping();
-        effect.element.setStyle({height: '0px'});
-        effect.element.show(); 
-      },  
-      afterFinishInternal: function(effect) {
-        effect.element.undoClipping();
-      }
-    }, arguments[1] || {})
-  );
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false,
+    scaleFrom: 0,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping();
+    }
+  }, arguments[1] || {}));
 }
 
 Effect.SwitchOff = function(element) {
   element = $(element);
   var oldOpacity = element.getInlineOpacity();
-  return new Effect.Appear(element, 
+  return new Effect.Appear(element, Object.extend({
     duration: 0.4,
     from: 0,
     transition: Effect.Transitions.flicker,
@@ -634,18 +658,14 @@ Effect.SwitchOff = function(element) {
         duration: 0.3, scaleFromCenter: true,
         scaleX: false, scaleContent: false, restoreAfterFinish: true,
         beforeSetup: function(effect) { 
-          effect.element.makePositioned();
-          effect.element.makeClipping();
+          effect.element.makePositioned().makeClipping();
         },
         afterFinishInternal: function(effect) {
-          effect.element.hide();
-          effect.element.undoClipping();
-          effect.element.undoPositioned();
-          effect.element.setStyle({opacity: oldOpacity});
+          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
         }
       })
     }
-  });
+  }, arguments[1] || {}));
 }
 
 Effect.DropOut = function(element) {
@@ -663,9 +683,7 @@ Effect.DropOut = function(element) {
           effect.effects[0].element.makePositioned(); 
         },
         afterFinishInternal: function(effect) {
-          effect.effects[0].element.hide();
-          effect.effects[0].element.undoPositioned();
-          effect.effects[0].element.setStyle(oldStyle);
+          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
         } 
       }, arguments[1] || {}));
 }
@@ -687,54 +705,42 @@ Effect.Shake = function(element) {
       { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
     new Effect.Move(effect.element,
       { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
-        effect.element.undoPositioned();
-        effect.element.setStyle(oldStyle);
+        effect.element.undoPositioned().setStyle(oldStyle);
   }}) }}) }}) }}) }}) }});
 }
 
 Effect.SlideDown = function(element) {
-  element = $(element);
-  element.cleanWhitespace();
+  element = $(element).cleanWhitespace();
   // SlideDown need to have the content of the element wrapped in a container element with fixed height!
-  var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+  var oldInnerBottom = element.down().getStyle('bottom');
   var elementDimensions = element.getDimensions();
   return new Effect.Scale(element, 100, Object.extend({ 
     scaleContent: false, 
     scaleX: false, 
-    scaleFrom: 0,
+    scaleFrom: window.opera ? 0 : 1,
     scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
     restoreAfterFinish: true,
     afterSetup: function(effect) {
       effect.element.makePositioned();
-      effect.element.firstChild.makePositioned();
+      effect.element.down().makePositioned();
       if(window.opera) effect.element.setStyle({top: ''});
-      effect.element.makeClipping();
-      effect.element.setStyle({height: '0px'});
-      effect.element.show(); },
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },
     afterUpdateInternal: function(effect) {
-      effect.element.firstChild.setStyle({bottom:
+      effect.element.down().setStyle({bottom:
         (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
     },
     afterFinishInternal: function(effect) {
-      effect.element.undoClipping(); 
-      // IE will crash if child is undoPositioned first
-      if(/MSIE/.test(navigator.userAgent)){
-        effect.element.undoPositioned();
-        effect.element.firstChild.undoPositioned();
-      }else{
-        effect.element.firstChild.undoPositioned();
-        effect.element.undoPositioned();
-      }
-      effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
+      effect.element.undoClipping().undoPositioned();
+      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
     }, arguments[1] || {})
   );
 }
-  
+
 Effect.SlideUp = function(element) {
-  element = $(element);
-  element.cleanWhitespace();
-  var oldInnerBottom = $(element.firstChild).getStyle('bottom');
-  return new Effect.Scale(element, 0, 
+  element = $(element).cleanWhitespace();
+  var oldInnerBottom = element.down().getStyle('bottom');
+  return new Effect.Scale(element, window.opera ? 0 : 1,
    Object.extend({ scaleContent: false, 
     scaleX: false, 
     scaleMode: 'box',
@@ -742,32 +748,32 @@ Effect.SlideUp = function(element) {
     restoreAfterFinish: true,
     beforeStartInternal: function(effect) {
       effect.element.makePositioned();
-      effect.element.firstChild.makePositioned();
+      effect.element.down().makePositioned();
       if(window.opera) effect.element.setStyle({top: ''});
-      effect.element.makeClipping();
-      effect.element.show(); },  
+      effect.element.makeClipping().show();
+    },  
     afterUpdateInternal: function(effect) {
-      effect.element.firstChild.setStyle({bottom:
-        (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' });
+    },
     afterFinishInternal: function(effect) {
-      effect.element.hide();
-      effect.element.undoClipping();
-      effect.element.firstChild.undoPositioned();
-      effect.element.undoPositioned();
-      effect.element.setStyle({bottom: oldInnerBottom}); }
+      effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+      effect.element.down().undoPositioned();
+    }
    }, arguments[1] || {})
   );
 }
 
 // Bug in opera makes the TD containing this element expand for a instance after finish 
 Effect.Squish = function(element) {
-  return new Effect.Scale(element, window.opera ? 1 : 0, 
-    { restoreAfterFinish: true,
-      beforeSetup: function(effect) {
-        effect.element.makeClipping(effect.element); },  
-      afterFinishInternal: function(effect) {
-        effect.element.hide(effect.element); 
-        effect.element.undoClipping(effect.element); }
+  return new Effect.Scale(element, window.opera ? 1 : 0, { 
+    restoreAfterFinish: true,
+    beforeSetup: function(effect) {
+      effect.element.makeClipping(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping(); 
+    }
   });
 }
 
@@ -823,9 +829,7 @@ Effect.Grow = function(element) {
     y: initialMoveY,
     duration: 0.01, 
     beforeSetup: function(effect) {
-      effect.element.hide();
-      effect.element.makeClipping();
-      effect.element.makePositioned();
+      effect.element.hide().makeClipping().makePositioned();
     },
     afterFinishInternal: function(effect) {
       new Effect.Parallel(
@@ -836,13 +840,10 @@ Effect.Grow = function(element) {
             sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
         ], Object.extend({
              beforeSetup: function(effect) {
-               effect.effects[0].element.setStyle({height: '0px'});
-               effect.effects[0].element.show(); 
+               effect.effects[0].element.setStyle({height: '0px'}).show(); 
              },
              afterFinishInternal: function(effect) {
-               effect.effects[0].element.undoClipping();
-               effect.effects[0].element.undoPositioned();
-               effect.effects[0].element.setStyle(oldStyle); 
+               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
              }
            }, options)
       )
@@ -896,13 +897,10 @@ Effect.Shrink = function(element) {
       new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
     ], Object.extend({            
          beforeStartInternal: function(effect) {
-           effect.effects[0].element.makePositioned();
-           effect.effects[0].element.makeClipping(); },
+           effect.effects[0].element.makePositioned().makeClipping(); 
+         },
          afterFinishInternal: function(effect) {
-           effect.effects[0].element.hide();
-           effect.effects[0].element.undoClipping();
-           effect.effects[0].element.undoPositioned();
-           effect.effects[0].element.setStyle(oldStyle); }
+           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
        }, options)
   );
 }
@@ -912,10 +910,10 @@ Effect.Pulsate = function(element) {
   var options    = arguments[1] || {};
   var oldOpacity = element.getInlineOpacity();
   var transition = options.transition || Effect.Transitions.sinoidal;
-  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
+  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
   reverser.bind(transition);
   return new Effect.Opacity(element, 
-    Object.extend(Object.extend({  duration: 3.0, from: 0,
+    Object.extend(Object.extend({  duration: 2.0, from: 0,
       afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
     }, options), {transition: reverser}));
 }
@@ -927,7 +925,7 @@ Effect.Fold = function(element) {
     left: element.style.left,
     width: element.style.width,
     height: element.style.height };
-  Element.makeClipping(element);
+  element.makeClipping();
   return new Effect.Scale(element, 5, Object.extend({   
     scaleContent: false,
     scaleX: false,
@@ -936,15 +934,147 @@ Effect.Fold = function(element) {
       scaleContent: false, 
       scaleY: false,
       afterFinishInternal: function(effect) {
-        effect.element.hide();
-        effect.element.undoClipping(); 
-        effect.element.setStyle(oldStyle);
+        effect.element.hide().undoClipping().setStyle(oldStyle);
       } });
   }}, arguments[1] || {}));
 };
 
+Effect.Morph = Class.create();
+Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      style: ''
+    }, arguments[1] || {});
+    this.start(options);
+  },
+  setup: function(){
+    function parseColor(color){
+      if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+      color = color.parseColor();
+      return $R(0,2).map(function(i){
+        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
+      });
+    }
+    this.transforms = this.options.style.parseStyle().map(function(property){
+      var originalValue = this.element.getStyle(property[0]);
+      return $H({ 
+        style: property[0], 
+        originalValue: property[1].unit=='color' ? 
+          parseColor(originalValue) : parseFloat(originalValue || 0), 
+        targetValue: property[1].unit=='color' ? 
+          parseColor(property[1].value) : property[1].value,
+        unit: property[1].unit
+      });
+    }.bind(this)).reject(function(transform){
+      return (
+        (transform.originalValue == transform.targetValue) ||
+        (
+          transform.unit != 'color' &&
+          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+        )
+      )
+    });
+  },
+  update: function(position) {
+    var style = $H(), value = null;
+    this.transforms.each(function(transform){
+      value = transform.unit=='color' ?
+        $R(0,2).inject('#',function(m,v,i){
+          return m+(Math.round(transform.originalValue[i]+
+            (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) : 
+        transform.originalValue + Math.round(
+          ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
+      style[transform.style] = value;
+    });
+    this.element.setStyle(style);
+  }
+});
+
+Effect.Transform = Class.create();
+Object.extend(Effect.Transform.prototype, {
+  initialize: function(tracks){
+    this.tracks  = [];
+    this.options = arguments[1] || {};
+    this.addTracks(tracks);
+  },
+  addTracks: function(tracks){
+    tracks.each(function(track){
+      var data = $H(track).values().first();
+      this.tracks.push($H({
+        ids:     $H(track).keys().first(),
+        effect:  Effect.Morph,
+        options: { style: data }
+      }));
+    }.bind(this));
+    return this;
+  },
+  play: function(){
+    return new Effect.Parallel(
+      this.tracks.map(function(track){
+        var elements = [$(track.ids) || $$(track.ids)].flatten();
+        return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+      }).flatten(),
+      this.options
+    );
+  }
+});
+
+Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage', 
+  'backgroundPosition', 'backgroundRepeat', 'borderBottomColor', 'borderBottomStyle', 
+  'borderBottomWidth', 'borderCollapse', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth',
+  'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderSpacing', 'borderTopColor',
+  'borderTopStyle', 'borderTopWidth', 'bottom', 'captionSide', 'clear', 'clip', 'color', 'content',
+  'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction',
+  'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
+  'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight',
+  'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight',
+  'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity',
+  'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY',
+  'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore',
+  'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes',
+  'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress',
+  'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top',
+  'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows',
+  'width', 'wordSpacing', 'zIndex'];
+  
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.prototype.parseStyle = function(){
+  var element = Element.extend(document.createElement('div'));
+  element.innerHTML = '<div style="' + this + '"></div>';
+  var style = element.down().style, styleRules = $H();
+  
+  Element.CSS_PROPERTIES.each(function(property){
+   if(style[property]) styleRules[property] = style[property]; 
+  });
+  
+  var result = $H();
+  
+  styleRules.each(function(pair){
+    var property = pair[0], value = pair[1], unit = null;
+    
+    if(value.parseColor('#zzzzzz') != '#zzzzzz') {
+      value = value.parseColor();
+      unit  = 'color';
+    } else if(Element.CSS_LENGTH.test(value)) 
+      var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
+          value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
+    
+    result[property.underscore().dasherize()] = $H({ value:value, unit:unit });
+  }.bind(this));
+  
+  return result;
+};
+
+Element.morph = function(element, style) {
+  new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
+  return element;
+};
+
 ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( 
+ 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( 
   function(f) { Element.Methods[f] = Element[f]; }
 );
 
index 0caf9cd7f0b7d902b0dada3752de348ed27c02cd..505822177b81910ba7426835e5014c1f3de374de 100755 (executable)
@@ -1,5 +1,5 @@
-/*  Prototype JavaScript framework, version 1.5.0_rc0
- *  (c) 2005 Sam Stephenson <sam@conio.net>
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
  *
  *  Prototype is freely distributable under the terms of an MIT-style license.
  *  For details, see the Prototype web site: http://prototype.conio.net/
@@ -7,11 +7,14 @@
 /*--------------------------------------------------------------------------*/
 
 var Prototype = {
-  Version: '1.5.0_rc0',
-  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
 
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
   emptyFunction: function() {},
-  K: function(x) {return x}
+  K: function(x) { return x }
 }
 
 var Class = {
@@ -31,16 +34,36 @@ Object.extend = function(destination, source) {
   return destination;
 }
 
-Object.inspect = function(object) {
-  try {
-    if (object == undefined) return 'undefined';
-    if (object == null) return 'null';
-    return object.inspect ? object.inspect() : object.toString();
-  } catch (e) {
-    if (e instanceof RangeError) return '...';
-    throw e;
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
   }
-}
+});
 
 Function.prototype.bind = function() {
   var __method = this, args = $A(arguments), object = args.shift();
@@ -50,9 +73,9 @@ Function.prototype.bind = function() {
 }
 
 Function.prototype.bindAsEventListener = function(object) {
-  var __method = this;
+  var __method = this, args = $A(arguments), object = args.shift();
   return function(event) {
-    return __method.call(object, event || window.event);
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
   }
 }
 
@@ -77,7 +100,7 @@ var Try = {
   these: function() {
     var returnValue;
 
-    for (var i = 0; i < arguments.length; i++) {
+    for (var i = 0, length = arguments.length; i < length; i++) {
       var lambda = arguments[i];
       try {
         returnValue = lambda();
@@ -102,20 +125,30 @@ PeriodicalExecuter.prototype = {
   },
 
   registerCallback: function() {
-    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
   },
 
   onTimerEvent: function() {
     if (!this.currentlyExecuting) {
       try {
         this.currentlyExecuting = true;
-        this.callback();
+        this.callback(this);
       } finally {
         this.currentlyExecuting = false;
       }
     }
   }
 }
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+}
+
 Object.extend(String.prototype, {
   gsub: function(pattern, replacement) {
     var result = '', source = this, match;
@@ -124,7 +157,7 @@ Object.extend(String.prototype, {
     while (source.length > 0) {
       if (match = source.match(pattern)) {
         result += source.slice(0, match.index);
-        result += (replacement(match) || '').toString();
+        result += String.interpret(replacement(match));
         source  = source.slice(match.index + match[0].length);
       } else {
         result += source, source = '';
@@ -189,15 +222,28 @@ Object.extend(String.prototype, {
   unescapeHTML: function() {
     var div = document.createElement('div');
     div.innerHTML = this.stripTags();
-    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
   },
 
-  toQueryParams: function() {
-    var pairs = this.match(/^\??(.*)$/)[1].split('&');
-    return pairs.inject({}, function(params, pairString) {
-      var pair = pairString.split('=');
-      params[pair[0]] = pair[1];
-      return params;
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
     });
   },
 
@@ -205,24 +251,43 @@ Object.extend(String.prototype, {
     return this.split('');
   },
 
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
   camelize: function() {
-    var oStringList = this.split('-');
-    if (oStringList.length == 1) return oStringList[0];
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
 
-    var camelizedString = this.indexOf('-') == 0
-      ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
-      : oStringList[0];
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
 
-    for (var i = 1, len = oStringList.length; i < len; i++) {
-      var s = oStringList[i];
-      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
-    }
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
 
-    return camelizedString;
+    return camelized;
   },
 
-  inspect: function() {
-    return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
   }
 });
 
@@ -246,7 +311,7 @@ Template.prototype = {
     return this.template.gsub(this.pattern, function(match) {
       var before = match[1];
       if (before == '\\') return match[2];
-      return before + (object[match[3]] || '').toString();
+      return before + String.interpret(object[match[3]]);
     });
   }
 }
@@ -268,6 +333,14 @@ var Enumerable = {
     } catch (e) {
       if (e != $break) throw e;
     }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
   },
 
   all: function(iterator) {
@@ -280,7 +353,7 @@ var Enumerable = {
   },
 
   any: function(iterator) {
-    var result = true;
+    var result = false;
     this.each(function(value, index) {
       if (result = !!(iterator || Prototype.K)(value, index))
         throw $break;
@@ -291,12 +364,12 @@ var Enumerable = {
   collect: function(iterator) {
     var results = [];
     this.each(function(value, index) {
-      results.push(iterator(value, index));
+      results.push((iterator || Prototype.K)(value, index));
     });
     return results;
   },
 
-  detect: function (iterator) {
+  detect: function(iterator) {
     var result;
     this.each(function(value, index) {
       if (iterator(value, index)) {
@@ -337,6 +410,14 @@ var Enumerable = {
     return found;
   },
 
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
   inject: function(memo, iterator) {
     this.each(function(value, index) {
       memo = iterator(memo, value, index);
@@ -346,7 +427,7 @@ var Enumerable = {
 
   invoke: function(method) {
     var args = $A(arguments).slice(1);
-    return this.collect(function(value) {
+    return this.map(function(value) {
       return value[method].apply(value, args);
     });
   },
@@ -398,7 +479,7 @@ var Enumerable = {
   },
 
   sortBy: function(iterator) {
-    return this.collect(function(value, index) {
+    return this.map(function(value, index) {
       return {value: value, criteria: iterator(value, index)};
     }).sort(function(left, right) {
       var a = left.criteria, b = right.criteria;
@@ -407,7 +488,7 @@ var Enumerable = {
   },
 
   toArray: function() {
-    return this.collect(Prototype.K);
+    return this.map();
   },
 
   zip: function() {
@@ -421,6 +502,10 @@ var Enumerable = {
     });
   },
 
+  size: function() {
+    return this.toArray().length;
+  },
+
   inspect: function() {
     return '#<Enumerable:' + this.toArray().inspect() + '>';
   }
@@ -439,7 +524,7 @@ var $A = Array.from = function(iterable) {
     return iterable.toArray();
   } else {
     var results = [];
-    for (var i = 0; i < iterable.length; i++)
+    for (var i = 0, length = iterable.length; i < length; i++)
       results.push(iterable[i]);
     return results;
   }
@@ -452,7 +537,7 @@ if (!Array.prototype._reverse)
 
 Object.extend(Array.prototype, {
   _each: function(iterator) {
-    for (var i = 0; i < this.length; i++)
+    for (var i = 0, length = this.length; i < length; i++)
       iterator(this[i]);
   },
 
@@ -471,7 +556,7 @@ Object.extend(Array.prototype, {
 
   compact: function() {
     return this.select(function(value) {
-      return value != undefined || value != null;
+      return value != null;
     });
   },
 
@@ -490,7 +575,7 @@ Object.extend(Array.prototype, {
   },
 
   indexOf: function(object) {
-    for (var i = 0; i < this.length; i++)
+    for (var i = 0, length = this.length; i < length; i++)
       if (this[i] == object) return i;
     return -1;
   },
@@ -499,15 +584,88 @@ Object.extend(Array.prototype, {
     return (inline !== false ? this : this.toArray())._reverse();
   },
 
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
   inspect: function() {
     return '[' + this.map(Object.inspect).join(', ') + ']';
   }
 });
-var Hash = {
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+}
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+         this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+               key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.map(encodeURIComponent).join('='));
+         });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
   _each: function(iterator) {
     for (var key in this) {
       var value = this[key];
-      if (typeof value == 'function') continue;
+      if (value && value == Hash.prototype[key]) continue;
 
       var pair = [key, value];
       pair.key = key;
@@ -525,16 +683,30 @@ var Hash = {
   },
 
   merge: function(hash) {
-    return $H(hash).inject($H(this), function(mergedHash, pair) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
       mergedHash[pair.key] = pair.value;
       return mergedHash;
     });
   },
 
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
   toQueryString: function() {
-    return this.map(function(pair) {
-      return pair.map(encodeURIComponent).join('=');
-    }).join('&');
+    return Hash.toQueryString(this);
   },
 
   inspect: function() {
@@ -542,14 +714,12 @@ var Hash = {
       return pair.map(Object.inspect).join(': ');
     }).join(', ') + '}>';
   }
-}
+});
 
 function $H(object) {
-  var hash = Object.extend({}, object || {});
-  Object.extend(hash, Enumerable);
-  Object.extend(hash, Hash);
-  return hash;
-}
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
 ObjectRange = Class.create();
 Object.extend(ObjectRange.prototype, Enumerable);
 Object.extend(ObjectRange.prototype, {
@@ -561,10 +731,10 @@ Object.extend(ObjectRange.prototype, {
 
   _each: function(iterator) {
     var value = this.start;
-    do {
+    while (this.include(value)) {
       iterator(value);
       value = value.succ();
-    } while (this.include(value));
+    }
   },
 
   include: function(value) {
@@ -599,18 +769,18 @@ Ajax.Responders = {
     this.responders._each(iterator);
   },
 
-  register: function(responderToAdd) {
-    if (!this.include(responderToAdd))
-      this.responders.push(responderToAdd);
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
   },
 
-  unregister: function(responderToRemove) {
-    this.responders = this.responders.without(responderToRemove);
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
   },
 
   dispatch: function(callback, request, transport, json) {
     this.each(function(responder) {
-      if (responder[callback] && typeof responder[callback] == 'function') {
+      if (typeof responder[callback] == 'function') {
         try {
           responder[callback].apply(responder, [request, transport, json]);
         } catch (e) {}
@@ -625,7 +795,6 @@ Ajax.Responders.register({
   onCreate: function() {
     Ajax.activeRequestCount++;
   },
-
   onComplete: function() {
     Ajax.activeRequestCount--;
   }
@@ -638,19 +807,14 @@ Ajax.Base.prototype = {
       method:       'post',
       asynchronous: true,
       contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
       parameters:   ''
     }
     Object.extend(this.options, options || {});
-  },
-
-  responseIsSuccess: function() {
-    return this.transport.status == undefined
-        || this.transport.status == 0
-        || (this.transport.status >= 200 && this.transport.status < 300);
-  },
 
-  responseIsFailure: function() {
-    return !this.responseIsSuccess();
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
   }
 }
 
@@ -659,6 +823,8 @@ Ajax.Request.Events =
   ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
 
 Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
   initialize: function(url, options) {
     this.transport = Ajax.getTransport();
     this.setOptions(options);
@@ -666,111 +832,146 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
   },
 
   request: function(url) {
-    var parameters = this.options.parameters || '';
-    if (parameters.length > 0) parameters += '&_=';
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
 
-    try {
-      this.url = url;
-      if (this.options.method == 'get' && parameters.length > 0)
-        this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
 
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
       Ajax.Responders.dispatch('onCreate', this, this.transport);
 
-      this.transport.open(this.options.method, this.url,
+      this.transport.open(this.method.toUpperCase(), this.url,
         this.options.asynchronous);
 
-      if (this.options.asynchronous) {
-        this.transport.onreadystatechange = this.onStateChange.bind(this);
-        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
-      }
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
 
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
       this.setRequestHeaders();
 
-      var body = this.options.postBody ? this.options.postBody : parameters;
-      this.transport.send(this.options.method == 'post' ? body : null);
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
 
-    } catch (e) {
-      this.dispatchException(e);
-    }
-  },
-
-  setRequestHeaders: function() {
-    var requestHeaders =
-      ['X-Requested-With', 'XMLHttpRequest',
-       'X-Prototype-Version', Prototype.Version,
-       'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+      this.transport.send(body);
 
-    if (this.options.method == 'post') {
-      requestHeaders.push('Content-type', this.options.contentType);
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
 
-      /* Force "Connection: close" for Mozilla browsers to work around
-       * a bug where XMLHttpReqeuest sends an incorrect Content-length
-       * header. See Mozilla Bugzilla #246651.
-       */
-      if (this.transport.overrideMimeType)
-        requestHeaders.push('Connection', 'close');
     }
-
-    if (this.options.requestHeaders)
-      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
-    for (var i = 0; i < requestHeaders.length; i += 2)
-      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
+    catch (e) {
+      this.dispatchException(e);
+    }
   },
 
   onStateChange: function() {
     var readyState = this.transport.readyState;
-    if (readyState != 1)
+    if (readyState > 1 && !((readyState == 4) && this._complete))
       this.respondToReadyState(this.transport.readyState);
   },
 
-  header: function(name) {
-    try {
-      return this.transport.getResponseHeader(name);
-    } catch (e) {}
-  },
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
 
-  evalJSON: function() {
-    try {
-      return eval('(' + this.header('X-JSON') + ')');
-    } catch (e) {}
-  },
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
 
-  evalResponse: function() {
-    try {
-      return eval(this.transport.responseText);
-    } catch (e) {
-      this.dispatchException(e);
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
     }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
   },
 
   respondToReadyState: function(readyState) {
-    var event = Ajax.Request.Events[readyState];
+    var state = Ajax.Request.Events[readyState];
     var transport = this.transport, json = this.evalJSON();
 
-    if (event == 'Complete') {
+    if (state == 'Complete') {
       try {
+        this._complete = true;
         (this.options['on' + this.transport.status]
-         || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
          || Prototype.emptyFunction)(transport, json);
       } catch (e) {
         this.dispatchException(e);
       }
 
-      if ((this.header('Content-type') || '').match(/^text\/javascript/i))
-        this.evalResponse();
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
     }
 
     try {
-      (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
-      Ajax.Responders.dispatch('on' + event, this, transport, json);
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
     } catch (e) {
       this.dispatchException(e);
     }
 
-    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
-    if (event == 'Complete')
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
       this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
   },
 
   dispatchException: function(exception) {
@@ -783,41 +984,37 @@ Ajax.Updater = Class.create();
 
 Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
   initialize: function(container, url, options) {
-    this.containers = {
-      success: container.success ? $(container.success) : $(container),
-      failure: container.failure ? $(container.failure) :
-        (container.success ? null : $(container))
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
     }
 
     this.transport = Ajax.getTransport();
     this.setOptions(options);
 
     var onComplete = this.options.onComplete || Prototype.emptyFunction;
-    this.options.onComplete = (function(transport, object) {
+    this.options.onComplete = (function(transport, param) {
       this.updateContent();
-      onComplete(transport, object);
+      onComplete(transport, param);
     }).bind(this);
 
     this.request(url);
   },
 
   updateContent: function() {
-    var receiver = this.responseIsSuccess() ?
-      this.containers.success : this.containers.failure;
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
     var response = this.transport.responseText;
 
-    if (!this.options.evalScripts)
-      response = response.stripScripts();
+    if (!this.options.evalScripts) response = response.stripScripts();
 
-    if (receiver) {
-      if (this.options.insertion) {
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
         new this.options.insertion(receiver, response);
-      } else {
-        Element.update(receiver, response);
-      }
+      else
+        receiver.update(response);
     }
 
-    if (this.responseIsSuccess()) {
+    if (this.success()) {
       if (this.onComplete)
         setTimeout(this.onComplete.bind(this), 10);
     }
@@ -846,7 +1043,7 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
   },
 
   stop: function() {
-    this.updater.onComplete = undefined;
+    this.updater.options.onComplete = undefined;
     clearTimeout(this.timer);
     (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
   },
@@ -866,25 +1063,43 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
     this.updater = new Ajax.Updater(this.container, this.url, this.options);
   }
 });
-function $() {
-  var results = [], element;
-  for (var i = 0; i < arguments.length; i++) {
-    element = arguments[i];
-    if (typeof element == 'string')
-      element = document.getElementById(element);
-    results.push(Element.extend(element));
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
   }
-  return results.length < 2 ? results[0] : results;
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
 }
 
 document.getElementsByClassName = function(className, parentElement) {
-  var children = ($(parentElement) || document.body).getElementsByTagName('*');
-  return $A(children).inject([], function(elements, child) {
-    if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
-      elements.push(Element.extend(child));
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
     return elements;
-  });
-}
+  }
+};
 
 /*--------------------------------------------------------------------------*/
 
@@ -892,21 +1107,28 @@ if (!window.Element)
   var Element = new Object();
 
 Element.extend = function(element) {
-  if (!element) return;
-  if (_nativeExtensions) return element;
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
 
   if (!element._extended && element.tagName && element != window) {
-    var methods = Element.Methods, cache = Element.extend.cache;
-    for (property in methods) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
       var value = methods[property];
-      if (typeof value == 'function')
+      if (typeof value == 'function' && !(property in element))
         element[property] = cache.findOrStore(value);
     }
   }
 
   element._extended = true;
   return element;
-}
+};
 
 Element.extend.cache = {
   findOrStore: function(value) {
@@ -914,46 +1136,45 @@ Element.extend.cache = {
       return value.apply(null, [this].concat($A(arguments)));
     }
   }
-}
+};
 
 Element.Methods = {
   visible: function(element) {
     return $(element).style.display != 'none';
   },
 
-  toggle: function() {
-    for (var i = 0; i < arguments.length; i++) {
-      var element = $(arguments[i]);
-      Element[Element.visible(element) ? 'hide' : 'show'](element);
-    }
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
   },
 
-  hide: function() {
-    for (var i = 0; i < arguments.length; i++) {
-      var element = $(arguments[i]);
-      element.style.display = 'none';
-    }
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
   },
 
-  show: function() {
-    for (var i = 0; i < arguments.length; i++) {
-      var element = $(arguments[i]);
-      element.style.display = '';
-    }
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
   },
 
   remove: function(element) {
     element = $(element);
     element.parentNode.removeChild(element);
+    return element;
   },
 
   update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
     $(element).innerHTML = html.stripScripts();
     setTimeout(function() {html.evalScripts()}, 10);
+    return element;
   },
 
   replace: function(element, html) {
     element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
     if (element.outerHTML) {
       element.outerHTML = html.stripScripts();
     } else {
@@ -963,11 +1184,106 @@ Element.Methods = {
         range.createContextualFragment(html.stripScripts()), element);
     }
     setTimeout(function() {html.evalScripts()}, 10);
+    return element;
   },
 
-  getHeight: function(element) {
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
     element = $(element);
-    return element.offsetHeight;
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
   },
 
   classNames: function(element) {
@@ -976,34 +1292,60 @@ Element.Methods = {
 
   hasClassName: function(element, className) {
     if (!(element = $(element))) return;
-    return Element.classNames(element).include(className);
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
   },
 
   addClassName: function(element, className) {
     if (!(element = $(element))) return;
-    return Element.classNames(element).add(className);
+    Element.classNames(element).add(className);
+    return element;
   },
 
   removeClassName: function(element, className) {
     if (!(element = $(element))) return;
-    return Element.classNames(element).remove(className);
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
   },
 
   // removes whitespace-only text node children
   cleanWhitespace: function(element) {
     element = $(element);
-    for (var i = 0; i < element.childNodes.length; i++) {
-      var node = element.childNodes[i];
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
       if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
-        Element.remove(node);
+        element.removeChild(node);
+      node = nextNode;
     }
+    return element;
   },
 
   empty: function(element) {
     return $(element).innerHTML.match(/^\s*$/);
   },
 
-  childOf: function(element, ancestor) {
+  descendantOf: function(element, ancestor) {
     element = $(element), ancestor = $(ancestor);
     while (element = element.parentNode)
       if (element == ancestor) return true;
@@ -1012,38 +1354,69 @@ Element.Methods = {
 
   scrollTo: function(element) {
     element = $(element);
-    var x = element.x ? element.x : element.offsetLeft,
-        y = element.y ? element.y : element.offsetTop;
-    window.scrollTo(x, y);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
   },
 
   getStyle: function(element, style) {
     element = $(element);
-    var value = element.style[style.camelize()];
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
     if (!value) {
       if (document.defaultView && document.defaultView.getComputedStyle) {
         var css = document.defaultView.getComputedStyle(element, null);
-        value = css ? css.getPropertyValue(style) : null;
+        value = css ? css[style] : null;
       } else if (element.currentStyle) {
-        value = element.currentStyle[style.camelize()];
+        value = element.currentStyle[style];
       }
     }
 
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
     if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
       if (Element.getStyle(element, 'position') == 'static') value = 'auto';
-
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
     return value == 'auto' ? null : value;
   },
 
   setStyle: function(element, style) {
     element = $(element);
-    for (var name in style)
-      element.style[name.camelize()] = style[name];
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value == '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
   },
 
   getDimensions: function(element) {
     element = $(element);
-    if (Element.getStyle(element, 'display') != 'none')
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
       return {width: element.offsetWidth, height: element.offsetHeight};
 
     // All *Width and *Height properties give 0 on elements with display none,
@@ -1051,12 +1424,13 @@ Element.Methods = {
     var els = element.style;
     var originalVisibility = els.visibility;
     var originalPosition = els.position;
+    var originalDisplay = els.display;
     els.visibility = 'hidden';
     els.position = 'absolute';
-    els.display = '';
+    els.display = 'block';
     var originalWidth = element.clientWidth;
     var originalHeight = element.clientHeight;
-    els.display = 'none';
+    els.display = originalDisplay;
     els.position = originalPosition;
     els.visibility = originalVisibility;
     return {width: originalWidth, height: originalHeight};
@@ -1075,6 +1449,7 @@ Element.Methods = {
         element.style.left = 0;
       }
     }
+    return element;
   },
 
   undoPositioned: function(element) {
@@ -1087,49 +1462,153 @@ Element.Methods = {
         element.style.bottom =
         element.style.right = '';
     }
+    return element;
   },
 
   makeClipping: function(element) {
     element = $(element);
-    if (element._overflow) return;
-    element._overflow = element.style.overflow;
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
     if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
       element.style.overflow = 'hidden';
+    return element;
   },
 
   undoClipping: function(element) {
     element = $(element);
-    if (element._overflow) return;
-    element.style.overflow = element._overflow;
-    element._overflow = undefined;
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
   }
-}
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
 
 Object.extend(Element, Element.Methods);
 
 var _nativeExtensions = false;
 
-if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
-  var HTMLElement = {}
-  HTMLElement.prototype = document.createElement('div').__proto__;
-}
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
 
 Element.addMethods = function(methods) {
   Object.extend(Element.Methods, methods || {});
 
-  if(typeof HTMLElement != 'undefined') {
-    var methods = Element.Methods, cache = Element.extend.cache;
-    for (property in methods) {
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
       var value = methods[property];
-      if (typeof value == 'function')
-        HTMLElement.prototype[property] = cache.findOrStore(value);
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
     }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
     _nativeExtensions = true;
   }
 }
 
-Element.addMethods();
-
 var Toggle = new Object();
 Toggle.display = Element.toggle;
 
@@ -1148,8 +1627,8 @@ Abstract.Insertion.prototype = {
       try {
         this.element.insertAdjacentHTML(this.adjacency, this.content);
       } catch (e) {
-        var tagName = this.element.tagName.toLowerCase();
-        if (tagName == 'tbody' || tagName == 'tr') {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
           this.insertContent(this.contentFromAnonymousTable());
         } else {
           throw e;
@@ -1248,20 +1727,18 @@ Element.ClassNames.prototype = {
 
   add: function(classNameToAdd) {
     if (this.include(classNameToAdd)) return;
-    this.set(this.toArray().concat(classNameToAdd).join(' '));
+    this.set($A(this).concat(classNameToAdd).join(' '));
   },
 
   remove: function(classNameToRemove) {
     if (!this.include(classNameToRemove)) return;
-    this.set(this.select(function(className) {
-      return className != classNameToRemove;
-    }).join(' '));
+    this.set($A(this).without(classNameToRemove).join(' '));
   },
 
   toString: function() {
-    return this.toArray().join(' ');
+    return $A(this).join(' ');
   }
-}
+};
 
 Object.extend(Element.ClassNames.prototype, Enumerable);
 var Selector = Class.create();
@@ -1308,15 +1785,15 @@ Selector.prototype = {
     if (params.wildcard)
       conditions.push('true');
     if (clause = params.id)
-      conditions.push('element.id == ' + clause.inspect());
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
     if (clause = params.tagName)
       conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
     if ((clause = params.classNames).length > 0)
-      for (var i = 0; i < clause.length; i++)
-        conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
     if (clause = params.attributes) {
       clause.each(function(attribute) {
-        var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
         var splitValueBy = function(delimiter) {
           return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
         }
@@ -1329,7 +1806,7 @@ Selector.prototype = {
                           ); break;
           case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
           case '':
-          case undefined: conditions.push(value + ' != null'); break;
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
           default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
         }
       });
@@ -1340,6 +1817,7 @@ Selector.prototype = {
 
   compileMatcher: function() {
     this.match = new Function('element', 'if (!element.tagName) return false; \
+      element = $(element); \
       return ' + this.buildMatchExpression());
   },
 
@@ -1354,7 +1832,7 @@ Selector.prototype = {
     scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
 
     var results = [];
-    for (var i = 0; i < scope.length; i++)
+    for (var i = 0, length = scope.length; i < length; i++)
       if (this.match(element = scope[i]))
         results.push(Element.extend(element));
 
@@ -1366,206 +1844,241 @@ Selector.prototype = {
   }
 }
 
-function $$() {
-  return $A(arguments).map(function(expression) {
-    return expression.strip().split(/\s+/).inject([null], function(results, expr) {
-      var selector = new Selector(expr);
-      return results.map(selector.findElements.bind(selector)).flatten();
-    });
-  }).flatten();
-}
-var Field = {
-  clear: function() {
-    for (var i = 0; i < arguments.length; i++)
-      $(arguments[i]).value = '';
-  },
-
-  focus: function(element) {
-    $(element).focus();
-  },
-
-  present: function() {
-    for (var i = 0; i < arguments.length; i++)
-      if ($(arguments[i]).value == '') return false;
-    return true;
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
   },
 
-  select: function(element) {
-    $(element).select();
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
   },
 
-  activate: function(element) {
-    element = $(element);
-    element.focus();
-    if (element.select)
-      element.select();
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
   }
-}
-
-/*--------------------------------------------------------------------------*/
+});
 
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
 var Form = {
-  serialize: function(form) {
-    var elements = Form.getElements($(form));
-    var queryComponents = new Array();
-
-    for (var i = 0; i < elements.length; i++) {
-      var queryComponent = Form.Element.serialize(elements[i]);
-      if (queryComponent)
-        queryComponents.push(queryComponent);
-    }
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
 
-    return queryComponents.join('&');
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
   },
 
   getElements: function(form) {
-    form = $(form);
-    var elements = new Array();
-
-    for (var tagName in Form.Element.Serializers) {
-      var tagElements = form.getElementsByTagName(tagName);
-      for (var j = 0; j < tagElements.length; j++)
-        elements.push(tagElements[j]);
-    }
-    return elements;
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
   },
 
   getInputs: function(form, typeName, name) {
     form = $(form);
     var inputs = form.getElementsByTagName('input');
 
-    if (!typeName && !name)
-      return inputs;
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
 
-    var matchingInputs = new Array();
-    for (var i = 0; i < inputs.length; i++) {
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
       var input = inputs[i];
-      if ((typeName && input.type != typeName) ||
-          (name && input.name != name))
+      if ((typeName && input.type != typeName) || (name && input.name != name))
         continue;
-      matchingInputs.push(input);
+      matchingInputs.push(Element.extend(input));
     }
 
     return matchingInputs;
   },
 
   disable: function(form) {
-    var elements = Form.getElements(form);
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
+    form = $(form);
+    form.getElements().each(function(element) {
       element.blur();
       element.disabled = 'true';
-    }
+    });
+    return form;
   },
 
   enable: function(form) {
-    var elements = Form.getElements(form);
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
+    form = $(form);
+    form.getElements().each(function(element) {
       element.disabled = '';
-    }
+    });
+    return form;
   },
 
   findFirstElement: function(form) {
-    return Form.getElements(form).find(function(element) {
+    return $(form).getElements().find(function(element) {
       return element.type != 'hidden' && !element.disabled &&
         ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
     });
   },
 
   focusFirstElement: function(form) {
-    Field.activate(Form.findFirstElement(form));
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
   },
 
-  reset: function(form) {
-    $(form).reset();
+  select: function(element) {
+    $(element).select();
+    return element;
   }
 }
 
-Form.Element = {
+Form.Element.Methods = {
   serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
     element = $(element);
     var method = element.tagName.toLowerCase();
-    var parameter = Form.Element.Serializers[method](element);
+    return Form.Element.Serializers[method](element);
+  },
 
-    if (parameter) {
-      var key = encodeURIComponent(parameter[0]);
-      if (key.length == 0) return;
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
 
-      if (parameter[1].constructor != Array)
-        parameter[1] = [parameter[1]];
+  present: function(element) {
+    return $(element).value != '';
+  },
 
-      return parameter[1].map(function(value) {
-        return key + '=' + encodeURIComponent(value);
-      }).join('&');
-    }
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
   },
 
-  getValue: function(element) {
+  disable: function(element) {
     element = $(element);
-    var method = element.tagName.toLowerCase();
-    var parameter = Form.Element.Serializers[method](element);
+    element.disabled = true;
+    return element;
+  },
 
-    if (parameter)
-      return parameter[1];
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
   }
 }
 
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
 Form.Element.Serializers = {
   input: function(element) {
     switch (element.type.toLowerCase()) {
-      case 'submit':
-      case 'hidden':
-      case 'password':
-      case 'text':
-        return Form.Element.Serializers.textarea(element);
       case 'checkbox':
       case 'radio':
         return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
     }
-    return false;
   },
 
   inputSelector: function(element) {
-    if (element.checked)
-      return [element.name, element.value];
+    return element.checked ? element.value : null;
   },
 
   textarea: function(element) {
-    return [element.name, element.value];
+    return element.value;
   },
 
   select: function(element) {
-    return Form.Element.Serializers[element.type == 'select-one' ?
+    return this[element.type == 'select-one' ?
       'selectOne' : 'selectMany'](element);
   },
 
   selectOne: function(element) {
-    var value = '', opt, index = element.selectedIndex;
-    if (index >= 0) {
-      opt = element.options[index];
-      value = opt.value || opt.text;
-    }
-    return [element.name, value];
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
   },
 
   selectMany: function(element) {
-    var value = [];
-    for (var i = 0; i < element.length; i++) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
       var opt = element.options[i];
-      if (opt.selected)
-        value.push(opt.value || opt.text);
+      if (opt.selected) values.push(this.optionValue(opt));
     }
-    return [element.name, value];
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
   }
 }
 
 /*--------------------------------------------------------------------------*/
 
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
 Abstract.TimedObserver = function() {}
 Abstract.TimedObserver.prototype = {
   initialize: function(element, frequency, callback) {
@@ -1583,7 +2096,9 @@ Abstract.TimedObserver.prototype = {
 
   onTimerEvent: function() {
     var value = this.getValue();
-    if (this.lastValue != value) {
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
       this.callback(this.element, value);
       this.lastValue = value;
     }
@@ -1628,9 +2143,7 @@ Abstract.EventObserver.prototype = {
   },
 
   registerFormCallbacks: function() {
-    var elements = Form.getElements(this.element);
-    for (var i = 0; i < elements.length; i++)
-      this.registerCallback(elements[i]);
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
   },
 
   registerCallback: function(element) {
@@ -1640,11 +2153,7 @@ Abstract.EventObserver.prototype = {
         case 'radio':
           Event.observe(element, 'click', this.onElementEvent.bind(this));
           break;
-        case 'password':
-        case 'text':
-        case 'textarea':
-        case 'select-one':
-        case 'select-multiple':
+        default:
           Event.observe(element, 'change', this.onElementEvent.bind(this));
           break;
       }
@@ -1679,6 +2188,10 @@ Object.extend(Event, {
   KEY_RIGHT:    39,
   KEY_DOWN:     40,
   KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
 
   element: function(event) {
     return event.target || event.srcElement;
@@ -1734,7 +2247,7 @@ Object.extend(Event, {
 
   unloadCache: function() {
     if (!Event.observers) return;
-    for (var i = 0; i < Event.observers.length; i++) {
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
       Event.stopObserving.apply(this, Event.observers[i]);
       Event.observers[i][0] = null;
     }
@@ -1742,7 +2255,7 @@ Object.extend(Event, {
   },
 
   observe: function(element, name, observer, useCapture) {
-    var element = $(element);
+    element = $(element);
     useCapture = useCapture || false;
 
     if (name == 'keypress' &&
@@ -1750,11 +2263,11 @@ Object.extend(Event, {
         || element.attachEvent))
       name = 'keydown';
 
-    this._observeAndCache(element, name, observer, useCapture);
+    Event._observeAndCache(element, name, observer, useCapture);
   },
 
   stopObserving: function(element, name, observer, useCapture) {
-    var element = $(element);
+    element = $(element);
     useCapture = useCapture || false;
 
     if (name == 'keypress' &&
@@ -1765,7 +2278,9 @@ Object.extend(Event, {
     if (element.removeEventListener) {
       element.removeEventListener(name, observer, useCapture);
     } else if (element.detachEvent) {
-      element.detachEvent('on' + name, observer);
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
     }
   }
 });
@@ -1819,7 +2334,8 @@ var Position = {
       valueL += element.offsetLeft || 0;
       element = element.offsetParent;
       if (element) {
-        p = Element.getStyle(element, 'position');
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
         if (p == 'relative' || p == 'absolute') break;
       }
     } while (element);
@@ -1875,17 +2391,6 @@ var Position = {
         element.offsetWidth;
   },
 
-  clone: function(source, target) {
-    source = $(source);
-    target = $(target);
-    target.style.position = 'absolute';
-    var offsets = this.cumulativeOffset(source);
-    target.style.top    = offsets[1] + 'px';
-    target.style.left   = offsets[0] + 'px';
-    target.style.width  = source.offsetWidth + 'px';
-    target.style.height = source.offsetHeight + 'px';
-  },
-
   page: function(forElement) {
     var valueT = 0, valueL = 0;
 
@@ -1902,8 +2407,10 @@ var Position = {
 
     element = forElement;
     do {
-      valueT -= element.scrollTop  || 0;
-      valueL -= element.scrollLeft || 0;
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
     } while (element = element.parentNode);
 
     return [valueL, valueT];
@@ -1964,10 +2471,10 @@ var Position = {
     element._originalHeight = element.style.height;
 
     element.style.position = 'absolute';
-    element.style.top    = top + 'px';;
-    element.style.left   = left + 'px';;
-    element.style.width  = width + 'px';;
-    element.style.height = height + 'px';;
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
   },
 
   relativize: function(element) {
@@ -2003,4 +2510,6 @@ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
 
     return [valueL, valueT];
   }
-}
\ No newline at end of file
+}
+
+Element.addMethods();
\ No newline at end of file
diff --git a/script/process/inspector b/script/process/inspector
new file mode 100755 (executable)
index 0000000..bf25ad8
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+require File.dirname(__FILE__) + '/../../config/boot'
+require 'commands/process/inspector'
diff --git a/script/process/spinner b/script/process/spinner
deleted file mode 100755 (executable)
index 2a49c44..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/ruby1.8
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/spinner'
diff --git a/vendor/actionmailer b/vendor/actionmailer
deleted file mode 120000 (symlink)
index ff2b054..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/rails/actionmailer
\ No newline at end of file
diff --git a/vendor/actionpack b/vendor/actionpack
deleted file mode 120000 (symlink)
index 7cbbd1b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/rails/actionpack
\ No newline at end of file
diff --git a/vendor/actionwebservice b/vendor/actionwebservice
deleted file mode 120000 (symlink)
index 259e514..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/rails/actionwebservice
\ No newline at end of file
diff --git a/vendor/activerecord b/vendor/activerecord
deleted file mode 120000 (symlink)
index d85f966..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/rails/activerecord
\ No newline at end of file
diff --git a/vendor/activesupport b/vendor/activesupport
deleted file mode 120000 (symlink)
index b179a59..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/rails/activesupport
\ No newline at end of file
diff --git a/vendor/plugins/engines/CHANGELOG b/vendor/plugins/engines/CHANGELOG
deleted file mode 100755 (executable)
index aec72d5..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-*SVN*
-
-
------
-1.1.4
-
-Fixed creation of multipart emails (Ticket #190)
-Added a temporary fix to the code-mixing issue. In your engine's test/test_helper.rb, please add the following lines:
-
-  # Ensure that the code mixing and view loading from the application is disabled
-  Engines.disable_app_views_loading = true
-  Engines.disable_app_code_mixing = true
-
-is will prevent code mixing for controllers and helpers, and loading views from the application. One thing to remember is to load any controllers/helpers using 'require_or_load' in your tests, to ensure that the engine behaviour is respected (Ticket #135)
-Added tasks to easily test engines individually (Ticket #120)
-Fixture extensions will now fail with an exception if the corresponding class cannot be loaded (Ticket #138)
-Patch for new routing/controller loading in Rails 1.1.6. The routing code is now replaced with the contents of config.controller_paths, along with controller paths from any started engines (Ticket #196)
-Rails' Configuration instance is now stored, and available from all engines and plugins.
-
-
------
-1.1.3
-
-Fixed README to show 'models' rather than 'model' class (Ticket #167)
-Fixed dependency loading to work with Rails 1.1.4 (Ticket #180)
-
-
------
-1.1.2
-
-Added better fix to version checking (Ticket #130, jdell@gbdev.com).
-Fixed generated init_engine.rb so that VERSION module doesn't cause probems (Ticket #131, japgolly@gmail.com)
-Fixed error with Rails 1.0 when trying to ignore the engine_schema_info table (Ticket #132, snowblink@gmail.com)
-Re-added old style rake tasks (Ticket #133)
-No longer adding all subdirectories of <engine>/app or <engine>/lib, as this can cause issues when files are grouped in modules (Ticket #149, kasatani@gmail.com)
-Fixed engine precidence ordering for Rails 1.1 (Ticket #146)
-Added new Engines.each method to assist in processing the engines in the desired order (Ticket #146)
-Fixed annoying error message at appears when starting the console in development mode (Ticket #134)
-Engines is now super-careful about loading the correct version of Rails from vendor (Ticket #154)
-
-
------
-1.1.1
-
-Fixed migration rake task failing when given a specific version (Ticket #115)
-Added new rake task "test:engines" which will test engines (and other plugins) but ensure that the test database is cloned from development beforehand (Ticket #125)
-Fixed issue where 'engine_schema_info' table was included in schema dumps (Ticket #87)
-Fixed multi-part emails (Ticket #121)
-Added an 'install.rb' file to new engines created by the bundled generator, which installs the engines plugin automatically if it doesn't already exist (Ticket #122)
-Added a default VERSION module to generated engines (Ticket #123)
-Refactored copying of engine's public files to a method of an Engine instance. You can now call Engines.get(:engine_name).copy_public_files (Ticket #108)
-Changed engine generator templates from .rb files to .erb files (Ticket #106)
-Fixed the test_helper.erb file to use the correct testing extensions and not load any schema - the schema will be cloned automatically via rake test:engines
-Fixed problem when running with Rails 1.1.1 where version wasn't determined correctly (Ticket #129)
-Fixed bug preventing engines from loading when both Rails 1.1.0 and 1.1.1 gems are installed and in use.
-Updated version (d'oh!)
-
-
------
-1.1.0
-
-Improved regexp matching for Rails 1.0 engines with peculiar paths
-Engine instance objects can be accessed via Engines[:name], an alias for Engines.get(:name) (Ticket #99)
-init_engine.rb is now processed as the final step in the Engine.start process, so it can access files within the lib directory, which is now in the $LOAD_PATH at that point. (Ticket #99)
-Clarified MIT license (Ticket #98)
-Updated Rake tasks to integrate smoothly with Rails 1.1 namespaces
-Changed the version to "1.1.0 (svn)"
-Added more information about using the plugin with Edge Rails to the README
-moved extensions into lib/engines/ directory to enable use of Engines module in extension code.
-Added conditional require_or_load method which attempts to detect the current Rails version. To use the Edge Rails version of the loading mechanism, add the line:
-  Engines.config :edge, true
-to your environment.rb file.
-Merged changes from /branches/edge and /branches/rb_1.0 into /trunk
-engine_schema_info now respects the prefix/suffixes set for ActiveRecord::Base (Ticket #67)
-added ActiveRecord::Base.wrapped_table_name(name) method to assist in determining the correct table name
-
-
------
-1.0.6
-
-Added ability to determine version information for engines: rake engine_info
-Added a custom logger for the Engines module, to stop pollution of the Rails logs.
-Added some more tests (in particular, see rails_engines/applications/engines_test).
-Another attempt at solving Ticket #53 - controllers and helpers should now be loadable from modules, and if a full path (including RAILS_ROOT/ENGINES_ROOT) is given, it should be safely stripped from the require filename such that corresponding files can be located in any active engines. In other words, controller/helper overloading should now completely work, even if the controllers/helpers are in modules.
-Added (finally) patch from Ticket #22 - ActionMailer helpers should now load
-Removed support for Engines.start :engine, :engine_name => 'whatever'. It was pointless.
-Fixed engine name referencing; engine_stylesheet/engine_javascript can now happily use shorthand engine names (i.e. :test == :test_engine) (Ticket #45)
-Fixed minor documentation error ('Engine.start' ==> 'Engines.start') (Ticket #57)
-Fixed double inclusion of RAILS_ROOT in engine_migrate rake task (Ticket #61)
-Added ability to force config values even if given as a hash (Ticket #62)
-
-
------
-1.0.5
-
-Fixed bug stopping fixtures from loading with PostgreSQL
-
-
------
-1.0.4
-
-Another attempt at loading controllers within modules (Ticket #56)
-
-
------
-1.0.3
-
-Fixed serious dependency bug stopping controllers being loaded (Ticket #56)
-
-
------
-1.0.2
-
-Fixed bug with overloading controllers in modules from /app directory
-Fixed exception thrown when public files couldn't be created; exception is now logged (Ticket #52)
-Fixed problem with generated test_helper.rb file via File.expand_path (Ticket #50)
-
-
------
-1.0.1
-
-Added engine generator for creation of new engines
-Fixed 'Engine' typo in README
-Fixed bug in fixtures extensions
-Fixed /lib path management bug
-Added method to determine public directory location from Engine object
-Fixed bug in the error message in get_engine_dir()
-Added proper component loading
-Added preliminary tests for the config() methods module
-
-
------
-pre-v170
-
-Fixed copyright notices to point to DHH, rather than me.
-Moved extension require statements into lib/engines.rb, so the will be loaded if another module/file calls require 'engines
-Added a CHANGELOG file (this file)
diff --git a/vendor/plugins/engines/MIT-LICENSE b/vendor/plugins/engines/MIT-LICENSE
deleted file mode 100755 (executable)
index 5376ba1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 2006 James Adam
-
-The MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/plugins/engines/README b/vendor/plugins/engines/README
deleted file mode 100755 (executable)
index e1ae48d..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-= Welcome
-
-This document gives an overview of how the Engines mechanism works within a Rails environment. In most cases the code below is just an example. For more information or documentation, please go to http://rails-engines.org.
-
-== Background
-
-Rails Engines are a way of dropping in whole chunks of functionality into your
-existing application without affecting *any* of your existing code. The could also be described as mini-applications, or vertical application slices - top-to-bottom units which provide full MVC coverage for a certain, specific application function.
-
-As an example, the Login Engine provides a full user login subsystem, including: 
-* controllers to manage user accounts; 
-* helpers for you to interact with account information from other 
-  parts of your application; 
-* the model objects and schemas to create the required tables; 
-* stylesheets and javascript files to enhance the views; 
-* and any other library files required.
-
-Once the Rails Core team decides on a suitable method for packaging plugins, Engines can be distributed using the same mechanisms. If you are developing engines yourself for use across multiple projects, linking them as svn externals allows seamless updating of bugfixes across multiple applications.
-
-
-
-
-
-= Edge Engines
-
-If you are using Edge Rails (an SVN copy of Rails, rather than an 'official' release), there are several MASSIVELY IMPORTANT issues that you need to bear in mind.
-
-Firstly, you are using an unstable version of Rails, so it is possible that things will break. We work hard to keep the Engines plugin up to speed with the changes in Rails at the bleeding edge, but sometimes significant parts of Rails change it WILL cause problems. This is the price of using the bleeding edge. Since edge is synonymous for unstable, the version of the Engines plugin which is compatible with Edge Rails is kept separate from the official release. Please ensure that you have used SVN to get your engines plugin from
-
-  http://svn.rails-engines.org/engines/trunk
-  
-The normal 'script/plugin install engines' will NOT get you this version.
-
-Secondly, you NEED to tell the engines plugin if you expect it to perform with Edge behaviour. This is done by adding the following lines at the *very top* of environment.rb (yes, the VERY TOP)
-
-  module Engines
-    CONFIG = {:edge => true}
-  end
-
-This will set the plugin to work with Edge Rails, rather than expecting an official release.
-
-If you are having problems, please try and contribute a bug report if you can so we can improve the plugin and keep up to speed with Rails' bleeding edge. Your input is *absolutely crucial* to this. If you're not comfortable with tracking down bugs in Rails' and Engines' internal code, there is a test application available at
-
-  http://svn.rails-engines.org/applications/engines_test
-  
-which contains an array of tests that might help you (and us) pinpoint where the issue is. Please download this application and consult the README for more information.
-
-Finally, please don't forget about our website and mailing lists. More information here:
-
-  http://rails-engines.org
-
-
-
-
-
-
-
-= Using the Engines plugin itself
-
-There are a number of features of the Engines plugin itself which may be useful to know:
-
-
-=== Engines.log
-The Engines plugin comes with its own logger, which is invaluable when debugging. To use it,
-simply call
-
-  Engines.create_logger
-  
-Two optional arguments may be passed to this method:
-
-  Engines.create_logger(<io>)
-  
-Would set the outputter to the logger to the given IO object <io>. For example, this could be STDERR or STDOUT (the default). The second argument is the logger level:
-
-  Engines.create_logger(STDOUT, Logger::INFO)
-  
-The logger can be accessed using either of the following:
-
-  Engines.log.[debug|info|whatever] "message"
-  Engines.logger.[debug|info|whatever] "message"
-  
-... essentially it's a Logger object. It's worth noting that if you *don't* create a logger, calls to Engines.log will just be swallowed without a sound, making it very very easy to completely silence Engine logging.
-
-
-=== Engines.config(:root)
-
-By default, the Engines plugin expects to be starting Engines from within RAILS_ROOT/vendor/plugins. However, if you'd like to store your engines in a different directory, add the following line *before* any call to Engines.start
-
-  Engines.config(:root, "/path/to/your/directory", :force)
-  
-  
-=== Rake Tasks
-
-The engines plugin comes with a number of handy rake tasks:
-
-  #¬†display version information about the engines subsystem
-  rake engines:info 
-  
-  # migrate engines' database schemas in a controlled way
-  rake db:migrate:engines
-  
-  # generates full documentation for all engines
-  rake doc:engines      
-  
-There are more, but you'll have to discover them yourself...  
-
-
-== More information
-
-For more information about what you can do with the Engines plugin, you'll need to generate the documentation (rake plugindoc), or go to http://rails-engines.org. Good luck!  
-
-
-
-
-
-
-
-
-= Quickstart
-
-=== Gentlemen, Start your Engines!
-
-
-Here's an *example* of how you might go about using Rails Engines. Please bear in mind that actual Engines may differ from this, but these are the steps you will *typically* have to take. Refer to individual Engine documentation for specific installation instructions. Anyway, on with the show:
-
-1. Install the Rails Engines plugin into your plugins directory. You'll probably need to accept the SSL certificate here for the OpenSVN servers. For example:
-
-    $ script/plugin install engines
-
- or
-
-    $ svn co http://svn.rails-engines.org/plugins/engines <MY_RAILS_APP>/vendor/plugins/engines
-
-2. Install your engine into the plugins directory in a similar way.
-
-3. Create the RDoc for the engines plugin and for your engines so you know what's going on:
-
-     $ rake doc:plugins
-     $ rake doc:engines
-
-4. Initialize any database schema provided. The Engine may provide Rake tasks to do this for you. Beware that accepting an Engine schema might affect any existing database tables you have installed! You are STRONGLY recommended to inspect the <tt>db/schema.rb</tt> file to see exactly what running it might change.
-
-5. Add configuration to <tt>environment.rb</tt>:
-   e.g.
-
-      # Add your application configuration here
-      module MyEngine
-        config :top_speed, "MegaTurboFast"
-      end
-      Engines.start :my_engine
-
-6. Run your server!
-
-      $ script/server
-
-
-
-
-= Building an Engine
-
-Here's a sample rails application with a detailed listing of an example engines as a concrete example:
-
-  RAILS_ROOT
-    |- app
-    |- lib
-    |- config
-    |- <... other directories ...>
-    |- vendor
-        |-plugins
-            |- engines               <-- the engines plugin
-            |- some_other_plugin 
-            |- my_engine             <-- our example engine
-                  |- init_engine.rb
-                  |- app
-                  |     |- controllers
-                  |     |- models
-                  |     |- helpers
-                  |     |- views
-                  |- db
-                  |- tasks
-                  |- lib
-                  |- public
-                  |     |- javascripts
-                  |     |- stylesheets
-                  |- test
-
-
-The internal structure of an engine mirrors the familiar core of a Rails application, with most of the engine within the <tt>app</tt> subdirectory. Within <tt>app</tt>, the controllers, views and model objects behave just as you might expect if there in the top-level <tt>app</tt> directory.
-
-When you call <tt>Engines.start :my_engine</tt> in <tt>environment.rb</tt> a few important bits of black magic voodoo happen:
-* the engine's controllers, views and models are mixed in to your running Rails application; 
-* files in the <tt>lib</tt> directory of your engine (and subdirectories) are made available 
-  to the rest of your system
-* any directory structure in the folder <tt>public/</tt> within your engine is made available to the webserver
-* the file <tt>init_engine.rb</tt> is loaded from within the engine - just like a plugin. The reason why engines need an init_engine.rb rather than an init.rb is because Rails' default plugin system might try and load an engine before the Engines plugin has been loaded, resulting in all manner of badness. Instead, Rails' skips over any engine plugins, and the Engines plugin handles initializing your Engines plugins when you 'start' each engine.
-
-From within <tt>init_engine.rb</tt> you should load any libraries from your <tt>lib</tt> directory that your engine might need to function. You can also perform any configuration required.
-
-=== Loading all Engines
-
-Calling either Engines.start (with no arguments) or Engines.start_all will load all engines available. Please note that your plugin can only be *automatically* detected as an engine by the presence of an 'init_engine.rb' file, or if the engine is in a directory named <something>_engine, or <something>_bundle. If neither of these conditions hold, then your engine will not be loaded by Engines.start() (with no arguments) or Engines.start_all().
-
-
-
-
-
-
-
-= Configuring Engines
-
-Often your engine will require a number of configuration parameters set, some of which should be alterable by the user to reflect their particular needs. For example, a Login System might need a unique Salt value set to encrypt user passwords. This value should be unique to each application.
-
-Engines provides a simple mechanism to handle this, and it's already been hinted at above. Within any module, a new method is now available: <tt>config</tt>. This method creates a special <tt>CONFIG</tt> Hash object within the Module it is called, and can be used to store your parameters. For a user to set these parameters, they should reopen the module (before the corresponding Engines.start call), as follows:
-
-  module MyModule
-    config :some_option, "really_important_value"
-  end
-  Engines.start :my_engine
-
-Because this config value has been set before the Engine is started, subsequent attempts to set this config value will be ignored and the user-specified value used instead. Of course, there are situations where you *really* want to set the config value, even if it already exists. In such cases the config call can be changed to:
-
-  config :some_option, "no_THIS_really_important_value", :force
-
-The additional parameter will force the new value to be used. For more information, see Module#config.
-
-
-
-
-= Tweaking Engines
-
-One of the best things about Engines is that if you don't like the default behaviour of any component, you can override it without needing to overhaul the whole engine. This makes adding your customisations to engines almost painless, and allows for upgrading/updating engine code without affecting the specialisations you need for your particular application.
-
-
-=== View Tweaks
-These are the simplest - just drop your customised view (or partial) into you <tt>/app/views</tt> directory in the corresponding location for the engine, and your view will be used in preference to the engine view. For example, if we have a ItemController with an action 'show', it will (normally) expect to find its view as <tt>report/show.rhtml</tt> in the <tt>views</tt> directory. The view is found in the engine at <tt>/vendor/engines/my_engine/app/views/report/show.rhtml</tt>. However, if you create the file <tt>/app/views/report/show.rhtml</tt>, that file will be used instead! The same goes for partials.
-
-
-=== Controller Tweaks
-You can override controller behaviour by replacing individual controller methods with your custom behaviour. Lets say that our ItemController's 'show' method isn't up to scratch, but the rest of it behaves just fine. To override the single method, create <tt>/app/controllers/item_controller.rb</tt>, just as if it were going to be a new controller in a regular Rails application. then, implement your show method as you would like it to happen.
-
-... and that's it. Your custom code will be mixed in to the engine controller, replacing its old method with your custom code.
-
-
-=== Model/Lib Tweaks
-Alas, tweaking model objects isn't quite so easy (yet). If you need to change the behaviour of model objects, you'll need to copy the model file from the engine into <tt>/app/models</tt> and edit the methods yourself. Library code can be overridden in a similar way.
-
-
-
-
-
-
-
-
-
-= Public Files
-
-If the Engine includes a <tt>public</tt> directory, its contents will be mirrored into <tt>RAILS_ROOT/public/engine_files/&lt;engine_name&gt;/</tt> so that these files can be served by your webserver to browsers and users over the internet.
-
-Engines also provides two convenience methods for loading stylesheets and javascript files in your layouts: <tt>engine_stylesheet</tt> and <tt>engine_javascript</tt>.
-
-=== Engine Stylesheets
-
-  <%= engine_stylesheet "my_engine" %>
-
-will include <tt>RAILS_ROOT/public/&lt;engine_files&gt;/my_engine/stylesheets/my_engine.css</tt> in your layout. If you have more than one stylesheet, you can include them in the same call:
-
-  <%= engine_stylesheet "my_engine", "stylesheet_2", "another_one" %>
-
-will give you:
-
-    <link href="/engine_files/my_engine/stylesheets/my_engine.css" media="screen" rel="Stylesheet" type="text/css" />
-    <link href="/engine_files/my_engine/stylesheets/stylesheet_2.css" media="screen" rel="Stylesheet" type="text/css" />
-    <link href="/engine_files/my_engine/stylesheets/another_one.css" media="screen" rel="Stylesheet" type="text/css" />
-
-in your rendered layout.
-
-=== Engine Javascripts
-
-The <tt>engine_javascript</tt> command works in exactly the same way as above.
-
-
-
-
-
-
-
-
-
-= Databases and Engines
-
-Engine schema information can be handled using similar mechanisms to your normal application schemas.
-
-== CAVEAT EMPTOR!
-
-I.E. Big Huge Warning In Flashing Lights.
-
-PLEASE, PLEASE, PLEASE bear in mind that if you are letting someone
-ELSE have a say in what tables you are using, you're basically opening
-your application schema open to potential HAVOC. I cannot stress how
-serious this is. It is YOUR responsibility to ensure that you trust
-the schema and migration information, and that it's not going to drop
-your whole database. You need to inspect these things. YOU do. If you
-run these voodoo commands and your database essplodes because you
-didn't double double double check what was going on, your embarassment
-will be infinite. And your project will be skroo'd if the migration
-is irreversible.
-
-That said, if you are working in a team and you all trust each other,
-which is hopefully true, this can be quite useful.
-
-
-== Migrating Engines
-
-To migrate all engines to the latest version:
-
- rake db:migrate:engines
-
-To migrate a single engine, for example the login engine:
-
- rake db:migrate:engines ENGINE=login  (or login_engine)
-
-To migrate a single engine to a specific revision:
-
- rake db:migrate:engines ENGINE=login VERSION=4
-
-This:
-
- rake db:migrate:engines VERSION=1
-
-... will not work, because we felt it was too dangerous to allow ALL
-engines to be migrated to a specific version, since such versions
-might be incompatible.
-
-
-
-
-
-
-
-= Testing Engines
-
-The Engines plugin comes with mechanisms to help test Engines within a developer's own application. The testing extensions enable developers to load fixtures into specific
-tables irrespective of the name of the fixtures file. This work is heavily based on
-patches made by Duane Johnson (canadaduane), viewable at
-http://dev.rubyonrails.org/ticket/1911
-
-Engine developers should supply fixture files in the <engine>/test/fixtures directory
-as normal. Within their tests, they should load the fixtures using the 'fixture' command
-(rather than the normal 'fixtures' command). For example:
-
-  class UserTest < Test::Unit::TestCase
-    fixture :users, :table_name => LoginEngine.config(:user_table), :class_name => "User"
-    ...
-
-This will ensure that the fixtures/users.yml file will get loaded into the correct
-table, and will use the correct model object class.
-
-Your engine should provide a test_helper.rb file in <engine>/test, the contents of which should include the following:
-
-  # Load the default rails test helper - this will load the environment.
-       require File.dirname(__FILE__) + '/../../../../test/test_helper'
-
-       # ensure that the Engines testing enhancements are loaded and will override Rails own
-       # code where needed. This line is very important!
-       require File.join(Engines.config(:root), "engines", "lib", "testing_extensions")
-
-       # Load the schema - if migrations have been performed, this will be up to date.
-       load(File.dirname(__FILE__) + "/../db/schema.rb")
-
-       # set up the fixtures location to use your engine's fixtures
-       Test::Unit::TestCase.fixture_path = File.dirname(__FILE__)  + "/fixtures/"
-       $LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
-
-== Loading Fixtures
-
-An additional helpful task for loading fixture data is also provided (thanks to Joe Van Dyk):
-
-  rake db:fixtures:engines:load
-  rake db:fixtures:engines:load PLUGIN=login_engine
-  
-will load the engine fixture data into your development database.
-
-=== Important Caveat
-Unlike the new 'fixture' directive described above, this task currently relies on you ensuring that the table name to load fixtures into is the same as the name of the fixtures file you are trying to load. If you are using defaults, this should be fine. If you have changed table names, you will need to rename your fixtures files (and possibly update your tests to reflect this too).
-
-You should also note that fixtures typically tend to depend on test configuration information (such as test salt values), so not all data will be usable in fixture form.
-
-
-
-= LICENCE
-
-Copyright (c) 2006, James Adam
-
-The MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/plugins/engines/generators/engine/USAGE b/vendor/plugins/engines/generators/engine/USAGE
deleted file mode 100755 (executable)
index f5970a3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Description:
-  The Engine Generator creates the directories and files you need
-  to create your own engine.
-
-Example:
-  ./script/generate engine MyEngine
-
-  This will generate:
-  RAILS_ROOT
-    |- vendor
-        |-plugins
-            |- my_engine             <-- our example engine
-                  |- init_engine.rb
-                  |- app
-                  |     |- controllers
-                  |     |- model
-                  |     |- helpers
-                  |     |- views
-                  |- db
-                  |- tasks
-                  |- lib
-                  |- public
-                  |     |- javascripts
-                  |     |- stylesheets
-                  |- test
-
diff --git a/vendor/plugins/engines/generators/engine/engine_generator.rb b/vendor/plugins/engines/generators/engine/engine_generator.rb
deleted file mode 100755 (executable)
index ac66525..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-#  Copyright (c) 2005 Jonathan Lim <snowblink@gmail.com>
-#  
-#  The MIT License
-#  
-#  Permission is hereby granted, free of charge, to any person obtaining a copy
-#  of this software and associated documentation files (the "Software"), to deal
-#  in the Software without restriction, including without limitation the rights
-#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#  copies of the Software, and to permit persons to whom the Software is
-#  furnished to do so, subject to the following conditions:
-#  
-#  The above copyright notice and this permission notice shall be included in
-#  all copies or substantial portions of the Software.
-#  
-#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#  THE SOFTWARE.
-
-
-module Rails
-  module Generator
-    module Commands
-
-      class Create < Base
-        def complex_template(relative_source, relative_destination, template_options = {})
-          options = template_options.dup
-          options[:assigns] ||= {}
-          options[:assigns]['template_for_inclusion'] = render_template_part(template_options) if template_options[:mark_id]
-          options[:assigns]['license'] = render_license(template_options)
-          template(relative_source, relative_destination, options)
-        end
-
-        def render_license(template_options)
-          # Getting Sandbox to evaluate part template in it
-          part_binding = template_options[:sandbox].call.sandbox_binding
-          part_rel_path = template_options[:insert]
-          part_path = source_path(part_rel_path)
-
-          # Render inner template within Sandbox binding
-          template_file = File.readlines(part_path)
-          case template_options[:comment_style]
-          when :rb
-            template_file.map! {|x| x.sub(/^/, '#  ')}
-          end
-          rendered_part = ERB.new(template_file.join, nil, '-').result(part_binding)
-        end
-
-      end
-    end
-  end
-end
-
-
-class LicensingSandbox
-  include ActionView::Helpers::ActiveRecordHelper
-  attr_accessor :author
-
-  def sandbox_binding
-    binding
-  end
-
-end
-
-class Author
-  def initialize
-    set_name
-    set_email
-  end
-
-  def set_name
-    print "Please enter the author's name: "
-    @name = gets.chomp
-  end
-
-  def set_email
-    print "Please enter the author's email: "
-    @email = gets.chomp
-  end
-
-  def to_s
-    "#{@name} <#{@email}>"
-  end
-end
-
-class License
-  def initialize(source_root)
-    @source_root = source_root
-    select_license
-  end
-
-  def select_license
-    # list all the licenses in the licenses directory
-    licenses = Dir.entries(File.join(@source_root, 'licenses')).select { |name| name !~ /^\./ }
-    puts "We can generate the following licenses automatically for you:"
-    licenses.sort.each_with_index do |license, index|
-      puts "#{index}) #{licenses[index]}"
-    end
-    print "Please select a license: "
-    while choice = gets.chomp
-      if (choice !~ /^[0-9]+$/)
-        print "Hint - you want to be typing a number.\nPlease select a license: "
-        next
-      end
-      break if choice.to_i >=0 && choice.to_i <= licenses.length
-    end
-      
-    @license = licenses[choice.to_i]
-    puts "'#{@license}' selected"
-  end
-
-  def to_s
-    File.join('licenses', @license)
-  end
-
-end
-
-class EngineGenerator < Rails::Generator::NamedBase
-
-  attr_reader :engine_class_name, :engine_underscored_name, :engine_start_name, :author
-
-
-  def initialize(runtime_args, runtime_options = {})
-    super
-    @engine_class_name = runtime_args.shift
-    
-    # ensure that they've given us a valid class name
-    if @engine_class_name =~ /^[a-z]/
-      raise "'#{@engine_class_name}' should be a valid Ruby constant, e.g. 'MyEngine'; aborting generation..." 
-    end
-    
-    @engine_underscored_name = @engine_class_name.underscore
-    @engine_start_name = @engine_underscored_name.sub(/_engine$/, '')
-    @author = Author.new
-    @license = License.new(source_root)
-  end
-
-  def manifest
-    record do |m|
-      m.directory File.join('vendor', 'plugins')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name)
-      m.complex_template 'README',
-        File.join('vendor', 'plugins', @engine_underscored_name, 'README'),
-        :sandbox => lambda {create_sandbox},
-        :insert => @license.to_s
-
-      m.file 'install.erb', File.join('vendor', 'plugins', @engine_underscored_name, 'install.rb')
-      
-      m.complex_template 'init_engine.erb',
-        File.join('vendor', 'plugins', @engine_underscored_name, 'init_engine.rb'),
-        :sandbox => lambda {create_sandbox},
-        :insert => @license.to_s,
-        :comment_style => :rb
-
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'models')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'controllers')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'helpers')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'views')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'db')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'db', 'migrate')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'lib')
-      m.complex_template File.join('lib', 'engine.erb'),
-        File.join('vendor', 'plugins', @engine_underscored_name, 'lib', "#{@engine_underscored_name}.rb"),
-        :sandbox => lambda {create_sandbox},
-        :insert => @license.to_s,
-        :comment_style => :rb
-
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'lib', @engine_underscored_name)
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'javascripts')
-      m.template File.join('public', 'javascripts', 'engine.js'), File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'javascripts', "#{@engine_underscored_name}.js")
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'stylesheets')
-      m.template File.join('public', 'stylesheets', 'engine.css'), File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'stylesheets', "#{@engine_underscored_name}.css")
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'tasks')
-      m.template File.join('tasks', 'engine.rake'), File.join('vendor', 'plugins', @engine_underscored_name, 'tasks', "#{@engine_underscored_name}.rake")
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test')
-      m.template File.join('test', 'test_helper.erb'), File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'test_helper.rb')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'fixtures')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'functional')
-      m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'unit')      
-    end
-  end
-
-protected
-  def banner
-    "Usage: #{$0} #{spec.name} MyEngine [general options]"
-  end
-
-  def create_sandbox
-    sandbox = LicensingSandbox.new
-    sandbox.author = @author
-    sandbox
-  end
-
-end
diff --git a/vendor/plugins/engines/generators/engine/templates/README b/vendor/plugins/engines/generators/engine/templates/README
deleted file mode 100755 (executable)
index 4d2371c..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-------------------[ once you've read this, delete it ]---------------------
-
-ENGINE DEVELOPERS - HEED THIS!
-
-This is a sample README file to guide your users when they are installing what is undoubtedly going to be the finest piece of code they ever got their hands on. Lucky them, but alas they are often foolish, and so this is where you can guide them with the metaphorical beating of twigs. Or just a numbered series of instructions.
-
-ANYWAY - you will almost certainly need to tailor this to your specific engine. For instance, your users will probably only need to include modules into the ApplicationController and ApplicationHelper if your engine defines methods to be usable by controllers and views external to your engine.
-
-If you engine does not rely on any database tables, you will probably not need migrations either.
-
-You are also under no obligation to use the 'config' method for setting options within your modules. Documentation which explains the purpose of the 'config' method is available as part of the Engines plugin itself.
-
-Please check the engine development information on the Rails Engines wiki for more information about what to do now:
-  
-  http://rails-engines.rubyforge.org/wiki/wiki.pl?DevelopingAnEngine
-
------------------------[ remember to delete me! ]--------------------------
-
-= <%= engine_class_name %>
-
-<%= engine_class_name %> is a ...
-
-This software package is developed using the Engines plugin. To find out more about how to use engines in general, go to http://rails-engines.rubyforge.org for general documentation about the Engines mechanism.
-
-== Installation
-
-1. Create your Rails application, set up your databases, grab the Engines plugin and the <%= engine_class_name %>, and install them.
-
-2. Install the <%= engine_class_name %> into your vendor/plugins directory
-
-3. Modify your Engines.start call in config/environment.rb
-
-    Engines.start :<%= engine_start_name %> # or :<%= engine_underscored_name %>
-
-4. Edit your application.rb file so it looks something like the following:
-
-    class ApplicationController < ActionController::Base
-      include <%= engine_class_name %>
-    end
-
-5. Edit your application_helper.rb file:
-
-    module ApplicationHelper
-      include <%= engine_class_name %>
-    end
-
-6. Perform any configuration you might need. You'll probably want to set these values in environment.rb (before the call to Engines.start):
-
-    module <%= engine_class_name %>
-      config :some_option, "some_value"
-    end
-
-7. Initialize the database tables. You can either use the engine migrations by calling:
-
-    rake engine_migrate
-
-  to move all engines to their latest versions, or
-
-    rake engine_migrate ENGINE=<%= engine_start_name %>
-
-  to migrate only this engine.
-
-8. The <%= engine_class_name %> provides a default stylesheet and a small javascript helper file, so you'll probably want to include the former and almost certainly the latter in your application's layout. Add the following lines:
-
-      <%%= engine_stylesheet "<%=engine_start_name%>_engine" %>
-      <%%= engine_javascript "<%=engine_start_name%>_engine" %>
-
-== Configuration
-
-A number of configuration parameters are available to allow to you control
-how the data is stored, should you be unhappy with the defaults. These are
-outlined below. 
-
-  module <%= engine_class_name %>
-    config :some_option, "some_value"
-  end
-
-=== Configuration Options
-+some_option+:: This option will set some_value 
-
-== Usage
-How to use this engine
-
-== License
-<%= license %>
diff --git a/vendor/plugins/engines/generators/engine/templates/init_engine.erb b/vendor/plugins/engines/generators/engine/templates/init_engine.erb
deleted file mode 100755 (executable)
index 42dda69..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<%= license %>
-
-module <%= engine_class_name %>
-  module VERSION
-    Major = 0 # change implies compatibility breaking with previous versions
-    Minor = 1 # change implies backwards-compatible change to API
-    Release = 0 # incremented with bug-fixes, updates, etc.
-  end
-end
-
-Engines.current.version = <%= engine_class_name %>::VERSION
-
-# load up all the required files we need...
-require '<%= engine_underscored_name %>'
-
diff --git a/vendor/plugins/engines/generators/engine/templates/install.erb b/vendor/plugins/engines/generators/engine/templates/install.erb
deleted file mode 100755 (executable)
index 523280c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# Install the engines plugin if it has been already
-unless File.exist?(File.dirname(__FILE__) + "/../engines")
-  Commands::Plugin.parse!(['install', 'http://svn.rails-engines.org/plugins/engines']) 
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/generators/engine/templates/lib/engine.erb b/vendor/plugins/engines/generators/engine/templates/lib/engine.erb
deleted file mode 100755 (executable)
index 80a4d51..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<%= license %>
-
-#require '<%= engine_underscored_name %>/additional_files'
-
-module <%= engine_class_name %>
-end
diff --git a/vendor/plugins/engines/generators/engine/templates/licenses/GPL b/vendor/plugins/engines/generators/engine/templates/licenses/GPL
deleted file mode 100755 (executable)
index ed90491..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) <%= Time.now.strftime("%Y") %> <%= author %>
-
-The GNU General Public License (GPL)
-Version 2, June 1991
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
diff --git a/vendor/plugins/engines/generators/engine/templates/licenses/LGPL b/vendor/plugins/engines/generators/engine/templates/licenses/LGPL
deleted file mode 100755 (executable)
index 0aec8f8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) <%= Time.now.strftime("%Y") %> <%= author %>
-
-GNU Lesser General Public License
-Version 2.1, February 1999
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
diff --git a/vendor/plugins/engines/generators/engine/templates/licenses/MIT b/vendor/plugins/engines/generators/engine/templates/licenses/MIT
deleted file mode 100755 (executable)
index 4b82fbf..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) <%= Time.now.strftime("%Y") %> <%= author %>
-
-The MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/vendor/plugins/engines/generators/engine/templates/licenses/None b/vendor/plugins/engines/generators/engine/templates/licenses/None
deleted file mode 100755 (executable)
index 6452ac0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Copyright (c) <%= Time.now.strftime("%Y") %> <%= author %>
diff --git a/vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js b/vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css b/vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/vendor/plugins/engines/generators/engine/templates/tasks/engine.rake b/vendor/plugins/engines/generators/engine/templates/tasks/engine.rake
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/vendor/plugins/engines/generators/engine/templates/test/test_helper.erb b/vendor/plugins/engines/generators/engine/templates/test/test_helper.erb
deleted file mode 100755 (executable)
index cf357be..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper') # the default rails helper
-
-# ensure that the Engines testing enhancements are loaded.
-require File.join(Engines.config(:root), "engines", "lib", "engines", "testing_extensions")
-
-# Ensure that the code mixing and view loading from the application is disabled
-Engines.disable_app_views_loading = true
-Engines.disable_app_code_mixing = true
-
-# force these config values
-module <%= engine_class_name %>
-#  config :some_option, "some_value"
-end
-
-# set up the fixtures location
-Test::Unit::TestCase.fixture_path = File.dirname(__FILE__)  + "/fixtures/"
-$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
\ No newline at end of file
diff --git a/vendor/plugins/engines/init.rb b/vendor/plugins/engines/init.rb
deleted file mode 100755 (executable)
index bce1a88..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#--
-# Copyright (c) 2006 James Adam
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-#
-#
-# = IN OTHER WORDS:
-#
-# You are free to use this software as you please, but if it breaks you'd
-# best not come a'cryin...
-#++
-
-# Load the engines & bundles extensions
-require 'engines'
-require 'bundles'
-
-module ::Engines::Version
-  Major = 1 # change implies compatibility breaking with previous versions
-  Minor = 1 # change implies backwards-compatible change to API
-  Release = 4 # incremented with bug-fixes, updates, etc.
-end
-
-#--
-# Create the Engines directory if it isn't present
-#++
-if !File.exist?(Engines.config(:root))
-  Engines.log.debug "Creating engines directory in /vendor"
-  FileUtils.mkdir_p(Engines.config(:root))
-end
-
-# Keep a hold of the Rails Configuration object
-Engines.rails_config = config
-
-# Initialize the routing (controller_paths)
-Engines.initialize_routing
\ No newline at end of file
diff --git a/vendor/plugins/engines/lib/bundles.rb b/vendor/plugins/engines/lib/bundles.rb
deleted file mode 100755 (executable)
index ce045f8..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-require 'bundles/require_resource'
-
-# The 'require_bundle' method is used in views to declare that certain stylesheets and javascripts should
-# be included by the 'resource_tags' (used in the layout) for the view to function properly.
-module Bundles
-  def require_bundle(name, *args)
-    method = "bundle_#{name}"
-    send(method, *args)
-  end
-  
-  def require_bundles(*names)
-    names.each { |name| require_bundle(name) }
-  end
-end
-
-ActionView::Base.send(:include, Bundles)
-
-# Registers a module within the Bundles module by renaming the module's 'bundle' method (so it doesn't
-# clash with other methods named 'bundle') and by including any Controller or Helper modules within
-# their respective Rails base classes.
-#
-# For example, if you have a module such as
-#   module Bundles::Calendar; end
-#
-# then within that Calendar module there *must* be a method named "bundle" which groups the
-# bundle's resources together.  Example:
-#   module Bundles::Calendar
-#     def bundle
-#       require_relative_to Engines.current.public_dir do
-#         require_stylesheet "/stylesheets/calendar.css"
-#         require_javascript "/javascripts/calendar.js"
-#       end
-#     end
-#   end
-#
-# You may optionally define a Controller or Helper sub-module if you need any methods available to
-# the applications controllers or views.  Example:
-#
-#   module Bundles::Calendar
-#     module Helper
-#       def calendar_date_select(*args
-#         # ... output some HTML
-#       end
-#     end
-#   end
-#
-# The calendar_date_select method will now be available within the scope of the app's views because the
-# register_bundle method will inject the Helper module's methods in to ActionView::Base for you.
-#
-# Similarly, you can make methods available to controllers by adding a Controller module.
-def register_bundle(name)
-  require "bundles/#{name}"
-  
-  # Rename the generic 'bundle' method in to something that doesn't conflict with
-  # the other module method names.
-  bundle_module = Bundles.const_get(name.to_s.camelize)
-  bundle_module.module_eval "alias bundle_#{name} bundle"
-  bundle_module.send :undef_method, :bundle
-
-  # Then include the bundle module in to the base module, so that the methods will
-  # be available inside ActionView::Base
-  ActionView::Base.send(:include, bundle_module)
-
-  # Check for optional Controller module
-  if bundle_module.const_defined? 'Controller'
-    controller_addon = bundle_module.const_get('Controller')
-    RAILS_DEFAULT_LOGGER.debug "Including #{name} bundle's Controller module"
-    ActionController::Base.send(:include, controller_addon)
-  end
-
-  # Check for optional Helper module
-  if bundle_module.const_defined? 'Helper'
-    helper_addon = bundle_module.const_get('Helper')
-    RAILS_DEFAULT_LOGGER.debug "Including #{name} bundle's Helper module"
-    ActionView::Base.send(:include, helper_addon)
-  end
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/lib/bundles/require_resource.rb b/vendor/plugins/engines/lib/bundles/require_resource.rb
deleted file mode 100755 (executable)
index 3469c63..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-# RequireResource v.1.4 by Duane Johnson
-#
-# Makes inclusion of javascript and stylesheet resources easier via automatic or explicit
-# calls.  e.g. require_javascript 'popup' is an explicit call.
-#
-# The simplest way to make use of this functionality is to add
-#   <%= resource_tags %>
-# to your layout (usually in the <head></head> section).  This will automatically add
-# bundle support to your application, as well as enable simple javascript and stylesheet
-# dependencies for your views.
-#
-# Note that this can easily be turned in to a helper on its own.
-module RequireResource
-  mattr_accessor :path_prefix
-
-  # Write out all javascripts & stylesheets, including default javascripts (unless :defaults => false)
-  def resource_tags(options = {})
-    options = {:auto => true, :defaults => true}.update(options)
-    require_defaults if options[:defaults]
-    stylesheet_auto_link_tags(:auto => options[:auto]) +
-    javascript_auto_include_tags(:auto => options[:auto])
-  end
-  
-  # Write out the <link> tags themselves based on the array of stylesheets to be included
-  def stylesheet_auto_link_tags(options = {})
-    options = {:auto => true}.update(options)
-    ensure_resource_is_initialized(:stylesheet)
-    autorequire(:stylesheet) if options[:auto]
-    @stylesheets.uniq.inject("") do |buffer, css|
-      buffer << stylesheet_link_tag(css) + "\n    "
-    end
-  end
-
-  # Write out the <script> tags themselves based on the array of javascripts to be included
-  def javascript_auto_include_tags(options = {})
-    options = {:auto => true}.update(options)
-    ensure_resource_is_initialized(:javascript)
-    autorequire(:javascript) if options[:auto]
-    @javascripts.uniq.inject("") do |buffer, js|
-      buffer << javascript_include_tag(js) + "\n    "
-    end
-  end
-
-  # Bundle the defaults together for easy inclusion
-  def require_defaults
-    require_javascript(:prototype)
-    require_javascript(:controls)
-    require_javascript(:effects)
-    require_javascript(:dragdrop)
-  end
-  
-  # Adds a javascript to the array of javascripts that will be included in the layout by
-  # either your call to 'javascript_auto_include_tags' or 'resource_tags'.
-  def require_javascript(*scripts)
-    scripts.each do |script|
-      require_resource(:javascript, RequireResource.path_prefix.to_s + script.to_s)
-    end
-  end
-
-  # Adds a stylesheet to the array of stylesheets that will be included in the layout by
-  # either your call to 'stylesheet_auto_link_tags' or 'resource_tags'.
-  def require_stylesheet(*sheets)
-    sheets.each do |sheet|
-      require_resource(:stylesheet, RequireResource.path_prefix.to_s + sheet.to_s)
-    end
-  end
-  
-  # Changes the RequireResource.path_prefix within the scope of a block.  This is
-  # particularly useful when requiring several resources within a directory.  For example,
-  # bundles can take advantage of this by calling
-  #   require_relative_to Engines.current.public_dir do
-  #     require_javascript '...'
-  #     require_stylesheet '...'
-  #     # ...
-  #   end
-  def require_relative_to(path)
-    former_prefix = RequireResource.path_prefix
-    RequireResource.path_prefix = path
-    yield
-    RequireResource.path_prefix = former_prefix
-  end
-  
-  protected
-    # Adds resources such as stylesheet or javascript files to the corresponding array of
-    # resources that will be 'required' by the layout. The +resource_type+ is either
-    # :javascript or :stylesheet. The +extension+ is optional, and should normally correspond
-    # with the resource type, e.g. 'css' for :stylesheet and 'js' for :javascript.
-    def autorequire(resource_type, extension = nil)
-      extensions = {:stylesheet => 'css', :javascript => 'js'}
-      extension ||= extensions[resource_type]
-      candidates = []
-      class_iterator = controller.class
-      resource_path = "#{RAILS_ROOT}/public/#{resource_type.to_s.pluralize}/" 
-
-      while ![ActionController::Base].include? class_iterator
-        controller_path = class_iterator.to_s.underscore.sub('controllers/', '').sub('_controller', '')
-        candidates |= [ "#{controller_path}", "#{controller_path}/#{controller.action_name}" ]
-        class_iterator = class_iterator.superclass
-      end
-      
-      for candidate in candidates
-        if FileTest.exist?("#{resource_path}/#{candidate}.#{extension}")
-          require_resource(resource_type, candidate)
-        end
-      end
-    end
-
-    # Adds a resource (e.g. a javascript) to the appropriate array (e.g. @javascripts)
-    # ONLY if the resource is not already included.
-    def require_resource(type, name)
-      variable = type.to_s.pluralize
-      new_resource_array = (instance_variable_get("@#{variable}") || []) | [name.to_s]
-      instance_variable_set("@#{variable}", new_resource_array)
-    end
-
-    # Ensures that a resource array (e.g. @javascripts) is not nil--uses [] if so
-    def ensure_resource_is_initialized(type)
-      variable = type.to_s.pluralize
-      new_resource_array = (instance_variable_get("@#{variable}") || [])
-      instance_variable_set("@#{variable}", new_resource_array)      
-    end
-end
-
-ActionView::Base.send(:include, RequireResource)
diff --git a/vendor/plugins/engines/lib/engines.rb b/vendor/plugins/engines/lib/engines.rb
deleted file mode 100755 (executable)
index 749ccb2..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-require 'logger'
-
-# We need to know the version of Rails that we are running before we
-# can override any of the dependency stuff, since Rails' own behaviour
-# has changed over the various releases. We need to explicily make sure
-# that the Rails::VERSION constant is loaded, because such things could
-# not automatically be achieved prior to 1.1, and the location of the
-# file moved in 1.1.1!
-def load_rails_version
-  # At this point, we can't even rely on RAILS_ROOT existing, so we have to figure
-  # the path to RAILS_ROOT/vendor/rails manually
-  rails_base = File.expand_path(
-    File.join(File.dirname(__FILE__), # RAILS_ROOT/vendor/plugins/engines/lib
-    '..', # RAILS_ROOT/vendor/plugins/engines
-    '..', # RAILS_ROOT/vendor/plugins
-    '..', # RAILS_ROOT/vendor
-    'rails', 'railties', 'lib')) # RAILS_ROOT/vendor/rails/railties/lib
-  begin
-    load File.join(rails_base, 'rails', 'version.rb')
-    #puts 'loaded 1.1.1+ from vendor: ' + File.join(rails_base, 'rails', 'version.rb')
-  rescue MissingSourceFile # this means they DON'T have Rails 1.1.1 or later installed in vendor
-    begin
-      load File.join(rails_base, 'rails_version.rb')
-      #puts 'loaded 1.1.0- from vendor: ' + File.join(rails_base, 'rails_version.rb')
-    rescue MissingSourceFile # this means they DON'T have Rails 1.1.0 or previous installed in vendor
-      begin
-        # try and load version information for Rails 1.1.1 or later from the $LOAD_PATH
-        require 'rails/version'
-        #puts 'required 1.1.1+ from load path'
-      rescue LoadError
-        # try and load version information for Rails 1.1.0 or previous from the $LOAD_PATH
-        require 'rails_version'
-        #puts 'required 1.1.0- from load path'
-      end
-    end
-  end
-end
-
-# Actually perform the load
-load_rails_version
-#puts "Detected Rails version: #{Rails::VERSION::STRING}"
-
-require 'engines/ruby_extensions'
-# ... further files are required at the bottom of this file
-
-# Holds the Rails Engine loading logic and default constants
-module Engines
-
-  class << self
-    # Return the version string for this plugin
-    def version
-      "#{Version::Major}.#{Version::Minor}.#{Version::Release}"
-    end
-    
-    # For holding the rails configuration object
-    attr_accessor :rails_config
-    
-    # A flag to stop searching for views in the application
-    attr_accessor :disable_app_views_loading
-    
-    # A flag to stop code being mixed in from the application
-    attr_accessor :disable_app_code_mixing
-  end
-
-  # The DummyLogger is a class which might pass through to a real Logger
-  # if one is assigned. However, it can gracefully swallow any logging calls
-  # if there is now Logger assigned.
-  class LoggerWrapper
-    def initialize(logger=nil)
-      set_logger(logger)
-    end
-    # Assign the 'real' Logger instance that this dummy instance wraps around.
-    def set_logger(logger)
-      @logger = logger
-    end
-    # log using the appropriate method if we have a logger
-    # if we dont' have a logger, ignore completely.
-    def method_missing(name, *args)
-      if @logger && @logger.respond_to?(name)
-        @logger.send(name, *args)
-      end
-    end
-  end
-
-  LOGGER = Engines::LoggerWrapper.new
-
-  class << self
-    # Create a new Logger instance for Engines, with the given outputter and level    
-    def create_logger(outputter=STDOUT, level=Logger::INFO)
-      LOGGER.set_logger(Logger.new(outputter, level))
-    end
-    # Sets the Logger instance that Engines will use to send logging information to
-    def set_logger(logger)
-      Engines::LOGGER.set_logger(logger) # TODO: no need for Engines:: part
-    end
-    # Retrieves the current Logger instance
-    def log
-      Engines::LOGGER # TODO: no need for Engines:: part
-    end
-    alias :logger :log
-  end
-  
-  # An array of active engines. This should be accessed via the Engines.active method.
-  ActiveEngines = []
-  
-  # The root directory for engines
-  config :root, File.join(RAILS_ROOT, "vendor", "plugins")
-  
-  # The name of the public folder under which engine files are copied
-  config :public_dir, "engine_files"
-  
-  class << self
-  
-    # Initializes a Rails Engine by loading the engine's init.rb file and
-    # ensuring that any engine controllers are added to the load path.
-    # This will also copy any files in a directory named 'public'
-    # into the public webserver directory. Example usage:
-    #
-    #   Engines.start :login
-    #   Engines.start :login_engine  # equivalent
-    #
-    # A list of engine names can be specified:
-    #
-    #   Engines.start :login, :user, :wiki
-    #
-    # The engines will be loaded in the order given.
-    # If no engine names are given, all engines will be started.
-    #
-    # Options can include:
-    # * :copy_files => true | false
-    #
-    # Note that if a list of engines is given, the options will apply to ALL engines.
-    def start(*args)
-      
-      options = (args.last.is_a? Hash) ? args.pop : {}
-      
-      if args.empty?
-        start_all
-      else
-        args.each do |engine_name|
-          start_engine(engine_name, options)
-        end
-      end
-    end
-
-    # Starts all available engines. Plugins are considered engines if they
-    # include an init_engine.rb file, or they are named <something>_engine.
-    def start_all
-      plugins = Dir[File.join(config(:root), "*")]
-      Engines.log.debug "considering plugins: #{plugins.inspect}"
-      plugins.each { |plugin|
-        engine_name = File.basename(plugin)
-        if File.exist?(File.join(plugin, "init_engine.rb")) || # if the directory contains init_engine.rb
-          (engine_name =~ /_engine$/) || # or it engines in '_engines'
-          (engine_name =~ /_bundle$/)    # or even ends in '_bundle'
-          
-          start(engine_name) # start the engine...
-        
-        end
-      }
-    end
-
-    # Initialize the routing controller paths. 
-    def initialize_routing
-      # See lib/engines/routing_extensions.rb for more information.
-      ActionController::Routing.controller_paths = Engines.rails_config.controller_paths
-    end
-
-    def start_engine(engine_name, options={})
-      
-      # Create a new Engine and put this engine at the front of the ActiveEngines list
-      current_engine = Engine.new(engine_name)
-      Engines.active.unshift current_engine
-      Engines.log.info "Starting engine '#{current_engine.name}' from '#{File.expand_path(current_engine.root)}'"
-
-      # add the code directories of this engine to the load path
-      add_engine_to_load_path(current_engine)
-
-      # add the controller & component path to the Dependency system
-      engine_controllers = File.join(current_engine.root, 'app', 'controllers')
-      engine_components = File.join(current_engine.root, 'components')
-
-
-      # This mechanism is no longer required in Rails trunk
-      if Rails::VERSION::STRING =~ /^1.0/ && !Engines.config(:edge)
-        Controllers.add_path(engine_controllers) if File.exist?(engine_controllers)
-        Controllers.add_path(engine_components) if File.exist?(engine_components)
-      else      
-        ActionController::Routing.controller_paths << engine_controllers
-        ActionController::Routing.controller_paths << engine_components
-      end
-        
-      # copy the files unless indicated otherwise
-      if options[:copy_files] != false
-        current_engine.mirror_engine_files
-      end
-
-      # load the engine's init.rb file
-      startup_file = File.join(current_engine.root, "init_engine.rb")
-      if File.exist?(startup_file)
-        eval(IO.read(startup_file), binding, startup_file)
-        # possibly use require_dependency? Hmm.
-      else
-        Engines.log.debug "No init_engines.rb file found for engine '#{current_engine.name}'..."
-      end
-    end
-
-    # Adds all directories in the /app and /lib directories within the engine
-    # to the load path
-    def add_engine_to_load_path(engine)
-      
-      # remove the lib directory added by load_plugin, and place it in the corrent
-      # location *after* the application/lib. This can be removed when 
-      # http://dev.rubyonrails.org/ticket/2910 is fixed.
-      app_lib_index = $LOAD_PATH.index(File.join(RAILS_ROOT, "lib"))
-      engine_lib = File.join(engine.root, "lib")
-      if app_lib_index
-        $LOAD_PATH.delete(engine_lib)
-        $LOAD_PATH.insert(app_lib_index+1, engine_lib)
-      end
-      
-      # Add ALL paths under the engine root to the load path
-      app_dirs = %w(controllers helpers models).collect { |d|
-        File.join(engine.root, 'app', d)
-      }
-      other_dirs = %w(components lib).collect { |d| 
-        File.join(engine.root, d)
-      }
-      load_paths  = (app_dirs + other_dirs).select { |d| File.directory?(d) }
-
-      # Remove other engines from the $LOAD_PATH by matching against the engine.root values
-      # in ActiveEngines. Store the removed engines in the order they came off.
-      
-      old_plugin_paths = []
-      # assumes that all engines are at the bottom of the $LOAD_PATH
-      while (File.expand_path($LOAD_PATH.last).index(File.expand_path(Engines.config(:root))) == 0) do
-        old_plugin_paths.unshift($LOAD_PATH.pop)
-      end
-
-
-      # add these LAST on the load path.
-      load_paths.reverse.each { |dir| 
-        if File.directory?(dir)
-          Engines.log.debug "adding #{File.expand_path(dir)} to the load path"
-          #$LOAD_PATH.push(File.expand_path(dir))
-          $LOAD_PATH.push dir
-        end
-      }
-      
-      # Add the other engines back onto the bottom of the $LOAD_PATH. Put them back on in
-      # the same order.
-      $LOAD_PATH.push(*old_plugin_paths)
-      $LOAD_PATH.uniq!
-    end
-
-    # Returns the directory in which all engine public assets are mirrored.
-    def public_engine_dir
-      File.expand_path(File.join(RAILS_ROOT, "public", Engines.config(:public_dir)))
-    end
-  
-    # create the /public/engine_files directory if it doesn't exist
-    def create_base_public_directory
-      if !File.exists?(public_engine_dir)
-        # create the public/engines directory, with a warning message in it.
-        Engines.log.debug "Creating public engine files directory '#{public_engine_dir}'"
-        FileUtils.mkdir(public_engine_dir)
-        File.open(File.join(public_engine_dir, "README"), "w") do |f|
-          f.puts <<EOS
-Files in this directory are automatically generated from your Rails Engines.
-They are copied from the 'public' directories of each engine into this directory
-each time Rails starts (server, console... any time 'start_engine' is called).
-Any edits you make will NOT persist across the next server restart; instead you
-should edit the files within the <engine_name>/public/ directory itself.
-EOS
-        end
-      end
-    end
-    
-    # Returns the Engine object for the specified engine, e.g.:
-    #    Engines.get(:login)  
-    def get(name)
-      active.find { |e| e.name == name.to_s || e.name == "#{name}_engine" }
-    end
-    alias_method :[], :get
-    
-    # Returns the Engine object for the current engine, i.e. the engine
-    # in which the currently executing code lies.
-    def current
-      current_file = caller[0]
-      active.find do |engine|
-        File.expand_path(current_file).index(File.expand_path(engine.root)) == 0
-      end
-    end
-    
-    # Returns an array of active engines
-    def active
-      ActiveEngines
-    end
-    
-    # Pass a block to perform an operation on each engine. You may pass an argument
-    # to determine the order:
-    # 
-    # * :load_order - in the order they were loaded (i.e. lower precidence engines first).
-    # * :precidence_order - highest precidence order (i.e. last loaded) first
-    def each(ordering=:precidence_order, &block)
-      engines = (ordering == :load_order) ? active.reverse : active
-      engines.each { |e| yield e }
-    end
-  end 
-end
-
-# A simple class for holding information about loaded engines
-class Engine
-  
-  # Returns the base path of this engine
-  attr_accessor :root
-  
-  # Returns the name of this engine
-  attr_reader :name
-  
-  # An attribute for holding the current version of this engine. There are three
-  # ways of providing an engine version. The simplest is using a string:
-  #
-  #   Engines.current.version = "1.0.7"
-  #
-  #¬†Alternatively you can set it to a module which contains Major, Minor and Release
-  # constants:
-  #
-  #   module LoginEngine::Version
-  #     Major = 1; Minor = 0; Release = 6;
-  #   end
-  #   Engines.current.version = LoginEngine::Version
-  #
-  # Finally, you can set it to your own Proc, if you need something really fancy:
-  #
-  #   Engines.current.version = Proc.new { File.open('VERSION', 'r').readlines[0] }
-  # 
-  attr_writer :version
-  
-  # Engine developers can store any information they like in here.
-  attr_writer :info
-  
-  # Creates a new object holding information about an Engine.
-  def initialize(name)
-
-    @root = ''
-    suffixes = ['', '_engine', '_bundle']
-    while !File.exist?(@root) && !suffixes.empty?
-      suffix = suffixes.shift
-      @root = File.join(Engines.config(:root), name.to_s + suffix)
-    end
-
-    if !File.exist?(@root)
-      raise "Cannot find the engine '#{name}' in either /vendor/plugins/#{name}, " +
-        "/vendor/plugins/#{name}_engine or /vendor/plugins/#{name}_bundle."
-    end      
-    
-    @name = File.basename(@root)
-  end
-    
-  # Returns the version string of this engine
-  def version
-    case @version
-    when Module
-      "#{@version::Major}.#{@version::Minor}.#{@version::Release}"
-    when Proc         # not sure about this
-      @version.call
-    when NilClass
-      'unknown'
-    else
-      @version
-    end
-  end
-  
-  # Returns a string describing this engine
-  def info
-    @info || '(none)'
-  end
-    
-  # Returns a string representation of this engine
-  def to_s
-    "Engine<'#{@name}' [#{version}]:#{root.gsub(RAILS_ROOT, '')}>"
-  end
-  
-  # return the path to this Engine's public files (with a leading '/' for use in URIs)
-  def public_dir
-    File.join("/", Engines.config(:public_dir), name)
-  end
-  
-  # Replicates the subdirectories under the engine's /public directory into
-  # the corresponding public directory.
-  def mirror_engine_files
-    
-    begin
-      Engines.create_base_public_directory
-  
-      source = File.join(root, "public")
-      Engines.log.debug "Attempting to copy public engine files from '#{source}'"
-  
-      # if there is no public directory, just return after this file
-      return if !File.exist?(source)
-
-      source_files = Dir[source + "/**/*"]
-      source_dirs = source_files.select { |d| File.directory?(d) }
-      source_files -= source_dirs  
-    
-      Engines.log.debug "source dirs: #{source_dirs.inspect}"
-
-      # Create the engine_files/<something>_engine dir if it doesn't exist
-      new_engine_dir = File.join(RAILS_ROOT, "public", public_dir)
-      if !File.exists?(new_engine_dir)
-        # Create <something>_engine dir with a message
-        Engines.log.debug "Creating #{public_dir} public dir"
-        FileUtils.mkdir_p(new_engine_dir)
-      end
-
-      # create all the directories, transforming the old path into the new path
-      source_dirs.uniq.each { |dir|
-        begin        
-          # strip out the base path and add the result to the public path, i.e. replace 
-          #   ../script/../vendor/plugins/engine_name/public/javascript
-          # with
-          #   engine_name/javascript
-          #
-          relative_dir = dir.gsub(File.join(root, "public"), name)
-          target_dir = File.join(Engines.public_engine_dir, relative_dir)
-          unless File.exist?(target_dir)
-            Engines.log.debug "creating directory '#{target_dir}'"
-            FileUtils.mkdir_p(target_dir)
-          end
-        rescue Exception => e
-          raise "Could not create directory #{target_dir}: \n" + e
-        end
-      }
-
-      # copy all the files, transforming the old path into the new path
-      source_files.uniq.each { |file|
-        begin
-          # change the path from the ENGINE ROOT to the public directory root for this engine
-          target = file.gsub(File.join(root, "public"), 
-                             File.join(Engines.public_engine_dir, name))
-          unless File.exist?(target) && FileUtils.identical?(file, target)
-            Engines.log.debug "copying file '#{file}' to '#{target}'"
-            FileUtils.cp(file, target)
-          end 
-        rescue Exception => e
-          raise "Could not copy #{file} to #{target}: \n" + e 
-        end
-      }
-    rescue Exception => e
-      Engines.log.warn "WARNING: Couldn't create the engine public file structure for engine '#{name}'; Error follows:"
-      Engines.log.warn e
-    end
-  end  
-end
-
-
-# These files must be required after the Engines module has been defined.
-require 'engines/dependencies_extensions'
-require 'engines/routing_extensions'
-require 'engines/action_view_extensions'
-require 'engines/action_mailer_extensions'
-require 'engines/migration_extensions'
-require 'engines/active_record_extensions'
-
-# only load the testing extensions if we are in the test environment
-require 'engines/testing_extensions' if %w(test).include?(RAILS_ENV)
diff --git a/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb b/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb
deleted file mode 100755 (executable)
index 839cd40..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-# Overriding ActionMailer to teach it about Engines...
-module ActionMailer
-  class Base
-
-    # Initialize the mailer via the given +method_name+. The body will be
-    # rendered and a new TMail::Mail object created.
-    def create!(method_name, *parameters) #:nodoc:
-      initialize_defaults(method_name)
-      send(method_name, *parameters)
-
-
-      # If an explicit, textual body has not been set, we check assumptions.
-      unless String === @body
-        # First, we look to see if there are any likely templates that match,
-        # which include the content-type in their file name (i.e.,
-        # "the_template_file.text.html.rhtml", etc.). Only do this if parts
-        # have not already been specified manually.
-
-        templates = get_all_templates_for_action(@template)
-        
-        #RAILS_DEFAULT_LOGGER.debug "template: #{@template}; templates: #{templates.inspect}"
-
-        if @parts.empty?
-          
-          # /app/views/<mailer object name> / <action>.something.rhtml
-          
-          #templates = Dir.glob("#{template_path}/#{@template}.*")
-                    
-          # this loop expects an array of paths to actual template files which match
-          # the given action name
-          templates.each do |path|
-            # TODO: don't hardcode rhtml|rxml
-            basename = File.basename(path)
-            next unless md = /^([^\.]+)\.([^\.]+\.[^\+]+)\.(rhtml|rxml)$/.match(basename)
-            
-            template_name = basename
-            content_type = md.captures[1].gsub('.', '/')
-
-            @parts << Part.new(:content_type => content_type,            
-              :disposition => "inline", :charset => charset,
-              :body => render_message(template_name, @body))
-          end
-          unless @parts.empty?
-            @content_type = "multipart/alternative"
-            @parts = sort_parts(@parts, @implicit_parts_order)
-          end
-        end
-
-        # Then, if there were such templates, we check to see if we ought to
-        # also render a "normal" template (without the content type). If a
-        # normal template exists (or if there were no implicit parts) we render
-        # it.
-        template_exists = @parts.empty?
-        # template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 }
-        template_exists ||= templates.any? do |i|
-          arr = File.basename(i).split(".")
-          (arr.length == 2) && (arr[0] == @template) 
-        end
-        @body = render_message(@template, @body) if template_exists
-
-        # Finally, if there are other message parts and a textual body exists,
-        # we shift it onto the front of the parts and set the body to nil (so
-        # that create_mail doesn't try to render it in addition to the parts).
-        if !@parts.empty? && String === @body
-          @parts.unshift Part.new(:charset => charset, :body => @body)
-          @body = nil
-        end
-      end
-
-      # If this is a multipart e-mail add the mime_version if it is not
-      # already set.
-      @mime_version ||= "1.0" if !@parts.empty?
-
-      # build the mail object itself
-      @mail = create_mail
-    end
-
-    private
-
-
-      # JGA - Modified to pass the method name to initialize_template_class
-      def render(opts)
-        body = opts.delete(:body)
-        initialize_template_class(body, opts[:file]).render(opts)
-      end
-
-      
-      # Return all ActionView template paths from the app and all Engines
-      def template_paths
-        paths = [template_path]
-        Engines.each { |engine|
-          # add a path for every engine if one exists.
-          engine_template_path = File.join(engine.root, "app", "views", mailer_name)
-          paths << engine_template_path if File.exists?(engine_template_path)
-        }
-        paths
-      end
-
-      # Returns a list of all template paths in the app and Engines
-      # which contain templates that might be used for the given action
-      def get_all_templates_for_action(action)
-        # can we trust uniq! to do this? i'm not sure...
-        templates = []
-        seen_names = []
-        template_paths.each { |path|
-          all_templates_for_path = Dir.glob(File.join(path, "#{action}*"))
-          all_templates_for_path.each { |template|
-            name = File.basename(template)
-            if !seen_names.include?(name)
-              seen_names << name
-              templates << template
-            end
-          }
-        }
-        templates
-      end
-
-      # Returns the first path to the given template in our
-      # app/Engine 'chain'.
-      def find_template_root_for(template)
-        all_paths = get_all_templates_for_action(template)
-        if all_paths.empty?
-          return template_path
-        else
-          return File.dirname(all_paths[0])
-        end
-      end
-
-      # JGA - changed here to include the method name that we
-      # are interested in, so that we can re-locate the proper
-      # template root
-      def initialize_template_class(assigns, method_name)
-        engine_template = find_template_root_for(method_name)
-        action_view_class = Class.new(ActionView::Base).send(:include, master_helper_module)
-        action_view_class.new(engine_template, assigns, self)        
-      end
-
-
-  end
-end
diff --git a/vendor/plugins/engines/lib/engines/action_view_extensions.rb b/vendor/plugins/engines/lib/engines/action_view_extensions.rb
deleted file mode 100755 (executable)
index bdfa11a..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-require 'fileutils'
-
-module ::ActionView
-  class Base
-    
-    private
-      def full_template_path(template_path, extension)
-
-        unless Engines.disable_app_views_loading
-          # If the template exists in the normal application directory,
-          # return that path
-          default_template = "#{@base_path}/#{template_path}.#{extension}"
-          return default_template if File.exist?(default_template)
-        end
-
-        # Otherwise, check in the engines to see if the template can be found there.
-        # Load this in order so that more recently started Engines will take priority.
-        Engines.each(:precidence_order) do |engine|
-          site_specific_path = File.join(engine.root, 'app', 'views',  
-                                         template_path.to_s + '.' + extension.to_s)
-          return site_specific_path if File.exist?(site_specific_path)
-        end
-
-        # If it cannot be found anywhere, return the default path, where the
-        # user *should* have put it.  
-        return "#{@base_path}/#{template_path}.#{extension}" 
-      end
-  end
-
-
-  # add methods to handle including javascripts and stylesheets
-  module Helpers
-    module AssetTagHelper
-      # Returns a stylesheet link tag to the named stylesheet(s) for the given
-      # engine. A stylesheet with the same name as the engine is included automatically.
-      # If other names are supplied, those stylesheets from within the same engine
-      # will be linked too.
-      #
-      #   engine_stylesheet "my_engine" =>
-      #   <link href="/engine_files/my_engine/stylesheets/my_engine.css" media="screen" rel="Stylesheet" type="text/css" />
-      #
-      #   engine_stylesheet "my_engine", "another_file", "one_more" =>
-      #   <link href="/engine_files/my_engine/stylesheets/my_engine.css" media="screen" rel="Stylesheet" type="text/css" />
-      #   <link href="/engine_files/my_engine/stylesheets/another_file.css" media="screen" rel="Stylesheet" type="text/css" />
-      #   <link href="/engine_files/my_engine/stylesheets/one_more.css" media="screen" rel="Stylesheet" type="text/css" />
-      #
-      # Any options supplied as a Hash as the last argument will be processed as in
-      # stylesheet_link_tag.
-      #
-      def engine_stylesheet(engine_name, *sources)
-        stylesheet_link_tag(*convert_public_sources(engine_name, :stylesheet, sources))
-      end
-
-      # Returns a javascript link tag to the named stylesheet(s) for the given
-      # engine. A javascript file with the same name as the engine is included automatically.
-      # If other names are supplied, those javascript from within the same engine
-      # will be linked too.
-      #
-      #   engine_javascript "my_engine" =>
-      #   <script type="text/javascript" src="/engine_files/my_engine/javascripts/my_engine.js"></script>
-      #
-      #   engine_javascript "my_engine", "another_file", "one_more" =>
-      #   <script type="text/javascript" src="/engine_files/my_engine/javascripts/my_engine.js"></script>
-      #   <script type="text/javascript" src="/engine_files/my_engine/javascripts/another_file.js"></script>
-      #   <script type="text/javascript" src="/engine_files/my_engine/javascripts/one_more.js"></script>
-      #
-      # Any options supplied as a Hash as the last argument will be processed as in
-      # javascript_include_tag.
-      #
-      def engine_javascript(engine_name, *sources)
-        javascript_include_tag(*convert_public_sources(engine_name, :javascript, sources))       
-      end
-
-      # Returns a image tag based on the parameters passed to it
-      # Required option is option[:engine] in order to correctly idenfity the correct engine location
-      #
-      #   engine_image 'rails-engines.png', :engine => 'my_engine', :alt => 'My Engine' =>
-      #   <img src="/engine_files/my_engine/images/rails-engines.png" alt="My Engine />
-      #
-      # Any options supplied as a Hash as the last argument will be processed as in
-      # image_tag.
-      #
-      def engine_image(src, options = {})
-       return if !src
-
-       image_src = engine_image_src(src, options)
-
-       options.delete(:engine)
-
-       image_tag(image_src, options)
-      end
-
-      # Alias for engine_image
-      def engine_image_tag(src, options = {})
-        engine_image(src, options)
-      end
-
-      # Returns a path to the image stored within the engine_files
-      # Required option is option[:engine] in order to correctly idenfity the correct engine location
-      #
-      #   engine_image_src 'rails-engines.png', :engine => 'my_engine' =>
-      #   "/engine_files/my_engine/images/rails-engines.png"
-      #
-      def engine_image_src(src, options = {})
-        File.join(Engines.get(options[:engine].to_sym).public_dir, 'images', src)
-      end
-      
-      private
-        # convert the engine public file sources into actual public paths
-        # type:
-        #   :stylesheet
-        #   :javascript
-        def convert_public_sources(engine_name, type, sources)
-          options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
-          new_sources = []
-        
-          case type
-            when :javascript
-              type_dir = "javascripts"
-              ext = "js"
-            when :stylesheet
-              type_dir = "stylesheets"
-              ext = "css"
-          end
-          
-          engine = Engines.get(engine_name)
-          
-          default = "#{engine.public_dir}/#{type_dir}/#{engine_name}"
-          if defined?(RAILS_ROOT) && File.exists?(File.join(RAILS_ROOT, "public", "#{default}.#{ext}"))
-            new_sources << default
-          end
-        
-          sources.each { |name| 
-            new_sources << "#{engine.public_dir}/#{type_dir}/#{name}"
-          }
-
-          new_sources << options         
-        end
-    end
-  end
-end
diff --git a/vendor/plugins/engines/lib/engines/active_record_extensions.rb b/vendor/plugins/engines/lib/engines/active_record_extensions.rb
deleted file mode 100755 (executable)
index 3345429..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-module ::ActiveRecord
-  class Base
-    class << self
-      
-      # NOTE: Currently the Migrations system will ALWAYS wrap given table names
-      # in the prefix/suffix, so any table name set via config(:table_name), for instnace
-      # will always get wrapped in the process of migration. For this reason, whatever
-      # value you give to the config will be wrapped when set_table_name is used in the
-      # model.
-      
-      def wrapped_table_name(name)
-        table_name_prefix + name + table_name_suffix
-      end
-    end
-  end
-end
-
-# Set ActiveRecord to ignore the engine_schema_info table by default
-unless Rails::VERSION::STRING =~ /^1\.0\./
-  ::ActiveRecord::SchemaDumper.ignore_tables << 'engine_schema_info'
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/lib/engines/dependencies_extensions.rb b/vendor/plugins/engines/lib/engines/dependencies_extensions.rb
deleted file mode 100755 (executable)
index 99be564..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-module ::Dependencies
-  
-  # we're going to intercept the require_or_load method; lets
-  # make an alias for the current method so we can use it as the basis
-  # for loading from engines.
-  alias :rails_pre_engines_require_or_load :require_or_load
-  
-  def require_or_load(file_name)
-    if Engines.config(:edge)
-      rails_edge_require_or_load(file_name)
-    
-    elsif Rails::VERSION::STRING =~ /^1.1/
-      # otherwise, assume we're on trunk (1.1 at the moment)
-      rails_1_1_require_or_load(file_name)
-    
-    elsif Rails::VERSION::STRING =~ /^1.0/
-      # use the old dependency load method
-      rails_1_0_require_or_load(file_name)
-    end
-  end
-  
-  def rails_edge_require_or_load(file_name)
-    rails_1_1_require_or_load(file_name)
-  end
-  
-  def rails_1_1_require_or_load(file_name)
-    Engines.log.debug("Engines 1.1 require_or_load: #{file_name}")
-
-    found = false
-
-    # try and load the engine code first
-    # can't use model, as there's nothing in the name to indicate that the file is a 'model' file
-    # rather than a library or anything else.
-    ['controller', 'helper'].each do |type| 
-      # if we recognise this type
-      # (this regexp splits out the module/filename from any instances of app/#{type}, so that
-      #  modules are still respected.)
-      if file_name =~ /^(.*app\/#{type}s\/)?(.*_#{type})(\.rb)?$/
-        # ... go through the active engines from first started to last, so that
-        # code with a high precidence (started later) will override lower precidence
-        # implementations
-        Engines.each(:load_order) do |engine|
-          engine_file_name = File.expand_path(File.join(engine.root, 'app', "#{type}s", $2))
-          #engine_file_name = $1 if engine_file_name =~ /^(.*)\.rb$/
-          Engines.log.debug("checking engine '#{engine.name}' for '#{engine_file_name}'")
-          if File.exist?("#{engine_file_name}.rb")
-            Engines.log.debug("==> loading from engine '#{engine.name}'")
-            rails_pre_engines_require_or_load(engine_file_name)
-            found = true
-          end
-        end
-      end 
-    end
-    
-    # finally, load any application-specific controller classes using the 'proper'
-    # rails load mechanism, EXCEPT when we're testing engines and could load this file
-    # from an engine
-    rails_pre_engines_require_or_load(file_name) unless Engines.disable_app_code_mixing && found
-  end
-  
-  def rails_1_0_require_or_load(file_name)
-    file_name = $1 if file_name =~ /^(.*)\.rb$/
-
-    Engines.log.debug "Engines 1.0.0 require_or_load '#{file_name}'"
-
-    # if the file_name ends in "_controller" or "_controller.rb", strip all
-    # path information out of it except for module context, and load it. Ditto
-    # for helpers.
-    found = if file_name =~ /_controller(.rb)?$/
-      require_engine_files(file_name, 'controller')
-    elsif file_name =~ /_helper(.rb)?$/ # any other files we can do this with?
-      require_engine_files(file_name, 'helper')
-    end
-    
-    # finally, load any application-specific controller classes using the 'proper'
-    # rails load mechanism, EXCEPT when we're testing engines and could load this file
-    # from an engine
-    Engines.log.debug("--> loading from application: '#{file_name}'")
-    rails_pre_engines_require_or_load(file_name) unless Engines.disable_app_code_mixing && found
-    Engines.log.debug("--> Done loading.")
-  end
-  
-  # Load the given file (which should be a path to be matched from the root of each
-  # engine) from all active engines which have that file.
-  # NOTE! this method automagically strips file_name up to and including the first
-  # instance of '/app/controller'. This should correspond to the app/controller folder
-  # under RAILS_ROOT. However, if you have your Rails application residing under a
-  # path which includes /app/controller anyway, such as:
-  #
-  #   /home/username/app/controller/my_web_application # == RAILS_ROOT
-  #
-  # then you might have trouble. Sorry, just please don't have your web application
-  # running under a path like that.
-  def require_engine_files(file_name, type='')
-    found = false
-    Engines.log.debug "requiring #{type} file '#{file_name}'"
-    processed_file_name = file_name.gsub(/[\w\W\/\.]*app\/#{type}s\//, '')    
-    Engines.log.debug "--> rewrote to '#{processed_file_name}'"
-    Engines.each(:load_order) do |engine|
-      engine_file_name = File.join(engine.root, 'app', "#{type}s", processed_file_name)
-      engine_file_name += '.rb' unless ! load? || engine_file_name[-3..-1] == '.rb'
-      Engines.log.debug "--> checking '#{engine.name}' for #{engine_file_name}"
-      if File.exist?(engine_file_name) || 
-        (engine_file_name[-3..-1] != '.rb' && File.exist?(engine_file_name + '.rb'))
-        Engines.log.debug "--> found, loading from engine '#{engine.name}'"
-        rails_pre_engines_require_or_load(engine_file_name)
-        found = true
-      end
-    end
-    found
-  end
-end
-
-
-# We only need to deal with LoadingModules in Rails 1.0.0
-if Rails::VERSION::STRING =~ /^1.0/ && !Engines.config(:edge)
-  module ::Dependencies
-    class RootLoadingModule < LoadingModule
-      # hack to allow adding to the load paths within the Rails Dependencies mechanism.
-      # this allows Engine classes to be unloaded and loaded along with standard
-      # Rails application classes.
-      def add_path(path)
-        @load_paths << (path.kind_of?(ConstantLoadPath) ? path : ConstantLoadPath.new(path))
-      end
-    end
-  end
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/lib/engines/migration_extensions.rb b/vendor/plugins/engines/lib/engines/migration_extensions.rb
deleted file mode 100755 (executable)
index 0653261..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#require 'active_record/connection_adapters/abstract/schema_statements'
-
-module ::ActiveRecord::ConnectionAdapters::SchemaStatements
-  alias :old_initialize_schema_information :initialize_schema_information
-  def initialize_schema_information
-    # create the normal schema stuff
-    old_initialize_schema_information
-    
-    # create the engines schema stuff.    
-    begin
-      execute "CREATE TABLE #{engine_schema_info_table_name} (engine_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
-    rescue ActiveRecord::StatementInvalid
-      # Schema has been initialized
-    end
-  end
-
-  def engine_schema_info_table_name
-    ActiveRecord::Base.wrapped_table_name "engine_schema_info"
-  end
-end
-
-
-require 'breakpoint'
-module ::Engines
-  class EngineMigrator < ActiveRecord::Migrator
-
-    # We need to be able to set the 'current' engine being migrated.
-    cattr_accessor :current_engine
-
-    class << self
-
-      def schema_info_table_name
-        ActiveRecord::Base.wrapped_table_name "engine_schema_info"
-      end
-
-      def current_version
-        result = ActiveRecord::Base.connection.select_one("SELECT version FROM #{schema_info_table_name} WHERE engine_name = '#{current_engine.name}'")
-        if result
-          result["version"].to_i
-        else
-          # There probably isn't an entry for this engine in the migration info table.
-          # We need to create that entry, and set the version to 0
-          ActiveRecord::Base.connection.execute("INSERT INTO #{schema_info_table_name} (version, engine_name) VALUES (0,'#{current_engine.name}')")      
-          0
-        end
-      end    
-    end
-
-    def set_schema_version(version)
-      ActiveRecord::Base.connection.update("UPDATE #{self.class.schema_info_table_name} SET version = #{down? ? version.to_i - 1 : version.to_i} WHERE engine_name = '#{self.current_engine.name}'")
-    end
-  end
-end
diff --git a/vendor/plugins/engines/lib/engines/routing_extensions.rb b/vendor/plugins/engines/lib/engines/routing_extensions.rb
deleted file mode 100755 (executable)
index 00f6b63..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-module ActionController
-  module Routing
-    
-    class << self
-      # This holds the global list of valid controller paths
-      attr_accessor :controller_paths
-    end
-    
-    class ControllerComponent
-      class << self
-      protected
-        def safe_load_paths #:nodoc:
-          if defined?(RAILS_ROOT)
-            paths = $LOAD_PATH.select do |base|
-              base = File.expand_path(base)
-              # Check that the path matches one of the allowed paths in controller_paths
-              base.match(/^#{ActionController::Routing.controller_paths.map { |p| File.expand_path(p) } * '|'}/)
-            end
-            Engines.log.debug "Engines safe_load_paths: #{paths.inspect}"
-            paths
-          else
-            $LOAD_PATH
-          end
-        end        
-      end
-    end
-  end
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/lib/engines/ruby_extensions.rb b/vendor/plugins/engines/lib/engines/ruby_extensions.rb
deleted file mode 100755 (executable)
index 189ca46..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#--
-# Add these methods to the top-level module so that they are available in all
-# modules, etc
-#++
-class ::Module
-  # Defines a constant within a module/class ONLY if that constant does
-  # not already exist.
-  #
-  # This can be used to implement defaults in plugins/engines/libraries, e.g.
-  # if a plugin module exists:
-  #   module MyPlugin
-  #     default_constant :MyDefault, "the_default_value"
-  #   end
-  #
-  # then developers can override this default by defining that constant at
-  # some point *before* the module/plugin gets loaded (such as environment.rb)
-  def default_constant(name, value)
-    if !(name.is_a?(String) or name.is_a?(Symbol))
-      raise "Cannot use a #{name.class.name} ['#{name}'] object as a constant name"
-    end
-    if !self.const_defined?(name)
-      self.class_eval("#{name} = #{value.inspect}")
-    end
-  end
-  
-  # A mechanism for defining configuration of Modules. With this
-  # mechanism, default values for configuration can be provided within shareable
-  # code, and the end user can customise the configuration without having to
-  # provide all values.
-  #
-  # Example:
-  #
-  #  module MyModule
-  #    config :param_one, "some value"
-  #    config :param_two, 12345
-  #  end
-  #
-  # Those values can now be accessed by the following method
-  #
-  #   MyModule.config :param_one  
-  #     => "some value"
-  #   MyModule.config :param_two  
-  #     => 12345
-  #
-  # ... or, if you have overrriden the method 'config'
-  #
-  #   MyModule::CONFIG[:param_one]  
-  #     => "some value"
-  #   MyModule::CONFIG[:param_two]  
-  #     => 12345
-  #
-  # Once a value is stored in the configuration, it will not be altered
-  # by subsequent assignments, unless a special flag is given:
-  #
-  #   (later on in your code, most likely in another file)
-  #   module MyModule
-  #     config :param_one, "another value"
-  #     config :param_two, 98765, :force
-  #   end
-  #
-  # The configuration is now:
-  #
-  #   MyModule.config :param_one  
-  #     => "some value" # not changed
-  #   MyModule.config :param_two  
-  #     => 98765
-  #
-  # Configuration values can also be given as a Hash:
-  #
-  #   MyModule.config :param1 => 'value1', :param2 => 'value2'
-  #
-  # Setting of these values can also be forced:
-  #
-  #   MyModule.config :param1 => 'value3', :param2 => 'value4', :force => true
-  #
-  # A value of anything other than false or nil given for the :force key will
-  # result in the new values *always* being set.
-  def config(*args)
-    
-    raise "config expects at least one argument" if args.empty?
-    
-    # extract the arguments
-    if args[0].is_a?(Hash)
-      override = args[0][:force]
-      args[0].delete(:force)
-      args[0].each { |key, value| _handle_config(key, value, override)}
-    else
-      _handle_config(*args)
-    end
-  end
-  
-  private
-    # Actually set the config values
-    def _handle_config(name, value=nil, override=false)
-      if !self.const_defined?("CONFIG")
-        self.class_eval("CONFIG = {}")
-      end
-    
-      if value != nil
-        if override or self::CONFIG[name] == nil
-          self::CONFIG[name] = value 
-        end
-      else
-        # if we pass an array of config keys to config(),
-        # get the array of values back
-        if name.is_a? Array
-          name.map { |c| self::CONFIG[c] }
-        else
-          self::CONFIG[name]
-        end
-      end      
-    end
-end
diff --git a/vendor/plugins/engines/lib/engines/testing_extensions.rb b/vendor/plugins/engines/lib/engines/testing_extensions.rb
deleted file mode 100755 (executable)
index 6d9755d..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-# The Engines testing extensions enable developers to load fixtures into specific
-# tables irrespective of the name of the fixtures file. This work is heavily based on
-# patches made by Duane Johnson (canadaduane), viewable at
-# http://dev.rubyonrails.org/ticket/1911
-#
-# Engine developers should supply fixture files in the <engine>/test/fixtures directory
-# as normal. Within their tests, they should load the fixtures using the 'fixture' command
-# (rather than the normal 'fixtures' command). For example:
-#
-#   class UserTest < Test::Unit::TestCase
-#     fixture :users, :table_name => LoginEngine.config(:user_table), :class_name => "User"
-#    
-#     ...
-#
-# This will ensure that the fixtures/users.yml file will get loaded into the correct
-# table, and will use the correct model object class.
-
-
-
-# A FixtureGroup is a set of fixtures identified by a name.  Normally, this is the name of the
-# corresponding fixture filename.  For example, when you declare the use of fixtures in a
-# TestUnit class, like so:
-#   fixtures :users
-# you are creating a FixtureGroup whose name is 'users', and whose defaults are set such that the
-# +class_name+, +file_name+ and +table_name+ are guessed from the FixtureGroup's name.
-class FixtureGroup
-  attr_accessor :table_name, :class_name, :connection
-  attr_reader :group_name, :file_name
-
-  def initialize(file_name, optional_names = {})
-    self.file_name = file_name
-    self.group_name = optional_names[:group_name] || file_name
-    if optional_names[:table_name]
-      self.table_name = optional_names[:table_name]
-      self.class_name = optional_names[:class_name] || Inflector.classify(@table_name.to_s.gsub('.','_'))
-    elsif optional_names[:class_name]
-      self.class_name = optional_names[:class_name]
-      if Object.const_defined?(@class_name)
-        model_class = Object.const_get(@class_name)
-        self.table_name = ActiveRecord::Base.table_name_prefix + model_class.table_name + ActiveRecord::Base.table_name_suffix
-      end
-    end
-
-    # In case either :table_name or :class_name was not set:
-    self.table_name ||= ActiveRecord::Base.table_name_prefix + @group_name.to_s + ActiveRecord::Base.table_name_suffix
-    self.class_name ||= Inflector.classify(@table_name.to_s.gsub('.','_'))
-  end
-
-  def file_name=(name)
-    @file_name = name.to_s
-  end
-  
-  def group_name=(name)
-    @group_name = name.to_sym
-  end
-
-  def class_file_name
-    Inflector.underscore(@class_name)
-  end
-  
-  # Instantiate an array of FixtureGroup objects from an array of strings (table_names)
-  def self.array_from_names(names)
-    names.collect { |n| FixtureGroup.new(n) }
-  end
-  
-  def hash
-    @group_name.hash
-  end
-  
-  def eql?(other)
-    @group_name.eql? other.group_name
-  end
-end
-
-class Fixtures < YAML::Omap
-
-  def self.instantiate_fixtures(object, fixture_group_name, fixtures, load_instances=true)
-    old_logger_level = ActiveRecord::Base.logger.level
-    ActiveRecord::Base.logger.level = Logger::ERROR
-
-    # table_name.to_s.gsub('.','_') replaced by 'fixture_group_name'
-    object.instance_variable_set "@#{fixture_group_name}", fixtures
-    if load_instances
-      ActiveRecord::Base.silence do
-        fixtures.each do |name, fixture|
-          begin
-            if model = fixture.find
-              object.instance_variable_set "@#{name}", model
-            end
-          rescue FixtureClassNotFound
-            # Let's hope the developer has included it himself
-          end
-        end
-      end
-    end
-
-    ActiveRecord::Base.logger.level = old_logger_level
-  end
-
-  # this doesn't really need to be overridden...
-  def self.instantiate_all_loaded_fixtures(object, load_instances=true)
-    all_loaded_fixtures.each do |fixture_group_name, fixtures|
-      Fixtures.instantiate_fixtures(object, fixture_group_name, fixtures, load_instances)
-    end
-  end
-
-  def self.create_fixtures(fixtures_directory, *fixture_groups)
-    connection = block_given? ? yield : ActiveRecord::Base.connection
-    fixture_groups.flatten!
-    
-    # Backwards compatibility: Allow an array of table names to be passed in, but just use them
-    # to create an array of FixtureGroup objects
-    if not fixture_groups.empty? and fixture_groups.first.is_a?(String)
-      fixture_groups = FixtureGroup.array_from_names(fixture_groups)
-    end
-
-    ActiveRecord::Base.silence do
-      fixtures_map = {}
-      fixtures = fixture_groups.map do |group|
-        fixtures_map[group.group_name] = Fixtures.new(connection, fixtures_directory, group)
-      end 
-      # Make sure all refs to all_loaded_fixtures use group_name as hash index, not table_name
-      all_loaded_fixtures.merge! fixtures_map 
-
-      connection.transaction do
-        fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
-        fixtures.each { |fixture| fixture.insert_fixtures }
-        
-        # Cap primary key sequences to max(pk).
-        if connection.respond_to?(:reset_pk_sequence!)
-          fixture_groups.each do |fg|
-            connection.reset_pk_sequence!(fg.table_name)
-          end
-        end
-      end
-
-      return fixtures.size > 1 ? fixtures : fixtures.first
-    end
-  end
-
-  attr_accessor :connection, :fixtures_directory, :file_filter
-  attr_accessor :fixture_group
-  def initialize(connection, fixtures_directory, fixture_group, file_filter = DEFAULT_FILTER_RE)
-    @connection, @fixtures_directory = connection, fixtures_directory
-    @fixture_group = fixture_group
-    @file_filter = file_filter
-    read_fixture_files
-  end
-  def delete_existing_fixtures
-    @connection.delete "DELETE FROM #{@fixture_group.table_name}", 'Fixture Delete'
-  end
-  def insert_fixtures
-    values.each do |fixture|
-      @connection.execute "INSERT INTO #{@fixture_group.table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
-    end
-  end
-  private
-    def read_fixture_files
-      if File.file?(yaml_file_path)
-        read_yaml_fixture_files
-      elsif File.file?(csv_file_path)
-        read_csv_fixture_files
-      elsif File.file?(deprecated_yaml_file_path)
-        raise Fixture::FormatError, ".yml extension required: rename #{deprecated_yaml_file_path} to #{yaml_file_path}"
-      elsif File.directory?(single_file_fixtures_path)
-        read_standard_fixture_files
-      else
-        raise Fixture::FixtureError, "Couldn't find a yaml, csv or standard file to load at #{@fixtures_directory} (#{@fixture_group.file_name})."
-      end
-    end
-
-    def read_yaml_fixture_files
-      # YAML fixtures
-      begin
-        if yaml = YAML::load(erb_render(IO.read(yaml_file_path)))
-          yaml = yaml.value if yaml.respond_to?(:type_id) and yaml.respond_to?(:value)
-          yaml.each do |name, data|
-            self[name] = Fixture.new(data, fixture_group.class_name)
-          end
-        end
-      rescue Exception=>boom
-        raise Fixture::FormatError, "a YAML error occured parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n  #{boom.class}: #{boom}"
-      end      
-    end
-
-    def read_csv_fixture_files
-      # CSV fixtures
-      reader = CSV::Reader.create(erb_render(IO.read(csv_file_path)))
-      header = reader.shift
-      i = 0
-      reader.each do |row|
-        data = {}
-        row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
-        self["#{@fixture_group.class_file_name}_#{i+=1}"]= Fixture.new(data, @fixture_group.class_name)
-      end
-    end
-
-    def read_standard_fixture_files
-      # Standard fixtures
-      path = File.join(@fixtures_directory, @fixture_group.file_name)
-      Dir.entries(path).each do |file|
-        path = File.join(@fixtures_directory, @fixture_group.file_name, file)
-        if File.file?(path) and file !~ @file_filter
-          self[file] = Fixture.new(path, @fixture_group.class_name)
-        end
-      end
-    end
-    def yaml_file_path
-      fixture_path_with_extension ".yml"
-    end
-    def deprecated_yaml_file_path
-      fixture_path_with_extension ".yaml"
-    end
-    def csv_file_path
-      fixture_path_with_extension ".csv"
-    end
-    
-    def single_file_fixtures_path
-      fixture_path_with_extension ""
-    end
-    def fixture_path_with_extension(ext)
-      File.join(@fixtures_directory, @fixture_group.file_name + ext)
-    end 
-
-    def erb_render(fixture_content)
-      ERB.new(fixture_content).result
-    end
-
-end
-
-module Test #:nodoc:
-  module Unit #:nodoc:
-    class TestCase #:nodoc:
-      cattr_accessor :fixtures_directory
-      class_inheritable_accessor :fixture_groups
-      class_inheritable_accessor :fixture_table_names
-      class_inheritable_accessor :use_transactional_fixtures
-      class_inheritable_accessor :use_instantiated_fixtures   # true, false, or :no_instances
-      class_inheritable_accessor :pre_loaded_fixtures
-
-      self.fixture_groups = []
-      self.use_transactional_fixtures = false
-      self.use_instantiated_fixtures = true
-      self.pre_loaded_fixtures = false
-
-      @@already_loaded_fixtures = {}
-
-      # Backwards compatibility
-      def self.fixture_path=(path); self.fixtures_directory = path; end
-      def self.fixture_path; self.fixtures_directory; end
-      def fixture_group_names; fixture_groups.collect { |g| g.group_name }; end
-      def fixture_table_names; fixture_group_names; end
-
-      def self.fixture(file_name, options = {})
-        self.fixture_groups |= [FixtureGroup.new(file_name, options)]
-        require_fixture_classes
-        setup_fixture_accessors
-      end
-
-      def self.fixtures(*file_names)
-        self.fixture_groups |= FixtureGroup.array_from_names(file_names.flatten)
-        require_fixture_classes
-        setup_fixture_accessors
-      end
-
-      def self.require_fixture_classes(fixture_groups_override = nil)
-        (fixture_groups_override || fixture_groups).each do |group| 
-          begin
-            require group.class_file_name
-          rescue LoadError
-            # Let's hope the developer has included it himself
-          end
-        end
-      end
-
-      def self.setup_fixture_accessors(fixture_groups_override=nil)
-        (fixture_groups_override || fixture_groups).each do |group|
-          define_method(group.group_name) do |fixture, *optionals|
-            force_reload = optionals.shift
-            @fixture_cache[group.group_name] ||= Hash.new
-            @fixture_cache[group.group_name][fixture] = nil if force_reload
-            @fixture_cache[group.group_name][fixture] ||= @loaded_fixtures[group.group_name][fixture.to_s].find
-          end
-        end
-      end
-
-      private
-        def load_fixtures
-          @loaded_fixtures = {}
-          fixtures = Fixtures.create_fixtures(fixtures_directory, fixture_groups)
-          unless fixtures.nil?
-            if fixtures.instance_of?(Fixtures)
-              @loaded_fixtures[fixtures.fixture_group.group_name] = fixtures
-            else
-              fixtures.each { |f| @loaded_fixtures[f.fixture_group.group_name] = f }
-            end
-          end
-        end
-
-        def instantiate_fixtures
-          if pre_loaded_fixtures
-            raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty?
-            unless @@required_fixture_classes
-              groups = Fixtures.all_loaded_fixtures.values.collect { |f| f.group_name }
-              self.class.require_fixture_classes groups
-              @@required_fixture_classes = true
-            end
-            Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
-          else
-            raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
-            @loaded_fixtures.each do |fixture_group_name, fixtures|
-              Fixtures.instantiate_fixtures(self, fixture_group_name, fixtures, load_instances?)
-            end
-          end
-        end
-    end
-  end
-end
diff --git a/vendor/plugins/engines/tasks/deprecated_engines.rake b/vendor/plugins/engines/tasks/deprecated_engines.rake
deleted file mode 100755 (executable)
index 33e2a28..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# Old-style engines rake tasks.
-# NOTE: THESE ARE DEPRICATED! PLEASE USE THE NEW STYLE!
-
-task :engine_info => "engines:info"
-task :engine_migrate => "db:migrate:engines"
-task :enginedoc => "doc:engines"
-task :load_plugin_fixtures => "db:fixtures:engines:load"
\ No newline at end of file
diff --git a/vendor/plugins/engines/tasks/engines.rake b/vendor/plugins/engines/tasks/engines.rake
deleted file mode 100755 (executable)
index 21bb763..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-module Engines
-  module RakeTasks
-    def self.all_engines
-      # An engine is informally defined as any subdirectory in vendor/plugins
-      # which ends in '_engine', '_bundle', or contains an 'init_engine.rb' file.
-      engine_base_dirs = ['vendor/plugins']
-      # The engine root may be different; if possible try to include
-      # those directories too
-      if Engines.const_defined?(:CONFIG)
-        engine_base_dirs << Engines::CONFIG[:root]
-      end
-      engine_base_dirs.map! {|d| [d + '/*_engine/*', 
-                                  d + '/*_bundle/*',
-                                  d + '/*/init_engine.rb']}.flatten!
-      engine_dirs = FileList.new(*engine_base_dirs)
-      engine_dirs.map do |engine| 
-        File.basename(File.dirname(engine))
-      end.uniq       
-    end
-  end
-end
-
-
-namespace :engines do
-  desc "Display version information about active engines"
-  task :info => :environment do
-    if ENV["ENGINE"]
-      e = Engines.get(ENV["ENGINE"])
-      header = "Details for engine '#{e.name}':"
-      puts header
-      puts "-" * header.length
-      puts "Version: #{e.version}"
-      puts "Details: #{e.info}"
-    else
-      puts "Engines plugin: #{Engines.version}"
-      Engines.each do |e|
-        puts "#{e.name}: #{e.version}"
-      end
-    end
-  end
-end
-
-namespace :db do  
-  namespace :fixtures do
-    namespace :engines do
-      
-      desc "Load plugin/engine fixtures into the current environment's database."
-      task :load => :environment do
-        require 'active_record/fixtures'
-        ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
-        plugin = ENV['ENGINE'] || '*'
-        Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', plugin, 'test', 'fixtures', '*.yml')).each do |fixture_file|
-          Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
-        end
-      end
-      
-    end
-  end
-
-
-  namespace :migrate do
-    
-    desc "Migrate all engines. Target specific version with VERSION=x, specific engine with ENGINE=x"
-    task :engines => :environment do
-      engines_to_migrate = ENV["ENGINE"] ? [Engines.get(ENV["ENGINE"])].compact : Engines.active
-      if engines_to_migrate.empty?
-        puts "Couldn't find an engine called '#{ENV["ENGINE"]}'"
-      else
-        if ENV["VERSION"] && !ENV["ENGINE"]
-          # ignore the VERSION, since it makes no sense in this context; we wouldn't
-          # want to revert ALL engines to the same version because of a misttype
-          puts "Ignoring the given version (#{ENV["VERSION"]})."
-          puts "To control individual engine versions, use the ENGINE=<engine> argument"
-        else
-          engines_to_migrate.each do |engine| 
-            Engines::EngineMigrator.current_engine = engine
-            migration_directory = File.join(engine.root, 'db', 'migrate')
-            if File.exist?(migration_directory)
-              puts "Migrating engine '#{engine.name}'"
-              Engines::EngineMigrator.migrate(migration_directory, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
-            else
-              puts "The db/migrate directory for engine '#{engine.name}' appears to be missing."
-              puts "Should be: #{migration_directory}"
-            end
-          end
-          if ActiveRecord::Base.schema_format == :ruby && !engines_to_migrate.empty?
-            Rake::Task[:db_schema_dump].invoke
-          end
-        end
-      end
-    end
-
-    namespace :engines do
-      Engines::RakeTasks.all_engines.each do |engine_name|
-        desc "Migrate the '#{engine_name}' engine. Target specific version with VERSION=x"
-        task engine_name => :environment do
-          ENV['ENGINE'] = engine_name; Rake::Task['db:migrate:engines'].invoke
-        end
-      end
-    end
-    
-  end
-end
-
-
-# this is just a rip-off from the plugin stuff in railties/lib/tasks/documentation.rake, 
-# because the default plugindoc stuff doesn't support subdirectories like <engine>/app or
-# <engine>/component.
-namespace :doc do
-
-  desc "Generate documation for all installed engines"
-  task :engines => Engines::RakeTasks.all_engines.map {|engine| "doc:engines:#{engine}"}
-
-  namespace :engines do
-    # Define doc tasks for each engine
-    Engines::RakeTasks.all_engines.each do |engine_name|
-      desc "Generation documentation for the '#{engine_name}' engine"
-      task engine_name => :environment do
-        engine_base   = "vendor/plugins/#{engine_name}"
-        options       = []
-        files         = Rake::FileList.new
-        options << "-o doc/plugins/#{engine_name}"
-        options << "--title '#{engine_name.titlecase} Documentation'"
-        options << '--line-numbers --inline-source'
-        options << '--all' #¬†include protected methods
-        options << '-T html'
-
-        files.include("#{engine_base}/lib/**/*.rb")
-        files.include("#{engine_base}/app/**/*.rb") # include the app directory
-        files.include("#{engine_base}/components/**/*.rb") # include the components directory
-        if File.exists?("#{engine_base}/README")
-          files.include("#{engine_base}/README")    
-          options << "--main '#{engine_base}/README'"
-        end
-        files.include("#{engine_base}/CHANGELOG") if File.exists?("#{engine_base}/CHANGELOG")
-
-        options << files.to_s
-
-        sh %(rdoc #{options * ' '})
-      end
-    end
-  end
-end
-
-namespace :test do
-  desc "Run the engine tests in vendor/plugins/**/test (or specify with ENGINE=name)"
-  # NOTE: we're using the Rails 1.0 non-namespaced task here, just to maintain
-  # compatibility with Rails 1.0
-  # TODO: make this work with Engines.config(:root)
-  
-  namespace :engines do
-    Engines::RakeTasks.all_engines.each do |engine_name|
-      desc "Run the engine tests for '#{engine_name}'"
-      Rake::TestTask.new(engine_name => :prepare_test_database) do |t|
-        t.libs << 'test'
-        t.pattern = "vendor/plugins/#{engine_name}/test/**/*_test.rb"
-        t.verbose = true
-      end
-    end    
-  end
-  
-  Rake::TestTask.new(:engines => [:warn_about_multiple_engines_testing, :prepare_test_database]) do |t|
-    t.libs << "test"
-    engines = ENV['ENGINE'] || '**'
-    t.pattern = "vendor/plugins/#{engines}/test/**/*_test.rb"
-    t.verbose = true
-  end
-  
-  task :warn_about_multiple_engines_testing do
-    puts %{-~============== A Moste Polite Warninge ==================~-
-You may experience issues testing multiple engines at once. 
-Please test engines individual for the moment.
--~===============( ... as you were ... )===================~-
-}
-  end
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/test/action_view_extensions_test.rb b/vendor/plugins/engines/test/action_view_extensions_test.rb
deleted file mode 100755 (executable)
index 8951785..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + '/../../../../config/environment')
-require 'test_help'
-
-class ActionViewExtensionsTest < Test::Unit::TestCase
-  def test_stylesheet_path
-    assert true
-  end
-end
\ No newline at end of file
diff --git a/vendor/plugins/engines/test/ruby_extensions_test.rb b/vendor/plugins/engines/test/ruby_extensions_test.rb
deleted file mode 100755 (executable)
index c904f67..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + '/../../../../config/environment')
-require 'test_help'
-
-class RubyExtensionsTest < Test::Unit::TestCase
-
-  def setup
-    # create the module to be used for config testing
-    eval "module TestModule end"
-  end  
-
-  def teardown
-    # remove the TestModule constant from our scope
-    self.class.class_eval { remove_const :TestModule }
-  end
-
-
-  #
-  # Module.config
-  #
-
-  def test_config_no_arguments
-    assert_raise(RuntimeError) { TestModule.config }
-  end
-  
-  def test_config_array_arguments
-    TestModule.config :monkey, 123
-    assert_equal(123, TestModule.config(:monkey))
-  end
-  
-  def test_config_hash_arguments
-    TestModule.config :monkey => 123, :donkey => 456
-    assert_equal(123, TestModule.config(:monkey))
-    assert_equal(456, TestModule.config(:donkey))
-  end
-
-  def test_config_can_store_hash
-    TestModule.config :hash, :key1 => 'val1', :key2 => 'val2'
-    assert_equal({:key1 => 'val1', :key2 => 'val2'}, TestModule.config(:hash))
-  end
-    
-  def test_config_cant_overwrite_existing_config_values
-    TestModule.config :monkey, 123
-    assert_equal(123, TestModule.config(:monkey))
-    TestModule.config :monkey, 456
-    assert_equal(123, TestModule.config(:monkey))
-    
-    TestModule.config :monkey => 456
-    assert_equal(123, TestModule.config(:monkey))    
-    
-    # in this case, the resulting Hash only has {:baboon => "goodbye!"} - that's Ruby, users beware.
-    TestModule.config :baboon => "hello", :baboon => "goodbye!"
-    assert_equal("goodbye!", TestModule.config(:baboon))    
-  end
-  
-  def test_config_force_new_value
-    TestModule.config :monkey, 123
-    TestModule.config :man, 321
-    assert_equal(123, TestModule.config(:monkey))
-    assert_equal(321, TestModule.config(:man))
-    TestModule.config :monkey, 456, :force
-    assert_equal(456, TestModule.config(:monkey))  
-    TestModule.config :monkey => 456, :man => 654, :force => true
-    assert_equal(456, TestModule.config(:monkey))
-    assert_equal(654, TestModule.config(:man))      
-    TestModule.config :monkey => 789, :man => 987, :force => false
-    assert_equal(456, TestModule.config(:monkey))
-    assert_equal(654, TestModule.config(:man))
-    
-    TestModule.config :hash, :key1 => 'val1', :key2 => 'val2'
-    assert_equal({:key1 => 'val1', :key2 => 'val2'}, TestModule.config(:hash))
-    TestModule.config :hash => {:key1 => 'val3', :key2 => 'val4'}, :force => true
-    assert_equal({:key1 => 'val3', :key2 => 'val4'}, TestModule.config(:hash))           
-  end
-  
-  # this test is somewhat redundant, but it might be an idea to havbe it explictly anyway
-  def test_config_get_values
-    TestModule.config :monkey, 123
-    assert_equal(123, TestModule.config(:monkey))
-  end
-  
-  def test_config_get_multiple_values
-    TestModule.config :monkey, 123
-    TestModule.config :donkey, 456
-    assert_equal([123, 456], TestModule.config([:monkey, :donkey]))
-  end
-  
-  
-  #
-  # Module.default_constant
-  #
-  
-  def test_default_constant_set
-    TestModule.default_constant :Monkey, 123
-    assert_equal(123, TestModule::Monkey)
-    TestModule.default_constant "Hello", 456
-    assert_equal(456, TestModule::Hello)
-  end
-
-  def test_default_constant_cannot_set_again
-    TestModule.default_constant :Monkey, 789
-    assert_equal(789, TestModule::Monkey)
-    TestModule.default_constant :Monkey, 456
-    assert_equal(789, TestModule::Monkey)
-  end
-
-  def test_default_constant_bad_arguments
-    # constant names must be Captialized
-    assert_raise(NameError) { TestModule.default_constant :lowercase_name, 123 }
-    
-    # constant names should be given as Strings or Symbols
-    assert_raise(RuntimeError) { TestModule.default_constant 123, 456 }
-    assert_raise(RuntimeError) { TestModule.default_constant Object.new, 456 }
-  end
-end
diff --git a/vendor/plugins/login_engine/CHANGELOG b/vendor/plugins/login_engine/CHANGELOG
deleted file mode 100755 (executable)
index 3764ef2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-= v1.0.2
-* Added version
-* Removed errant requires no longer needed (murray.steele@gmail.com, Ticket #156, Ticket #157, Ticket #158)
-# Removed documentation/rake tasks that refer the schema.rb (Ticket #155)
-# Verified cannot be assigned via URL parameters. If more security is required, users should override the signup action itself (Ticket #169)
-# Minor view/flash message cleanup
-# Authentication by token now respects primary key prefixes (Ticket #140)
-
-= v1.0.1
- * Added CHANGELOG
- * Changed wording for when password forgotten to 'reset', rather than 'retrieve'. (snowblink@gmail.com)
- * Fixed new location of engines testing extensions. (lazyatom@gmail.com)
- * Removed schema.db from Login Engine; migrations should be used instead. (snowblink@gmail.com)
- * Updated User Controller tests to parse the user_id and email out of the URL in the email body. (snowblink@gmail.com)
- * Ticket #89 (lazyatom@gmail.com) User creation halts the after_save callback chain.
- * Ticket #97 (dcorbin@machturtle.com) The forgotten_password view generates invalid HTML
- * Ticket #112 (segabor@gmail.com) Authentication system will break even on successful login
- * Added simple email validation to the User model. (snowblink@gmail.com)
-   This should also take care of the unit test failures detailed in Ticket #114 (morris@wolfman.com)
- * Ticket #118 (augustz@augustz.com) SVN source for login_engine not found
- * Ticket #119 (Goynang) Unit tests for engines fail after default install
- * Ticket #126 (lazyatom@gmail.com) Add install.rb to login engine
diff --git a/vendor/plugins/login_engine/README b/vendor/plugins/login_engine/README
deleted file mode 100755 (executable)
index 69b2981..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-= Before we start
-
-This is a Rails Engine version of the Salted Login Generator, a most excellent login system which is sufficient for most simple cases. For the most part, this code has not been altered from its generator form, with the following notable exceptions
-
-* Localization has been removed.
-* The 'welcome' page has been changed to the 'home' page
-* A few new functions have been thrown in
-* It's... uh.... a Rails Engine now ;-)
-
-However, what I'm trying to say is that 99.9999% of the credit for this should go to Joe Hosteny, Tobias Luetke (xal) and the folks that worked on the original Salted Login generator code. I've just wrapped it into something runnable with the Rails Engine system.
-
-Please also bear in mind that this is a work in progress, and things like testing are wildly up in the air... but they will fall into place very soon. And now, on with the show.
-
-
-= Installation
-
-Installing the Login Engine is fairly simple.
-
-Your options are:
-  1.  Install as a rails plugin:
-      $ script/plugin install login_engine
-  2.  Use svn:externals
-      $ svn propedit svn:externals vendor/plugins
-
-      You can choose to use the latest stable release:
-          login_engine http://svn.rails-engines.org/plugins/login_engine
-
-      Or a tagged release (recommended for releases of your code):
-          login_engine http://svn.rails-engines.org/logine_engine/tags/<TAGGED_RELEASE>
-
-There are a few configuration steps that you'll need to take to get everything running smoothly. Listed below are the changes to your application you will need to make.
-
-=== Setup your Rails application
-
-Edit your <tt>database.yml</tt>, most importantly! You might also want to move <tt>public/index.html</tt> out of the way, and set up some default routes in <tt>config/routes.rb</tt>.
-
-=== Add configuration and start engine
-
-Add the following to the bottom of environment.rb:
-
-  module LoginEngine
-    config :salt, "your-salt-here"
-  end
-
-  Engines.start :login
-  
-You'll probably want to change the Salt value to something unique. You can also override any of the configuration values defined at the top of lib/user_system.rb in a similar way. Note that you don't need to start the engine with <tt>Engines.start :login_engine</tt> - instead, <tt>:login</tt> (or any name) is sufficient if the engine is a directory named <some-name>_engine.
-
-
-=== Add the filters
-
-Next, edit your <tt>app/controllers/application.rb</tt> file. The beginning of your <tt>ApplicationController</tt> should look something like this:
-
-  require 'login_engine'
-
-  class ApplicationController < ActionController::Base
-    include LoginEngine
-    helper :user
-    model :user
-    
-    before_filter :login_required
-
-If you don't want ALL actions to require a login, you need to read further below to learn how to restrict only certain actions. 
-
-Add the following to your ApplicationHelper:
-
-  module ApplicationHelper
-    include LoginEngine
-  end
-
-This ensures that the methods to work with users in your views are available
-
-=== Set up ActionMailer
-
-If you want to disable email functions within the Login Engine, simple set the :use_email_notification config flag to false in your environment.rb file:
-
-  module LoginEngine
-    
-    #  ... other options...
-    config :use_email_notification, false
-
-  end
-
-You should note that retrieving forgotten passwords automatically isn't possible when the email functions are disabled. Instead, the user is presented with a message instructing them to contact the system administrator
-
-If you wish you use email notifications and account creation verification, you must properly configure ActionMailer for your mail settings. For example, you could add the following in config/environments/development.rb (for a .Mac account, and with your own username and password, obviously):
-
-ActionMailer::Base.server_settings = {
-  :address => "smtp.mac.com",
-  :port => 25,
-  :domain => "smtp.mac.com",
-  :user_name => "<your user name here>",
-  :password => "<your password here>",
-  :authentication => :login
-}
-
-You'll need to configure it properly so that email can be sent. One of the easiest ways to test your configuration is to temporarily reraise exceptions from the signup method (so that you get the actual mailer exception string). In the rescue statement, put a single "raise" statement in. Once you've debugged any setting problems, remove that statement to get the proper flash error handling back.
-
-
-=== Create the DB schema
-
-After you have done the modifications the the ApplicationController and its helper, you can import the user model into the database. Migration information in login_engine/db/migrate/. 
-
-You *MUST* check that these files aren't going to interfere with anything in your application. 
-
-You can change the table name used by adding
-
-  module LoginEngine
-    
-    #  ... other options...
-    config :user_table, "your_table_name"
-
-  end
-
-...to the LoginEngine configuration in <tt>environment.rb</tt>. Then run from the root of your project:
-
-  rake db:migrate:engines ENGINE=login
-
-to import the schema into your database.
-
-
-== Include stylesheets
-
-If you want the default stylesheet, add the following line to your layout:
-
-  <%= engine_stylesheet 'login_engine' %>
-  
-... somewhere in the <head> section of your HTML layout file.
-
-== Integrate flash messages into your layout
-
-LoginEngine does not display any flash messages in the views it contains, and thus you must display them yourself. This allows you to integrate any flash messages into your existing layout. LoginEngine adheres to the emerging flash usage standard, namely:
-
-* :warning - warning (failure) messages
-* :notice - success messages
-* :message - neutral (reminder, informational) messages
-
-This gives you the flexibility to theme the different message classes separately. In your layout you should check for and display flash[:warning], flash[:notice] and flash[:message]. For example:
-
-  <% for name in [:notice, :warning, :message] %>
-    <% if flash[name] %>
-      <%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
-    <% end %>
-  <% end %>
-
-Alternately, you could look at using the flash helper plugin (available from https://opensvn.csie.org/traccgi/flash_helper_plugin/trac.cgi/), which supports the same naming convention.
-
-
-= How to use the Login Engine 
-
-Now you can go around and happily add "before_filter :login_required" to the controllers which you would like to protect. 
-
-After integrating the login system with your rails application navigate to your new controller's signup method. There you can create a new account. After you are done you should have a look at your DB. Your freshly created user will be there but the password will be a sha1 hashed 40 digit mess. I find this should be the minimum of security which every page offering login & password should give its customers. Now you can move to one of those  controllers which you protected with the before_filter :login_required snippet. You will automatically be re-directed to your freshly created login controller and you are asked for a password. After entering valid account data you will be taken back to the controller which you requested earlier. Simple huh?
-
-=== Protection using <tt>before_filter</tt>
-
-Adding the line <tt>before_filter :login_required</tt> to your <tt>app/controllers/application.rb</tt> file will protect *all* of your applications methods, in every controller. If you only want to control access to specific controllers, remove this line from <tt>application.rb</tt> and add it to the controllers that you want to secure.
-
-Within individual controllers you can restrict which methods the filter runs on in the usual way:
-
-       before_filter :login_required, :only => [:myaccount, :changepassword]
-       before_filter :login_required, :except => [:index]
-
-=== Protection using <tt>protect?()</tt>
-
-Alternatively, you can leave the <tt>before_filter</tt> in the global <tt>application.rb</tt> file, and control which actions are restricted in individual controllers by defining a <tt>protect?()</tt> method in that controller.
-
-For instance, in the <tt>UserController</tt> we want to allow everyone access to the 'login', 'signup' and 'forgot_password' methods (otherwise noone would be able to access our site!). So a <tt>protect?()</tt> method is defined in <tt>user_controller.rb</tt> as follows:
-
-  def protect?(action)
-    if ['login', 'signup', 'forgot_password'].include?(action)
-      return false
-    else
-      return true
-    end
-  end
-
-Of course, you can override this Engine behaviour in your application - see below.
-
-== Configuration
-
-The following configuration variables are set in lib/login_engine.rb. If you wish to override them, you should set them BEFORE calling Engines.start (it is possible to set them after, but it's simpler to just do it before. Please refer to the Engine documentation for the #config method for more information).
-
-For example, the following might appear at the bottom of /config/environment.rb:
-
-  module LoginEngine
-    config :salt, 'my salt'
-    config :app_name, 'My Great App'
-    config :app_url, 'http://www.wow-great-domain.com'
-  end
-  
-  Engines.start
-
-=== Configuration Options
-
-+email_from+:: The email from which registration/administration emails will appear to 
-               come from. Defaults to 'webmaster@your.company'.
-+admin_email+:: The email address users are prompted to contact if passwords cannot
-                be emailed. Defaults to 'webmaster@your.company'.
-+app_url+:: The URL of the site sent to users for signup/forgotten passwords, etc.
-            Defaults to 'http://localhost:3000/'.
-+app_name+:: The application title used in emails. Defaults to 'TestApp'.
-+mail_charset+:: The charset used in emails. Defaults to 'utf-8'.
-+security_token_life_hours+:: The life span of security tokens, in hours. If a security
-                              token is older than this when it is used to try and authenticate
-                              a user, it will be discarded. In other words, the amount of time
-                              new users have between signing up and clicking the link they
-                              are sent. Defaults to 24 hours.
-+two_column_input+:: If true, forms created with the UserHelper#form_input method will
-                     use a two-column table. Defaults to true.
-+changeable_fields+:: An array of fields within the user model which the user
-                      is allowed to edit. The Salted Hash Login generator documentation
-                      states that you should NOT include the email field in this
-                      array, although I am not sure why. Defaults to +[ 'firstname', 'lastname' ]+.
-+delayed_delete+::  Set to true to allow delayed deletes (i.e., delete of record
-                    doesn't happen immediately after user selects delete account,
-                    but rather after some expiration of time to allow this action
-                    to be reverted). Defaults to false.
-+delayed_delete_days+:: The time delay used for the 'delayed_delete' feature. Defaults to
-                        7 days.
-+user_table+:: The table to store User objects in. Defaults to "users" (or "user" if
-               ActiveRecord pluralization is disabled).
-+use_email_notification+:: If false, no emails will be sent to the user. As a consequence,
-                           users who signup are immediately verified, and they cannot request
-                           forgotten passwords. Defaults to true.
-+confirm_account+:: An overriding flag to control whether or not user accounts must be
-                    verified by email. This overrides the +user_email_notification+ flag.
-                    Defaults to true.
-
-== Overriding controllers and views
-
-The standard home page is almost certainly not what you want to present to your users. Because this login system is a Rails Engine, overriding the default behaviour couldn't be simpler. To change the RHTML template shown for the <tt>home</tt> action, simple create a new file in <tt>RAILS_ROOT/app/views/user/home.rhtml</tt> (you'll probably need to create the directory <tt>user</tt> at the same time). This new view file will be used instead of the one provided in the Login Engine. Easy!
-
-
-== Tips & Tricks
-
-How do I...
-
-  ... access the user who is currently logged in
-
-  A: You can get the user object from the session using session[:user]
-     Example: 
-       Welcome <%= session[:user].name %>
-
-    You can also use the 'current_user' method provided by UserHelper:
-    Example:
-      Welcome <%= current_user.name %>
-
-
-  ... restrict access to only a few methods? 
-  
-  A: Use before_filters build in scoping. 
-     Example: 
-       before_filter :login_required, :only => [:myaccount, :changepassword]
-       before_filter :login_required, :except => [:index]
-     
-  ... check if a user is logged-in in my views?
-  
-  A: session[:user] will tell you. Here is an example helper which you can use to make this more pretty:
-     Example: 
-       def user?
-         !session[:user].nil?
-       end
-
-  ... return a user to the page they came from before logging in?
-
-  A: The user will be send back to the last url which called the method "store_location"
-     Example:
-       User was at /articles/show/1, wants to log in.
-       in articles_controller.rb, add store_location to the show function and
-       send the user to the login form. 
-       After he logs in he will be send back to /articles/show/1
-
-You can find more help at http://wiki.rubyonrails.com/rails/show/SaltedLoginGenerator
-
-== Troubleshooting
-
-One of the more common problems people have seen is that after verifying an account by following the emailed URL, they are unable to login via the normal login method since the verified field is not properly set in the user model's row in the DB.
-
-The most common cause of this problem is that the DB and session get out of sync. In particular, it always happens for me after recreating the DB if I have run the server previously. To fix the problem, remove the /tmp/ruby* session files (from wherever they are for your installation) while the server is stopped, and then restart. This usually is the cause of the problem.
-
-= Notes
-
-=== Database Schemas & Testing
-
-Currently, since not all databases appear to support structure cloning, the tests will load the entire schema into your test database, potentially blowing away any other test structures you might have. If this presents an issue for your application, comment out the line in test/test_helper.rb
-
-
-= Database Schema Details
-
-You need a database table corresponding to the User model. This is provided as a Rails Schema file, but the schema is presented below for information. Note the table type for MySQL. Whatever DB you use, it must support transactions. If it does not, the functional tests will not work properly, nor will the application in the face of failures during certain DB creates and updates.
-
-  mysql syntax:
-  CREATE TABLE users (
-    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-    login VARCHAR(80) NOT NULL,
-    salted_password VARCHAR(40) NOT NULL,
-    email VARCHAR(60) NOT NULL,
-    firstname VARCHAR(40),
-    lastname VARCHAR(40),
-    salt CHAR(40) NOT NULL,
-    verified INT default 0,
-    role VARCHAR(40) default NULL,
-    security_token CHAR(40) default NULL,
-    token_expiry DATETIME default NULL,
-    deleted INT default 0,
-    delete_after DATETIME default NULL
-  ) TYPE=InnoDB DEFAULT CHARSET=utf8;
-
-  postgres:
-  CREATE TABLE "users" (
-    id SERIAL PRIMARY KEY
-    login VARCHAR(80) NOT NULL,
-    salted_password VARCHAR(40) NOT NULL,
-    email VARCHAR(60) NOT NULL,
-    firstname VARCHAR(40),
-    lastname VARCHAR(40),
-    salt CHAR(40) NOT NULL,
-    verified INT default 0,
-    role VARCHAR(40) default NULL,
-    security_token CHAR(40) default NULL,
-    token_expiry TIMESTAMP default NULL,
-    deleted INT default 0,
-    delete_after TIMESTAMP default NULL
-  ) WITH OIDS;
-
-  sqlite:
-  CREATE TABLE 'users' (
-    id INTEGER PRIMARY KEY,
-    login VARCHAR(80) NOT NULL,
-    salted_password VARCHAR(40) NOT NULL,
-    email VARCHAR(60) NOT NULL,
-    firstname VARCHAR(40),
-    lastname VARCHAR(40),
-    salt CHAR(40) NOT NULL,
-    verified INT default 0,
-    role VARCHAR(40) default NULL,
-    security_token CHAR(40) default NULL,
-    token_expiry DATETIME default NULL,
-    deleted INT default 0,
-    delete_after DATETIME default NULL
-  );
-
-Of course your user model can have any amount of extra fields. This is just a starting point.
diff --git a/vendor/plugins/login_engine/app/controllers/user_controller.rb b/vendor/plugins/login_engine/app/controllers/user_controller.rb
deleted file mode 100755 (executable)
index 397f06b..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-class UserController < ApplicationController
-  model   :user
-
-  # Override this function in your own application to define a custom home action.
-  def home
-    if user?
-      @fullname = "#{current_user.firstname} #{current_user.lastname}"
-    else
-      @fullname = "Not logged in..."
-    end # this is a bit of a hack since the home action is used to verify user
-        # keys, where noone is logged in. We should probably create a unique
-        # 'validate_key' action instead.
-  end
-
-  # The action used to log a user in. If the user was redirected to the login page
-  # by the login_required method, they should be sent back to the page they were
-  # trying to access. If not, they will be sent to "/user/home".
-  def login
-    return if generate_blank
-    @user = User.new(params[:user])
-    if session[:user] = User.authenticate(params[:user][:login], params[:user][:password])
-      session[:user].logged_in_at = Time.now
-      session[:user].save
-      flash[:notice] = 'Login successful'
-      redirect_to_stored_or_default :action => 'home'
-    else
-      @login = params[:user][:login]
-      flash.now[:warning] = 'Login unsuccessful'
-    end
-  end
-
-  # Register as a new user. Upon successful registration, the user will be sent to
-  # "/user/login" to enter their details.
-  def signup
-    return if generate_blank
-    params[:user].delete('form')
-    params[:user].delete('verified') # you CANNOT pass this as part of the request
-    @user = User.new(params[:user])
-    begin
-      User.transaction(@user) do
-        @user.new_password = true
-        unless LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
-          @user.verified = 1
-        end
-        if @user.save
-          key = @user.generate_security_token
-          url = url_for(:action => 'home', :user_id => @user.id, :key => key)
-          flash[:notice] = 'Signup successful!'
-          if LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
-            UserNotify.deliver_signup(@user, params[:user][:password], url)
-            flash[:notice] << ' Please check your registered email account to verify your account registration and continue with the login.'
-          else
-            flash[:notice] << ' Please log in.'
-          end
-          redirect_to :action => 'login'
-        end
-      end
-    rescue Exception => e
-      flash.now[:notice] = nil
-      flash.now[:warning] = 'Error creating account: confirmation email not sent'
-      logger.error "Unable to send confirmation E-Mail:"
-      logger.error e
-    end
-  end
-
-  def logout
-    session[:user] = nil
-    redirect_to :action => 'login'
-  end
-
-  def change_password
-    return if generate_filled_in
-    if do_change_password_for(@user)
-      # since sometimes we're changing the password from within another action/template...
-      #redirect_to :action => params[:back_to] if params[:back_to]
-      redirect_back_or_default :action => 'change_password'
-    end
-  end
-
-  protected
-    def do_change_password_for(user)
-      begin
-        User.transaction(user) do
-          user.change_password(params[:user][:password], params[:user][:password_confirmation])
-          if user.save
-            if LoginEngine.config(:use_email_notification)
-              UserNotify.deliver_change_password(user, params[:user][:password])
-              flash[:notice] = "Updated password emailed to #{@user.email}"
-            else
-              flash[:notice] = "Password updated."
-            end
-            return true
-          else
-            flash[:warning] = 'There was a problem saving the password. Please retry.'
-            return false
-          end
-        end
-      rescue
-        flash[:warning] = 'Password could not be changed at this time. Please retry.'
-      end
-    end
-    
-  public
-
-
-  def forgot_password
-    # Always redirect if logged in
-    if user?
-      flash[:message] = 'You are currently logged in. You may change your password now.'
-      redirect_to :action => 'change_password'
-      return
-    end
-
-    # Email disabled... we are unable to provide the password
-    if !LoginEngine.config(:use_email_notification)
-      flash[:message] = "Please contact the system admin at #{LoginEngine.config(:admin_email)} to reset your password."
-      redirect_back_or_default :action => 'login'
-      return
-    end
-
-    # Render on :get and render
-    return if generate_blank
-
-    # Handle the :post
-    if params[:user][:email].empty?
-      flash.now[:warning] = 'Please enter a valid email address.'
-    elsif (user = User.find_by_email(params[:user][:email])).nil?
-      flash.now[:warning] = "We could not find a user with the email address #{params[:user][:email]}"
-    else
-      begin
-        User.transaction(user) do
-          key = user.generate_security_token
-          url = url_for(:action => 'change_password', :user_id => user.id, :key => key)
-          UserNotify.deliver_forgot_password(user, url)
-          flash[:notice] = "Instructions on resetting your password have been emailed to #{params[:user][:email]}"
-        end  
-        unless user?
-          redirect_to :action => 'login'
-          return
-        end
-        redirect_back_or_default :action => 'home'
-      rescue
-        flash.now[:warning] = "Your password could not be emailed to #{params[:user][:email]}"
-      end
-    end
-  end
-
-  def edit
-    return if generate_filled_in
-    do_edit_user(@user)
-  end
-  
-  protected
-    def do_edit_user(user)
-      begin
-        User.transaction(user) do
-          user.attributes = params[:user].delete_if { |k,v| not LoginEngine.config(:changeable_fields).include?(k) }
-          if user.save
-            flash[:notice] = "User details updated"
-          else
-            flash[:warning] = "Details could not be updated! Please retry."
-          end
-        end
-      rescue
-        flash.now[:warning] = "Error updating user details. Please try again later."
-      end
-    end
-  
-  public
-
-  def delete
-    get_user_to_act_on
-    if do_delete_user(@user)
-      logout
-    else
-      redirect_back_or_default :action => 'home'
-    end    
-  end
-  
-  protected
-    def do_delete_user(user)
-      begin
-        if LoginEngine.config(:delayed_delete)
-          User.transaction(user) do
-            key = user.set_delete_after
-            if LoginEngine.config(:use_email_notification)
-              url = url_for(:action => 'restore_deleted', :user_id => user.id, :key => key)
-              UserNotify.deliver_pending_delete(user, url)
-            end
-          end
-        else
-          destroy(@user)
-        end
-        return true
-      rescue
-        if LoginEngine.config(:use_email_notification)
-          flash.now[:warning] = 'The delete instructions were not sent. Please try again later.'
-        else
-          flash.now[:notice] = 'The account has been scheduled for deletion. It will be removed in #{LoginEngine.config(:delayed_delete_days)} days.'
-        end
-        return false
-      end
-    end
-    
-  public
-
-  def restore_deleted
-    get_user_to_act_on
-    @user.deleted = 0
-    if not @user.save
-      flash.now[:warning] = "The account for #{@user['login']} was not restored. Please try the link again."
-      redirect_to :action => 'login'
-    else
-      redirect_to :action => 'home'
-    end
-  end
-
-  protected
-
-  def destroy(user)
-    UserNotify.deliver_delete(user) if LoginEngine.config(:use_email_notification)
-    flash[:notice] = "The account for #{user['login']} was successfully deleted."
-    user.destroy()
-  end
-
-  def protect?(action)
-    if ['login', 'signup', 'forgot_password'].include?(action)
-      return false
-    else
-      return true
-    end
-  end
-
-  # Generate a template user for certain actions on get
-  def generate_blank
-    case request.method
-    when :get
-      @user = User.new
-      render
-      return true
-    end
-    return false
-  end
-
-  # Generate a template user for certain actions on get
-  def generate_filled_in
-    get_user_to_act_on
-    case request.method
-    when :get
-      render
-      return true
-    end
-    return false
-  end
-  
-  # returns the user object this method should act upon; only really
-  # exists for other engines operating on top of this one to redefine...
-  def get_user_to_act_on
-    @user = session[:user]
-  end
-end
diff --git a/vendor/plugins/login_engine/app/helpers/user_helper.rb b/vendor/plugins/login_engine/app/helpers/user_helper.rb
deleted file mode 100755 (executable)
index 2dad7d8..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-module UserHelper
-
-  # Abstraction to make views a little cleaner
-  def form_input(helper_method, prompt, field_name=nil, options = {}, form_name = nil)
-    form_name = "user" if form_name.nil?
-    case helper_method.to_s
-    when 'hidden_field'
-      self.hidden_field(form_name, field_name, options)
-    when /^.*button$/
-      #prompt = l(:"#{@controller.controller_name}_#{field_name}_button")
-      <<-EOL
-      <tr><td class="button" colspan="2">
-        #{self.send(helper_method, form_name, prompt, options)}
-      </td></tr>
-      EOL
-    else
-      field = (
-        case helper_method
-        when :select
-          self.send(helper_method, form_name, field_name, options.delete('values'), options)
-        when :password_field
-          options[:value] = ""
-          self.send(helper_method, form_name, field_name, options)
-        else
-          self.send(helper_method, form_name, field_name, options)
-        end)
-#      lname = "#{form_name}_#{field_name}_form"
-#      prompt = l(:"#{lname}")
-      if LoginEngine.config(:two_column_input)
-<<-EOL
-        <tr class="two_columns">
-          <td class="prompt"><label>#{prompt}:</label></td>
-          <td class="value">#{field}</td>
-        </tr>
-        EOL
-      else
-<<-EOL
-        <tr><td class="prompt"><label>#{prompt}:</label></td></tr>
-        <tr><td class="value">#{field}</td></tr>
-        EOL
-      end
-    end
-  end
-
-#  def button_helper(name, options = {})
-#    label = l(:"#{@controller.controller_name}_#{name}_button")
-#    "#{self.send(:submit_tag, label, options)}"
-#  end
-
-#  def link_helper(name, options = {})
-#    raise ArgumentError if name.nil?
-#    label = l(:"#{@controller.controller_name}_#{name}_link")
-#    "#{self.send(:link_to, label, options)}"
-#  end
-
-  def title_helper
-    "#{@controller.controller_class_name} #{@controller.action_name}"
-  end
-
-#  def message_helper(name)
-#    l(:"#{@controller.controller_name}_#{name}_message")
-#  end
-
-  def start_form_tag_helper(options = {})
-    url = url_for(:action => "#{@controller.action_name}")
-    "#{self.send(:start_form_tag, url, options)}"
-  end
-
-  def attributes(hash)
-    hash.keys.inject("") { |attrs, key| attrs + %{#{key}="#{h(hash[key])}" } }
-  end
-
-  def read_only_field(form_name, field_name, html_options)
-    "<span #{attributes(html_options)}>#{instance_variable_get('@' + form_name)[field_name]}</span>"
-  end
-
-  def submit_button(form_name, prompt, html_options)
-    %{<input name="submit" type="submit" value="#{prompt}" />}
-  end
-
-  def changeable(user, field)
-    if user.new_record? or LoginEngine.config(:changeable_fields).include?(field)
-      :text_field
-    else
-      :read_only_field
-    end
-  end
-end
diff --git a/vendor/plugins/login_engine/app/models/user.rb b/vendor/plugins/login_engine/app/models/user.rb
deleted file mode 100755 (executable)
index 6a313fa..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-class User < ActiveRecord::Base
-  include LoginEngine::AuthenticatedUser
-
-  # all logic has been moved into login_engine/lib/login_engine/authenticated_user.rb
-
-end
-
diff --git a/vendor/plugins/login_engine/app/models/user_notify.rb b/vendor/plugins/login_engine/app/models/user_notify.rb
deleted file mode 100755 (executable)
index 0767842..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-class UserNotify < ActionMailer::Base
-  def signup(user, password, url=nil)
-    setup_email(user)
-
-    # Email header info
-    @subject += "Welcome to #{LoginEngine.config(:app_name)}!"
-
-    # Email body substitutions
-    @body["name"] = "#{user.firstname} #{user.lastname}"
-    @body["login"] = user.login
-    @body["password"] = password
-    @body["url"] = url || LoginEngine.config(:app_url).to_s
-    @body["app_name"] = LoginEngine.config(:app_name).to_s
-  end
-
-  def forgot_password(user, url=nil)
-    setup_email(user)
-
-    # Email header info
-    @subject += "Forgotten password notification"
-
-    # Email body substitutions
-    @body["name"] = "#{user.firstname} #{user.lastname}"
-    @body["login"] = user.login
-    @body["url"] = url || LoginEngine.config(:app_url).to_s
-    @body["app_name"] = LoginEngine.config(:app_name).to_s
-  end
-
-  def change_password(user, password, url=nil)
-    setup_email(user)
-
-    # Email header info
-    @subject += "Changed password notification"
-
-    # Email body substitutions
-    @body["name"] = "#{user.firstname} #{user.lastname}"
-    @body["login"] = user.login
-    @body["password"] = password
-    @body["url"] = url || LoginEngine.config(:app_url).to_s
-    @body["app_name"] = LoginEngine.config(:app_name).to_s
-  end
-
-  def pending_delete(user, url=nil)
-    setup_email(user)
-
-    # Email header info
-    @subject += "Delete user notification"
-
-    # Email body substitutions
-    @body["name"] = "#{user.firstname} #{user.lastname}"
-    @body["url"] = url || LoginEngine.config(:app_url).to_s
-    @body["app_name"] = LoginEngine.config(:app_name).to_s
-    @body["days"] = LoginEngine.config(:delayed_delete_days).to_s
-  end
-
-  def delete(user, url=nil)
-    setup_email(user)
-
-    # Email header info
-    @subject += "Delete user notification"
-
-    # Email body substitutions
-    @body["name"] = "#{user.firstname} #{user.lastname}"
-    @body["url"] = url || LoginEngine.config(:app_url).to_s
-    @body["app_name"] = LoginEngine.config(:app_name).to_s
-  end
-
-  def setup_email(user)
-    @recipients = "#{user.email}"
-    @from       = LoginEngine.config(:email_from).to_s
-    @subject    = "[#{LoginEngine.config(:app_name)}] "
-    @sent_on    = Time.now
-    @headers['Content-Type'] = "text/plain; charset=#{LoginEngine.config(:mail_charset)}; format=flowed"
-  end
-end
diff --git a/vendor/plugins/login_engine/app/views/user/_edit.rhtml b/vendor/plugins/login_engine/app/views/user/_edit.rhtml
deleted file mode 100755 (executable)
index e963d1c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<div class="user_edit">
-  <table>
-    <%= form_input changeable(user, "firstname"), "First Name", "firstname" %>
-    <%= form_input changeable(user, "lastname"), "Last Name","lastname" %>
-    <%= form_input changeable(user, "login"), "Login ID", "login", :size => 30 %><br/>
-    <%= form_input changeable(user, "email"), "Email", "email" %>
-    <% if submit %>
-      <%= form_input :submit_button, (user.new_record? ? 'Signup' : 'Change Settings'), :class => 'two_columns' %>
-    <% end %>
-  </table>
-</div>
diff --git a/vendor/plugins/login_engine/app/views/user/_password.rhtml b/vendor/plugins/login_engine/app/views/user/_password.rhtml
deleted file mode 100755 (executable)
index 27139f3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="user_password">
-  <table>
-    <%= form_input :password_field, "Password", "password", :size => 30 %>
-    <%= form_input :password_field, "Password Confirmation", "password_confirmation", :size => 30 %>
-    <% if submit %>
-      <%= form_input :submit_button, 'Change password' %>
-    <% end %>
-  </table>
-</div>                                                                          
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user/change_password.rhtml b/vendor/plugins/login_engine/app/views/user/change_password.rhtml
deleted file mode 100755 (executable)
index 3b5abe4..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<div title="<%= title_helper %>" class="form">
-  <h3>Change Password</h3>
-
-  <%= error_messages_for 'user' %>
-
-  <div class="form-padding">
-    <p>Enter your new password in the fields below and click 'Change Password' to have a new password sent to your email inbox.</p>
-
-    <%= start_form_tag :action => 'change_password' %>
-      <%= render_partial 'password', :user => @user, :submit => false %>
-      <div class="button-bar">
-        <%= submit_tag 'Change password' %>
-        <%= link_to 'Cancel', :action => 'home' %>
-      </div>
-    <%= end_form_tag %>
-  </div>
-</div>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user/edit.rhtml b/vendor/plugins/login_engine/app/views/user/edit.rhtml
deleted file mode 100755 (executable)
index efe7953..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<div title="<%= title_helper %>" class="form">
-  <h3>Edit user</h3>
-
-  <%= error_messages_for 'user' %>
-
-    <%= start_form_tag :action => 'edit' %>
-      <%= render_partial 'edit', :user => @user, :submit => true %>
-    <%= end_form_tag %>
-    <br/>
-    <%= start_form_tag :action => 'change_password' %>
-      <%= hidden_field_tag "back_to", "edit" %>
-      <%= render_partial 'password', :submit => true %>
-    <%= end_form_tag %>
-
-    <%= start_form_tag :action => 'delete' %>
-      <div class="user_delete">
-        <%= hidden_field 'user', 'form', :value => 'delete' %>
-
-        <%= form_input :submit_button, 'Delete Account' %>
-      </div>
-    <%= end_form_tag %>
-  </div>
-</div>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml b/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml
deleted file mode 100755 (executable)
index 66c7ce9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<div title="<%= title_helper %>" class="form">
-  <h3>Forgotten Password</h3>
-
-  <%= error_messages_for 'user' %>
-
-  <div class="form-padding">
-    <p>Enter your email address in the field below and click 'Reset Password' to have instructions on how to retrieve your forgotten password emailed to you.</p>
-
-    <%= start_form_tag_helper %>
-      <label>Email Address:</label> <%= text_field("user", "email", "size" => 30) %>
-
-      <div class="button-bar">
-        <%= submit_tag 'Reset Password' %>
-        <%= link_to 'Cancel', :action => 'login' %>
-      </div>
-    <%= end_form_tag %>
-  </div>
-</div>
diff --git a/vendor/plugins/login_engine/app/views/user/home.rhtml b/vendor/plugins/login_engine/app/views/user/home.rhtml
deleted file mode 100755 (executable)
index 019b865..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<div title="<%= title_helper %>" class="memo">
-  <h3>Welcome</h3>
-  <p>You are now logged into the system, <%= @fullname %>...</p>
-  <p>Since you are here it's safe to assume the application never called store_location, otherwise you would have been redirected somewhere else after a successful login.</p>
-
-  <%= link_to '&#171; logout', :action => 'logout' %>
-</div>
diff --git a/vendor/plugins/login_engine/app/views/user/login.rhtml b/vendor/plugins/login_engine/app/views/user/login.rhtml
deleted file mode 100755 (executable)
index 50a6eb3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<div title="<%= title_helper %>" class="form">
-  <h3>Please Login</h3>
-
-  <div class="form-padding">
-    <%= start_form_tag :action => 'login'  %>
-      <table>
-        <%= form_input :text_field, "Login ID", "login", :size => 30 %><br/>
-        <%= form_input :password_field, "Password", "password", :size => 30 %><br/>
-      </table>
-
-      <div class="button-bar">
-        <%= submit_tag 'Login' %>
-        <%= link_to 'Register for an account', :action => 'signup' %> |
-        <%= link_to 'Forgot my password', :action => 'forgot_password' %>      </div>
-    <%= end_form_tag %>
-  </div>
-</div>
diff --git a/vendor/plugins/login_engine/app/views/user/logout.rhtml b/vendor/plugins/login_engine/app/views/user/logout.rhtml
deleted file mode 100755 (executable)
index 18f8b3d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<div title="<%= title_helper %>" class="memo">
-  <h3>Logoff</h3>
-
-  <p>You are now logged out of the system...</p>
-
-  <%= link_to '&#171; login', :action => 'login' %>
-</div>
-
diff --git a/vendor/plugins/login_engine/app/views/user/signup.rhtml b/vendor/plugins/login_engine/app/views/user/signup.rhtml
deleted file mode 100755 (executable)
index c3a0cd3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<div title="<%= title_helper %>" class="form">
-  <h3>Signup</h3>
-
-  <%= error_messages_for 'user' %>
-
-  <div class="form-padding">
-    <%= start_form_tag :action => 'signup' %>
-      <%= render_partial 'edit', :user => @user, :submit => false %><br/>
-      <%= render_partial 'password', :submit => false %>
-
-      <div class="button-bar">
-        <%= submit_tag 'Signup' %>
-        <%= link_to 'Cancel', :action => 'login' %>
-      </div>
-    <%= end_form_tag %>
-  </div>
-</div>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml b/vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml
deleted file mode 100755 (executable)
index 7c0933f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-Dear <%= @name %>,
-
-At your request, <%= @app_name %> has changed your password. If it was not at your request, then you should be aware that someone has access to your account and requested this change.
-
-Your new login credentials are:
-
-  login:    <%= @login %>
-  password: <%= @password %>
-<%= @url %>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user_notify/delete.rhtml b/vendor/plugins/login_engine/app/views/user_notify/delete.rhtml
deleted file mode 100755 (executable)
index de91707..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Dear <%= @name %>,
-
-At your request, <%= @app_name %> has permanently deleted your account.
-<%= @url %>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml b/vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml
deleted file mode 100755 (executable)
index 17f36c3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-Dear <%= @name %>,
-
-At your request, <%= @app_name %> has sent you the following URL so that you may reset your password. If it was not at your request, then you should be aware that someone has entered your email address as theirs in the forgotten password section of <%= @app_name %>.
-
-Please click on the following link to go to the change password page:
-
-<a href="<%= @url%>">Click me!</a>
-It's advisable for you to change your password as soon as you login. It's as simple as navigating to 'Preferences' and clicking on 'Change Password'.
-
-<%= @url %>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml b/vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml
deleted file mode 100755 (executable)
index 84e200e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Dear <%= @name %>,
-
-At your request, <%= @app_name %> has marked your account for deletion. If it was not at your request, then you should be aware that someone has access to your account and requested this change.
-
-The following link is provided for you to restore your deleted account. If you click on this link within the next <%= @days %> days, your account will not be deleted. Otherwise, simply ignore this email and your account will be permanently deleted after that time.
-
-<a href="<%= @url%>">Click me!</a>
-<%= @url %>
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/app/views/user_notify/signup.rhtml b/vendor/plugins/login_engine/app/views/user_notify/signup.rhtml
deleted file mode 100755 (executable)
index ae2626c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Welcome to <%= @app_name %>, <%= @name %>.
-
-Your login credentials are:
-
-  login:    <%= @login %>
-  password: <%= @password %>
-
-Please click on the following link to confirm your registration:
-
-<a href="<%= @url%>">Click me!</a>
-
-<%= @url %>
diff --git a/vendor/plugins/login_engine/db/migrate/001_initial_schema.rb b/vendor/plugins/login_engine/db/migrate/001_initial_schema.rb
deleted file mode 100755 (executable)
index 6af212c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-class InitialSchema < ActiveRecord::Migration
-  def self.up
-    create_table LoginEngine.config(:user_table), :force => true do |t|
-      t.column "login", :string, :limit => 80, :default => "", :null => false
-      t.column "salted_password", :string, :limit => 40, :default => "", :null => false
-      t.column "email", :string, :limit => 60, :default => "", :null => false
-      t.column "firstname", :string, :limit => 40
-      t.column "lastname", :string, :limit => 40
-      t.column "salt", :string, :limit => 40, :default => "", :null => false
-      t.column "verified", :integer, :default => 0
-      t.column "role", :string, :limit => 40
-      t.column "security_token", :string, :limit => 40
-      t.column "token_expiry", :datetime
-      t.column "created_at", :datetime
-      t.column "updated_at", :datetime
-      t.column "logged_in_at", :datetime
-      t.column "deleted", :integer, :default => 0
-      t.column "delete_after", :datetime
-    end
-  end
-
-  def self.down
-    drop_table LoginEngine.config(:user_table)
-  end
-end
diff --git a/vendor/plugins/login_engine/init_engine.rb b/vendor/plugins/login_engine/init_engine.rb
deleted file mode 100755 (executable)
index a959da0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# load up all the required files we need...
-
-require 'login_engine'
-
-module LoginEngine::Version
-  Major = 1
-  Minor = 0
-  Release = 2
-end
-
-Engines.current.version = LoginEngine::Version
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/install.rb b/vendor/plugins/login_engine/install.rb
deleted file mode 100755 (executable)
index 523280c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# Install the engines plugin if it has been already
-unless File.exist?(File.dirname(__FILE__) + "/../engines")
-  Commands::Plugin.parse!(['install', 'http://svn.rails-engines.org/plugins/engines']) 
-end
\ No newline at end of file
diff --git a/vendor/plugins/login_engine/lib/login_engine.rb b/vendor/plugins/login_engine/lib/login_engine.rb
deleted file mode 100755 (executable)
index 6164603..0000000
+++ /dev/null
@@ -1,62 +0,0