diff --git a/.gitignore b/.gitignore
index 280bfd5..54583c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,3 @@ _site/
 jhw.*.html
 coverage/
 tmp/
-cache dir/
diff --git a/Gemfile b/Gemfile
index b736b0d..f04a59b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,25 +6,18 @@ gemspec
 gem 'rspec'
 gem 'fakefs', :require => nil
 gem 'guard'
-
 gem 'guard-rspec'
 gem 'guard-shell'
 gem 'guard-coffeescript'
-gem 'guard-cucumber'
+gem 'growl'
+gem 'rake', '0.8.7'
+gem 'mocha', '0.9.12'
+gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git'
+gem 'facter'
 
-require 'rbconfig'
-case RbConfig::CONFIG['host_os']
-when /darwin/
-when /linux/
-  gem 'libnotify'
-end
-
-gem 'mocha'
-
-gem 'cucumber'
-
-gem 'jquery-rails', '~> 1.0.0'
+gem 'jquery-rails'
 gem 'ejs'
 
-gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git'
+gem 'simplecov'
+#gem 'perftools.rb'
 
diff --git a/Guardfile b/Guardfile
index 620fcd4..38c2dc6 100644
--- a/Guardfile
+++ b/Guardfile
@@ -22,18 +22,13 @@ guard 'rspec', :version => 2, :all_on_start => false do
   watch('spec/spec_helper.rb') { "spec" }
 end
 
-guard 'cucumber', :cli => '-r features --format pretty' do
-  watch(%r{^features/.+\.feature$})
-  watch(%r{^features/support/.+$})          { 'features' }
-  watch(%r{^features/steps/(.+)_steps\.rb$}) { 'features' }
-end
-
 guard 'jasmine-headless-webkit', :all_on_start => false do
   watch(%r{^spec/javascripts/.+_spec\.coffee})
   watch(%r{^jasmine/(.+)\.coffee$}) { |m| "spec/javascripts/#{m[1]}_spec.coffee" }
 end
 
 def compile
+  #system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb}
   system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb}
 end
 
diff --git a/README.md b/README.md
index 18a02b2..1df0ad5 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-_I am looking for a new maintainer for this project. Please contact me via GitHub if you're interested._
-
 # Jasmine Headless WebKit runner
 
 Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns!
diff --git a/Rakefile b/Rakefile
index 3dcac83..6f33603 100644
--- a/Rakefile
+++ b/Rakefile
@@ -14,7 +14,7 @@ require 'jasmine/headless/task'
 
 Jasmine::Headless::Task.new
 
-PLATFORMS = %w{1.9.2 1.9.3}
+PLATFORMS = %w{1.8.7 1.9.2 ree 1.9.3-rc1}
 
 def rvm_bundle(command = '')
   Bundler.with_clean_env do
@@ -30,7 +30,6 @@ namespace :spec do
   task :platforms do
     rvm_bundle
     rvm_bundle "exec rspec spec"
-    rvm_bundle "exec cucumber"
     raise SpecError.new if $?.exitstatus != 0
   end
 end
diff --git a/config/cucumber.yml b/config/cucumber.yml
deleted file mode 100644
index a061551..0000000
--- a/config/cucumber.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-default: -r features
-
diff --git a/ext/jasmine-webkit-specrunner/Page.cpp b/ext/jasmine-webkit-specrunner/Page.cpp
index cdfa396..b3f6c3d 100644
--- a/ext/jasmine-webkit-specrunner/Page.cpp
+++ b/ext/jasmine-webkit-specrunner/Page.cpp
@@ -11,5 +11,6 @@ void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, con
 }
 
 void Page::javaScriptAlert(QWebFrame *, const QString &) {}
-bool Page::javaScriptConfirm(QWebFrame *, const QString &) { return false; }
-bool Page::javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *) { return false; }
+bool Page::javaScriptConfirm(QWebFrame *, const QString &) {
+  return false;
+}
diff --git a/ext/jasmine-webkit-specrunner/Page.h b/ext/jasmine-webkit-specrunner/Page.h
index bae094d..74c6f77 100644
--- a/ext/jasmine-webkit-specrunner/Page.h
+++ b/ext/jasmine-webkit-specrunner/Page.h
@@ -12,7 +12,6 @@ class Page: public QWebPage {
     void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
     void javaScriptAlert(QWebFrame *, const QString &);
     bool javaScriptConfirm(QWebFrame *, const QString &);
-    bool javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *);
   signals:
     void handleError(const QString & message, int lineNumber, const QString & sourceID);
 };
diff --git a/ext/jasmine-webkit-specrunner/Runner.cpp b/ext/jasmine-webkit-specrunner/Runner.cpp
index 66943a5..e5e03a5 100644
--- a/ext/jasmine-webkit-specrunner/Runner.cpp
+++ b/ext/jasmine-webkit-specrunner/Runner.cpp
@@ -18,7 +18,6 @@ Runner::Runner() : QObject()
   , usedConsole(false)
   , isFinished(false)
   , useColors(false)
-  , quiet(false)
   {
   page.settings()->enablePersistentStorage();
   ticker.setInterval(TIMER_TICK);
@@ -63,17 +62,17 @@ void Runner::handleError(const QString &message, int lineNumber, const QString &
 
 void Runner::loadSpec()
 {
-  QVectorIterator<QString> iterator(reportFiles);
-
-  while (iterator.hasNext()) {
-    QFile *outputFile = new QFile(iterator.next());
+  if (reportFileName.isEmpty()) {
+    outputFile = 0;
+    ts = 0;
+  } else {
+    outputFile = new QFile(reportFileName);
     outputFile->open(QIODevice::WriteOnly);
-    outputFiles.enqueue(outputFile);
+
+    ts = new QTextStream(outputFile);
   }
 
-  QString runnerFile = runnerFiles.dequeue();
-
-  page.mainFrame()->load(runnerFile);
+  page.mainFrame()->load(runnerFiles.dequeue());
   ticker.start();
 }
 
@@ -105,8 +104,8 @@ void Runner::hasSpecFailure() {
   _hasSpecFailure = true;
 }
 
-void Runner::setReportFiles(QStack<QString> &files) {
-  reportFiles = files;
+void Runner::reportFile(const QString &file) {
+  reportFileName = file;
 }
 
 void Runner::timerPause() {
@@ -121,22 +120,6 @@ void Runner::ping() {
   runs = 0;
 }
 
-void Runner::setSeed(QString s) {
-  seed = s;
-}
-
-void Runner::setQuiet(bool q) {
-  quiet = q;
-}
-
-QString Runner::getSeed() {
-  return seed;
-}
-
-bool Runner::isQuiet() {
-  return quiet;
-}
-
 void Runner::print(const QString &fh, const QString &content) {
   if (fh == "stdout") {
     std::cout << qPrintable(content);
@@ -148,18 +131,14 @@ void Runner::print(const QString &fh, const QString &content) {
     std::cerr.flush();
   }
 
-  if (fh.contains("report")) {
-    int index = (int)fh.split(":").last().toUInt();
-
-    QTextStream ts(outputFiles.at(index));
-    ts << qPrintable(content);
-    ts.flush();
+  if (fh == "report" && outputFile) {
+    *ts << qPrintable(content);
+    ts->flush();
   }
 }
 
 void Runner::finishSuite() {
   isFinished = true;
-  runs = 0;
 }
 
 void Runner::timerEvent() {
@@ -168,9 +147,9 @@ void Runner::timerEvent() {
   if (hasErrors && runs > 2)
     QApplication::instance()->exit(1);
 
-  if (isFinished && runs > 2) {
-    while (!outputFiles.isEmpty()) {
-      outputFiles.dequeue()->close();
+  if (isFinished) {
+    if (outputFile) {
+      outputFile->close();
     }
 
     int exitCode = 0;
diff --git a/ext/jasmine-webkit-specrunner/Runner.h b/ext/jasmine-webkit-specrunner/Runner.h
index 3f1f01b..03e2c53 100644
--- a/ext/jasmine-webkit-specrunner/Runner.h
+++ b/ext/jasmine-webkit-specrunner/Runner.h
@@ -7,9 +7,7 @@
 #include <QTextStream>
 #include <iostream>
 #include <fstream>
-#include <sstream>
 #include <QQueue>
-#include <QApplication>
 
 #include "Page.h"
 
@@ -22,10 +20,7 @@ class Runner: public QObject {
 
     Runner();
     void setColors(bool colors);
-    void setReportFiles(QStack<QString> &files);
-    void setSeed(QString s);
-    void setQuiet(bool q);
-
+    void reportFile(const QString &file);
     void addFile(const QString &spec);
     void go();
 
@@ -35,10 +30,6 @@ class Runner: public QObject {
     void hasUsedConsole();
     void hasError();
     void hasSpecFailure();
-
-    bool isQuiet();
-    QString getSeed();
-
     void print(const QString &fh, const QString &content);
     void finishSuite();
     void ping();
@@ -58,16 +49,15 @@ class Runner: public QObject {
     bool usedConsole;
     bool isFinished;
     bool useColors;
-    bool quiet;
-
-    QString seed;
 
     QQueue<QString> runnerFiles;
-    QStack<QString> reportFiles;
+
+    QString reportFileName;
 
     void loadSpec();
 
-    QQueue<QFile *> outputFiles;
+    QFile *outputFile;
+    QTextStream *ts;
 };
 
 #endif
diff --git a/ext/jasmine-webkit-specrunner/common.pri b/ext/jasmine-webkit-specrunner/common.pri
index b80fe37..0320485 100644
--- a/ext/jasmine-webkit-specrunner/common.pri
+++ b/ext/jasmine-webkit-specrunner/common.pri
@@ -1,6 +1,7 @@
 TEMPLATE = app
 CONFIG -= app_bundle
 QMAKE_INFO_PLIST = Info.plist
+QMAKESPEC = macx-g++
 QT += network webkit
 
 SOURCES = Page.cpp Runner.cpp
diff --git a/ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro b/ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro
new file mode 100644
index 0000000..e6710d1
--- /dev/null
+++ b/ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro
@@ -0,0 +1,19 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Tue Aug 2 10:37:48 2011
+######################################################################
+
+TEMPLATE = app
+TARGET = 
+DEPENDPATH += . HeadlessSpecRunner Test
+INCLUDEPATH += . HeadlessSpecRunner Test
+
+# Input
+HEADERS += HeadlessSpecRunner/ConsoleOutput.h \
+           HeadlessSpecRunner/Page.h \
+           HeadlessSpecRunner/Runner.h \
+           Test/Page_test.h
+SOURCES += specrunner.cpp \
+           HeadlessSpecRunner/ConsoleOutput.cpp \
+           HeadlessSpecRunner/Page.cpp \
+           HeadlessSpecRunner/Runner.cpp \
+           Test/Page_test.cpp
diff --git a/ext/jasmine-webkit-specrunner/specrunner.cpp b/ext/jasmine-webkit-specrunner/specrunner.cpp
index 9f961d7..c0e969f 100644
--- a/ext/jasmine-webkit-specrunner/specrunner.cpp
+++ b/ext/jasmine-webkit-specrunner/specrunner.cpp
@@ -29,44 +29,34 @@
 
 int main(int argc, char** argv)
 {
-  bool showColors = false;
-  bool isQuiet = false;
-  QString seed;
-  QStack<QString> reporterFiles;
+  char *reporter = NULL;
+  char showColors = false;
 
   int c, index;
 
-  while ((c = getopt(argc, argv, "cr:s:q")) != -1) {
+  while ((c = getopt(argc, argv, "cr:")) != -1) {
     switch(c) {
       case 'c':
         showColors = true;
         break;
-      case 'q':
-        isQuiet = true;
-        break;
       case 'r':
-        reporterFiles.push(QString(optarg));
-        break;
-      case 's':
-        seed = QString(optarg);
+        reporter = optarg;
         break;
     }
   }
 
   if (optind == argc) {
     std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl;
-    std::cerr << "  specrunner [-c] [-s seed] [-r report file ...] specrunner.html ..." << std::endl;
+    std::cerr << "  specrunner [-c] [-r <report file>] specrunner.html ..." << std::endl;
     return 1;
   }
 
   QApplication app(argc, argv);
   app.setApplicationName("jasmine-headless-webkit");
   Runner runner;
-
   runner.setColors(showColors);
-  runner.setQuiet(isQuiet);
-  runner.setReportFiles(reporterFiles);
-  runner.setSeed(seed);
+
+  runner.reportFile(reporter);
 
   for (index = optind; index < argc; index++) {
     runner.addFile(QString::fromLocal8Bit(argv[index]));
diff --git a/features/bin/failure.feature b/features/bin/failure.feature
deleted file mode 100644
index 56e2aa5..0000000
--- a/features/bin/failure.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Failure
-  Scenario: Run a failing test
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml -f File:spec/report.txt`
-    Then the exit status should be 1
-      And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
-
diff --git a/features/bin/files.feature b/features/bin/files.feature
deleted file mode 100644
index 37f3af3..0000000
--- a/features/bin/files.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Files
-  Scenario: List the files a test suite will use
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml -l`
-    Then the exit status should be 0
-      And the output should include "spec/jasmine/success/success.js"
-      And the output should include "spec/jasmine/success/success_spec.js"
diff --git a/features/bin/filtered_run/both_runs.feature b/features/bin/filtered_run/both_runs.feature
deleted file mode 100644
index 03953a8..0000000
--- a/features/bin/filtered_run/both_runs.feature
+++ /dev/null
@@ -1,18 +0,0 @@
-Feature: Bin - Filtered Run - Both Runs
-  Background:
-    Given there is no existing "spec/report.txt" file
-
-  Scenario: Run one and fail
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml -f File:spec/report.txt ./spec/jasmine/filtered_failure/failure_spec.js`
-    Then the exit status should be 1
-      And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
-
-  Scenario: Run both and succeed
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success/success_one_spec.js`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage
-
-  Scenario: Run both with console.log
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success_with_console/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success_with_console/success_one_spec.js`
-    Then the exit status should be 2
-      And the report file "spec/report.txt" should have 2 total, 0 failures, yes console usage
diff --git a/features/bin/filtered_run/no_full_run.feature b/features/bin/filtered_run/no_full_run.feature
deleted file mode 100644
index 0b1f1e8..0000000
--- a/features/bin/filtered_run/no_full_run.feature
+++ /dev/null
@@ -1,14 +0,0 @@
-Feature: Bin - No Full Run
-  Background:
-    Given there is no existing "spec/report.txt" file
-
-  Scenario: Only run the filtered run
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt --no-full-run ./spec/jasmine/filtered_success/success_one_spec.js`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage
-
-  Scenario: Use a file outside of the normal test run
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success/success_other_file.js`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage
-
diff --git a/features/bin/help.feature b/features/bin/help.feature
deleted file mode 100644
index cf3461d..0000000
--- a/features/bin/help.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Help
-  Scenario: Display the Help
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -h`
-    Then I should get help output
-      And the exit status should be 0
-
diff --git a/features/bin/quiet_messages.feature b/features/bin/quiet_messages.feature
deleted file mode 100644
index 36be433..0000000
--- a/features/bin/quiet_messages.feature
+++ /dev/null
@@ -1,8 +0,0 @@
-Feature: Bin - Quiet Messages
-  Scenario: Run a test that would cause a lot of messages to be displayed and silence them all
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -q -j spec/jasmine/noisy/noisy.yml`
-    Then the exit status should be 0
-      And the output should not include "[Skipping File]"
-      And the output should not include "You should mock"
-
diff --git a/features/bin/runner_out.feature b/features/bin/runner_out.feature
deleted file mode 100644
index bdafe76..0000000
--- a/features/bin/runner_out.feature
+++ /dev/null
@@ -1,8 +0,0 @@
-Feature: Bin - Runner Out
-  Scenario: Write out the runner to a specified file
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --runner-out spec/runner.html`
-    Then the exit status should be 0
-      And the file "spec/runner.html" should contain a JHW runner
-    When I delete the file "spec/runner.html"
-
diff --git a/features/bin/spec_files_with_same_basename.feature b/features/bin/spec_files_with_same_basename.feature
deleted file mode 100644
index 753fc60..0000000
--- a/features/bin/spec_files_with_same_basename.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Two spec files with same basename
-  Scenario: Run both files
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_spec_files_same_basename/jasmine.yml -f File:spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage
-
diff --git a/features/bin/success.feature b/features/bin/success.feature
deleted file mode 100644
index b87239e..0000000
--- a/features/bin/success.feature
+++ /dev/null
@@ -1,20 +0,0 @@
-Feature: Bin - Success
-  Scenario: Run a successful test with long format definition
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit --seed 1234 -j spec/jasmine/success/success.yml --format File --out spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
-      And the report file "spec/report.txt" should have seed 1234
-
-  Scenario: Run a successful test with legacy file reporting
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
-
-  Scenario: Run a successful test with shortened format definition
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml -f File:spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
-
diff --git a/features/bin/success_with_js_error.feature b/features/bin/success_with_js_error.feature
deleted file mode 100644
index b899e97..0000000
--- a/features/bin/success_with_js_error.feature
+++ /dev/null
@@ -1,5 +0,0 @@
-Feature: Bin - Success with JS Error
-  Scenario: Succeed
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml -f File:spec/report.txt`
-    Then the exit status should be 1
diff --git a/features/bin/tries_to_leave_page.feature b/features/bin/tries_to_leave_page.feature
deleted file mode 100644
index 3e037c3..0000000
--- a/features/bin/tries_to_leave_page.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Try to Leave Page
-  Scenario: Fail on trying to leave the page
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/leave_page/leave_page.yml -f File:spec/report.txt`
-    Then the exit status should be 1
-      And the report file "spec/report.txt" should exist
-
diff --git a/features/bin/try_to_click_a_button.feature b/features/bin/try_to_click_a_button.feature
deleted file mode 100644
index f0824e0..0000000
--- a/features/bin/try_to_click_a_button.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - Try to Click A Button
-  Scenario: Don't leave page when clicking a button
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/click_button/click_button.yml -f File:spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 0 total, 0 failures, no console usage
-
diff --git a/features/bin/two_files_from_src_files.feature b/features/bin/two_files_from_src_files.feature
deleted file mode 100644
index af7efab..0000000
--- a/features/bin/two_files_from_src_files.feature
+++ /dev/null
@@ -1,11 +0,0 @@
-Feature: Two files from source files
-  Scenario: Files are ordered directly
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_files_from_src_files/jasmine.yml -l`
-    Then the exit status should be 0
-      And the following files should be loaded in order:
-        | vendor/vendor-file.js |
-        | vendor/vendor.js |
-        | app/app-file.js |
-        | app/app.js |
-
diff --git a/features/bin/with_coffeescript_error.feature b/features/bin/with_coffeescript_error.feature
deleted file mode 100644
index 442851b..0000000
--- a/features/bin/with_coffeescript_error.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - With CoffeeScript error
-  Scenario: Fail on CoffeeScript error
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/coffeescript_error/coffeescript_error.yml -f File:spec/report.txt`
-    Then the exit status should be 1
-      And the report file "spec/report.txt" should not exist
-
diff --git a/features/bin/with_console_log.feature b/features/bin/with_console_log.feature
deleted file mode 100644
index 734d983..0000000
--- a/features/bin/with_console_log.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Use console.log
-  Scenario: Run a successful test that uses console.log
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml -f File:spec/report.txt`
-    Then the exit status should be 2
-      And the report file "spec/report.txt" should have 1 total, 0 failures, yes console usage
-
diff --git a/features/bin/with_server.feature b/features/bin/with_server.feature
deleted file mode 100644
index 6e9fa03..0000000
--- a/features/bin/with_server.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - With Server
-  Scenario: Run using an HTTP server
-    Given there is no existing "spec/report.txt" file
-    When I run `bin/jasmine-headless-webkit --use-server -j spec/jasmine/success/success.yml -f File:spec/report.txt`
-    Then the exit status should be 0
-      And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
-
diff --git a/features/bin/with_window_prompt.feature b/features/bin/with_window_prompt.feature
deleted file mode 100644
index 0f1dac1..0000000
--- a/features/bin/with_window_prompt.feature
+++ /dev/null
@@ -1,7 +0,0 @@
-Feature: Bin - With window.prompt()
-  Scenario: Alert the user that window.prompt() needs to be stubbed
-    Given I have a test suite
-    When I run `bin/jasmine-headless-webkit -j spec/jasmine/window_prompt/window_prompt.yml`
-    Then the exit status should be 0
-      And the output should include "You should mock window.prompt"
-
diff --git a/features/reporters.feature b/features/reporters.feature
deleted file mode 100644
index 76dfdd7..0000000
--- a/features/reporters.feature
+++ /dev/null
@@ -1,24 +0,0 @@
-Feature: Reporters
-  In order to allow for multiple types of output
-  I should be able to
-  Manage reporters and decide which ones to use
-
-  Scenario: Use default reporters
-    Given I have the default runner options
-    When I get a runner
-      And I get a template writer
-    Then the template should use the "Console" reporter to "stdout"
-      And the command to run the runner should not include a report file
-
-  Scenario: Use a file reporter
-    Given I have the default runner options
-      And I have the following reporters:
-        | Name | File |
-        | Console | |
-        | File | file |
-    When I get a runner
-      And I get a template writer
-    Then the template should use the "Console" reporter to "stdout"
-      And the template should use the "File" reporter to "report:0"
-      And the command to run the runner should include the report file "file"
-
diff --git a/features/runner.feature b/features/runner.feature
deleted file mode 100644
index 81f69d4..0000000
--- a/features/runner.feature
+++ /dev/null
@@ -1,34 +0,0 @@
-Feature: Using the Runner directly
-  Scenario: Succeed
-    Given I have the following runner options:
-      """
-      :jasmine_config: spec/jasmine/success/success.yml
-      :reporters:
-      - [ 'File', 'spec/report.txt' ]
-      """
-    When I get a runner
-      And I run the runner
-    Then the runner should have an exit status of 0
-    And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
-
-  Scenario: JavaScript Error
-    Given I have the following runner options:
-      """
-      :jasmine_config: spec/jasmine/success_with_error/success_with_error.yml
-      """
-    When I get a runner
-      And I run the runner
-    Then the runner should have an exit status of 1
-
-  Scenario: Failure
-    Given I have the following runner options:
-      """
-      :jasmine_config: spec/jasmine/failure/failure.yml
-      :reporters:
-      - [ 'File', 'spec/report.txt' ]
-      """
-    When I get a runner
-      And I run the runner
-    Then the runner should have an exit status of 1
-    And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
-
diff --git a/features/steps/given/i_have_test_suite.rb b/features/steps/given/i_have_test_suite.rb
deleted file mode 100644
index 5efab54..0000000
--- a/features/steps/given/i_have_test_suite.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-Given /^I have a test suite$/ do
-end
diff --git a/features/steps/given/no_existing_file.rb b/features/steps/given/no_existing_file.rb
deleted file mode 100644
index 04a8b15..0000000
--- a/features/steps/given/no_existing_file.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Given /^there is no existing "([^"]*)" file$/ do |file|
-  FileUtils.rm_rf file
-end
-
diff --git a/features/steps/given/options/i_have_defaults.rb b/features/steps/given/options/i_have_defaults.rb
deleted file mode 100644
index 03e7971..0000000
--- a/features/steps/given/options/i_have_defaults.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Given /^I have the default runner options$/ do
-  @options = Jasmine::Headless::Options.new
-end
-
diff --git a/features/steps/given/options/i_have_reporters.rb b/features/steps/given/options/i_have_reporters.rb
deleted file mode 100644
index 60ffb68..0000000
--- a/features/steps/given/options/i_have_reporters.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-Given /^I have the following reporters:$/ do |table|
-  @options[:reporters] = []
-
-  table.hashes.each do |hash|
-    reporter = [ hash['Name'] ]
-    reporter << hash['File'] if !hash['File'].empty?
-
-    @options[:reporters] << reporter
-  end
-end
diff --git a/features/steps/given/options/i_have_runner_options.rb b/features/steps/given/options/i_have_runner_options.rb
deleted file mode 100644
index 93b76d9..0000000
--- a/features/steps/given/options/i_have_runner_options.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Given /^I have the following runner options:$/ do |string|
-  @options = YAML.load(string)
-end
diff --git a/features/steps/then/bin/exit_status_should_be.rb b/features/steps/then/bin/exit_status_should_be.rb
deleted file mode 100644
index 0e6992c..0000000
--- a/features/steps/then/bin/exit_status_should_be.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Then /^the exit status should be (\d+)$/ do |exitstatus|
-  $?.exitstatus.should == exitstatus.to_i
-end
diff --git a/features/steps/then/bin/file_should_contain_runner.rb b/features/steps/then/bin/file_should_contain_runner.rb
deleted file mode 100644
index 7904498..0000000
--- a/features/steps/then/bin/file_should_contain_runner.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^the file "([^"]*)" should contain a JHW runner$/ do |file|
-  File.read(file).should include('jasmine.HeadlessReporter')
-end
-
diff --git a/features/steps/then/bin/following_files_loaded_in_order.rb b/features/steps/then/bin/following_files_loaded_in_order.rb
deleted file mode 100644
index 7370d8c..0000000
--- a/features/steps/then/bin/following_files_loaded_in_order.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-Then /^the following files should be loaded in order:$/ do |table|
-  files = table.raw.flatten
-
-  @output.lines.collect(&:strip).each do |line|
-    files.shift if line[files.first]
-  end
-
-  files.should be_empty
-end
-
diff --git a/features/steps/then/bin/i_should_get_help_output.rb b/features/steps/then/bin/i_should_get_help_output.rb
deleted file mode 100644
index 70a252c..0000000
--- a/features/steps/then/bin/i_should_get_help_output.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^I should get help output$/ do
-  @output.should include("Usage:")
-end
-
diff --git a/features/steps/then/bin/output_should_include.rb b/features/steps/then/bin/output_should_include.rb
deleted file mode 100644
index d52cb68..0000000
--- a/features/steps/then/bin/output_should_include.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Then /^the output should include "([^"]*)"$/ do |string|
-  @output.should include(string)
-end
diff --git a/features/steps/then/bin/output_should_not_include.rb b/features/steps/then/bin/output_should_not_include.rb
deleted file mode 100644
index e4a1716..0000000
--- a/features/steps/then/bin/output_should_not_include.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^the output should not include "([^"]*)"$/ do |string|
-  @output.should_not include(string)
-end
-
diff --git a/features/steps/then/reporting/report_does_not_exist.rb b/features/steps/then/reporting/report_does_not_exist.rb
deleted file mode 100644
index 2cff304..0000000
--- a/features/steps/then/reporting/report_does_not_exist.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^the report file "([^"]*)" should not exist$/ do |file|
-  File.file?(file).should be_false
-end
-
diff --git a/features/steps/then/reporting/report_should_exist.rb b/features/steps/then/reporting/report_should_exist.rb
deleted file mode 100644
index d7b5859..0000000
--- a/features/steps/then/reporting/report_should_exist.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Then /^the report file "([^"]*)" should exist$/ do |file|
-  File.file?(file).should be_true
-end
diff --git a/features/steps/then/reporting/report_should_have.rb b/features/steps/then/reporting/report_should_have.rb
deleted file mode 100644
index ef2ad58..0000000
--- a/features/steps/then/reporting/report_should_have.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-Then /^the report file "(.*)" should have (\d+) total, (\d+) failures?, (no|yes) console usage$/ do |file, total, failures, console_usage|
-  report = Jasmine::Headless::Report.load(file)
-
-  report.total.should == total.to_i
-  report.failed.should == failures.to_i
-  report.has_used_console?.should == (console_usage == 'yes')
-end
diff --git a/features/steps/then/reporting/report_should_have_seed.rb b/features/steps/then/reporting/report_should_have_seed.rb
deleted file mode 100644
index ec905a3..0000000
--- a/features/steps/then/reporting/report_should_have_seed.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^the report file "([^"]*)" should have seed (\d+)$/ do |file, seed|
-  report = Jasmine::Headless::Report.load(file)
-  report.seed.should == seed.to_i
-end
diff --git a/features/steps/then/runner/it_should_have_exit_status.rb b/features/steps/then/runner/it_should_have_exit_status.rb
deleted file mode 100644
index a788e4a..0000000
--- a/features/steps/then/runner/it_should_have_exit_status.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Then /^the runner should have an exit status of (\d+)$/ do |exit_status|
-  @result.should == exit_status.to_i
-end
diff --git a/features/steps/then/runner/it_should_include_report_file.rb b/features/steps/then/runner/it_should_include_report_file.rb
deleted file mode 100644
index 0dd465a..0000000
--- a/features/steps/then/runner/it_should_include_report_file.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-Then /^the command to run the runner should include the report file "([^"]*)"$/ do |file|
-  @runner.jasmine_command.should include("-r #{file}")
-end
-
diff --git a/features/steps/then/runner/it_should_not_include_report_file.rb b/features/steps/then/runner/it_should_not_include_report_file.rb
deleted file mode 100644
index 28a7417..0000000
--- a/features/steps/then/runner/it_should_not_include_report_file.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-Then /^the command to run the runner should not include a report file$/ do
-  @runner.jasmine_command.should_not include('-r')
-end
diff --git a/features/steps/then/templates/it_should_use_reporter.rb b/features/steps/then/templates/it_should_use_reporter.rb
deleted file mode 100644
index d9a98cc..0000000
--- a/features/steps/then/templates/it_should_use_reporter.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-Then /^the template should use the "([^"]*)" reporter to "([^"]*)"$/ do |reporter, target|
-  output = @template_writer.render
-
-  output.should include(%{jasmine.HeadlessReporter.#{reporter}("#{target}")})
-end
-
diff --git a/features/steps/when/i_delete_file.rb b/features/steps/when/i_delete_file.rb
deleted file mode 100644
index c22c5d0..0000000
--- a/features/steps/when/i_delete_file.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-When /^I delete the file "([^"]*)"$/ do |file|
-  FileUtils.rm_f(file)
-end
diff --git a/features/steps/when/i_get_runner.rb b/features/steps/when/i_get_runner.rb
deleted file mode 100644
index ed1b2e6..0000000
--- a/features/steps/when/i_get_runner.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-When /^I get a runner$/ do
-  @runner = Jasmine::Headless::Runner.new(@options)
-end
-
diff --git a/features/steps/when/i_get_template_writer.rb b/features/steps/when/i_get_template_writer.rb
deleted file mode 100644
index 77c1e2c..0000000
--- a/features/steps/when/i_get_template_writer.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-When /^I get a template writer$/ do
-  @template_writer = Jasmine::Headless::TemplateWriter.new(@runner)
-end
-
diff --git a/features/steps/when/i_run_executable.rb b/features/steps/when/i_run_executable.rb
deleted file mode 100644
index 06faa72..0000000
--- a/features/steps/when/i_run_executable.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-When /^I run `(.*)`$/ do |command|
-  @output = `#{command}`
-end
-
diff --git a/features/steps/when/i_run_runner.rb b/features/steps/when/i_run_runner.rb
deleted file mode 100644
index 717bf6f..0000000
--- a/features/steps/when/i_run_runner.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-When /^I run the runner$/ do
-  @result = @runner.run
-end
-
diff --git a/features/support/env.rb b/features/support/env.rb
deleted file mode 100644
index 0545a30..0000000
--- a/features/support/env.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require 'jasmine-headless-webkit'
-
-After do
-  FileUtils.rm_f 'spec/report.txt'
-  FileUtils.rm_f 'spec/runner.html'
-end
-
diff --git a/jasmine-headless-webkit.gemspec b/jasmine-headless-webkit.gemspec
index d3bd110..2a6c27e 100644
--- a/jasmine-headless-webkit.gemspec
+++ b/jasmine-headless-webkit.gemspec
@@ -20,11 +20,9 @@ Gem::Specification.new do |s|
   s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
   s.require_paths = ["lib"]
 
-  s.add_runtime_dependency 'jasmine-core'
+  s.add_runtime_dependency 'jasmine-core', '~> 1.1'
   s.add_runtime_dependency 'coffee-script'
   s.add_runtime_dependency 'rainbow'
-  s.add_runtime_dependency 'multi_json', '>= 1.2.0'
-  s.add_runtime_dependency 'sprockets'
-  s.add_runtime_dependency 'sprockets-vendor_gems'
+  s.add_runtime_dependency 'multi_json'
+  s.add_runtime_dependency 'sprockets', '~> 2'
 end
-
diff --git a/lib/digest/jasmine_test.rb b/lib/digest/jasmine_test.rb
new file mode 100644
index 0000000..f29e207
--- /dev/null
+++ b/lib/digest/jasmine_test.rb
@@ -0,0 +1,20 @@
+module Digest
+  class JasmineTest
+    def self.file(file)
+      new
+    end
+
+    def file(file)
+      self
+    end
+
+    def hexdigest
+      'test'
+    end
+
+    def update(prefix)
+      self
+    end
+  end
+end
+
diff --git a/lib/jasmine-headless-webkit.rb b/lib/jasmine-headless-webkit.rb
index 556c370..a99ab37 100644
--- a/lib/jasmine-headless-webkit.rb
+++ b/lib/jasmine-headless-webkit.rb
@@ -1,3 +1,7 @@
 require 'jasmine/headless'
 require 'jasmine/headless/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
 
+module Digest
+  autoload :JasmineTest, 'digest/jasmine_test'
+end
+
diff --git a/lib/jasmine/headless.rb b/lib/jasmine/headless.rb
index 0a60efa..a1dae0b 100644
--- a/lib/jasmine/headless.rb
+++ b/lib/jasmine/headless.rb
@@ -35,24 +35,6 @@ module Jasmine
       def root
         @root ||= Pathname(File.expand_path('../../..', __FILE__))
       end
-
-      def warn(message)
-        output.puts message if show_warnings?
-      end
-
-      def show_warnings=(show)
-        @show_warnings = show
-      end
-
-      def show_warnings?
-        @show_warnings = true if @show_warnings.nil?
-
-        @show_warnings
-      end
-
-      def output
-        $stdout
-      end
     end
   end
 end
diff --git a/lib/jasmine/headless/cacheable_action.rb b/lib/jasmine/headless/cacheable_action.rb
index ee29ffb..84e946f 100644
--- a/lib/jasmine/headless/cacheable_action.rb
+++ b/lib/jasmine/headless/cacheable_action.rb
@@ -54,11 +54,7 @@ module Jasmine::Headless
     end
 
     def cache_file
-      @cache_file ||= File.expand_path(relative_cache_file) + '.js'
-    end
-
-    def relative_cache_file
-      File.join(self.class.cache_dir, self.class.cache_type, file.gsub(Dir.pwd + '/', ''))
+      @cache_file ||= File.expand_path(File.join(self.class.cache_dir, self.class.cache_type, file)) + '.js'
     end
 
     def fresh?
diff --git a/lib/jasmine/headless/file_checker.rb b/lib/jasmine/headless/file_checker.rb
index 6795a5b..fd7a3a7 100644
--- a/lib/jasmine/headless/file_checker.rb
+++ b/lib/jasmine/headless/file_checker.rb
@@ -1,18 +1,14 @@
 module Jasmine::Headless::FileChecker
-  def excluded_formats
-    ::Jasmine::Headless::EXCLUDED_FORMATS
-  end
-
   def bad_format?(file)
     return if file.nil?
 
-    excluded_formats.any? do |format|
+    ::Jasmine::Headless::EXCLUDED_FORMATS.any? do |format|
       file[%r{\.#{format}(\.|$)}]
     end
   end
-
+  
   def alert_bad_format(file)
-    Jasmine::Headless.warn("[%s] %s: %s" % [ 'Skipping File'.color(:red), file.color(:yellow), "unsupported format".color(:white) ])
+    puts "[%s] %s: %s" % [ 'Skipping File'.color(:red), file.color(:yellow), "unsupported format".color(:white) ]
   end
 
   def alert_if_bad_format?(file)
diff --git a/lib/jasmine/headless/files_list.rb b/lib/jasmine/headless/files_list.rb
index aad2d62..d4d1cff 100644
--- a/lib/jasmine/headless/files_list.rb
+++ b/lib/jasmine/headless/files_list.rb
@@ -4,7 +4,6 @@ require 'multi_json'
 require 'set'
 require 'sprockets'
 require 'sprockets/engines'
-require 'sprockets-vendor_gems'
 
 module Jasmine::Headless
   class FilesList
@@ -12,14 +11,35 @@ module Jasmine::Headless
 
     class << self
       def asset_paths
-        @asset_paths ||= Sprockets.find_gem_vendor_paths(:for => 'javascripts')
+        return @asset_paths if @asset_paths
+
+        require 'rubygems'
+
+        raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:each)
+
+        @asset_paths = []
+
+        Gem::Specification.each { |gemspec| @asset_paths += get_paths_from_gemspec(gemspec) }
+
+        @asset_paths
+      end
+
+      def get_paths_from_gemspec(gemspec)
+        %w{vendor lib app}.collect do |dir|
+          path = File.join(gemspec.gem_dir, dir, "assets/javascripts")
+
+          if File.directory?(path) && !@asset_paths.include?(path)
+            path
+          else
+            nil
+          end
+        end.compact
       end
 
       def reset!
         @asset_paths = nil
-        @registered_engines = {}
 
-        # register haml-sprockets and handlebars_assets if it's available...
+        # register haml-sprockets if it's available...
         %w{haml-sprockets handlebars_assets}.each do |library|
           begin
             require library
@@ -27,37 +47,21 @@ module Jasmine::Headless
           end
         end
 
-        if ENV['JHW_ENV']
-          begin
-            require 'bundler'
-
-            Bundler.require(ENV['JHW_ENV'].to_sym)
-          rescue LoadError
+        # ...and unregister ones we don't want/need
+        Sprockets.instance_eval do
+          EXCLUDED_FORMATS.each do |extension|
+            register_engine ".#{extension}", Jasmine::Headless::NilTemplate
           end
-        end
 
-        @sprockets_environment = nil
-      end
-
-      def registered_engines
-        @registered_engines ||= {}
-      end
-
-      def register_engine(file_extension, template_class)
-        registered_engines[file_extension] = template_class
-      end
-
-      def register_engines!
-        registered_engines.each do |file_extension, template_class|
-          Sprockets.register_engine file_extension, template_class
+          register_engine '.coffee', Jasmine::Headless::CoffeeTemplate
+          register_engine '.js', Jasmine::Headless::JSTemplate
+          register_engine '.css', Jasmine::Headless::CSSTemplate
+          register_engine '.jst', Jasmine::Headless::JSTTemplate
         end
       end
 
       def default_files
-        %w{jasmine.js jasmine-html jasmine.css jasmine-extensions
-           intense headless_reporter_result jasmine.HeadlessReporter
-           jasmine.HeadlessReporter.ConsoleBase
-           jsDump beautify-html}
+        %w{jasmine.js jasmine-html jasmine.css jasmine-extensions intense headless_reporter_result jasmine.HeadlessConsoleReporter jsDump beautify-html}
       end
 
       def extension_filter
@@ -69,43 +73,25 @@ module Jasmine::Headless
 
     PLEASE_WAIT_IM_WORKING_TIME = 2
 
-    attr_reader :options, :required_files, :potential_files_to_filter
+    attr_reader :required_files, :potential_files_to_filter
 
     def initialize(options = {})
       @options = options
 
-      Kernel.srand(options[:seed]) if options[:seed]
+      Kernel.srand(@options[:seed]) if @options[:seed]
 
       @required_files = UniqueAssetList.new
       @potential_files_to_filter = []
 
-      register_engines!
-
-      load_initial_assets
-
-      use_config if config?
-    end
-
-    def register_engines!
-      begin
-        require spec_helper
-      rescue LoadError
-      end
-      self.class.register_engines!
-    end
-
-    def load_initial_assets
       self.class.default_files.each do |file|
         begin
-          add_path(file)
+          @required_files << sprockets_environment.find_asset(file, :bundle => false)
         rescue InvalidUniqueAsset => e
           raise StandardError.new("Not an asset: #{file}")
         end
       end
 
-      (options[:reporters] || []).each do |reporter, identifier, file|
-        add_path("jasmine.HeadlessReporter.#{reporter}")
-      end
+      use_config! if config?
     end
 
     def files
@@ -131,7 +117,6 @@ module Jasmine::Headless
       @search_paths += asset_paths.collect { |dir| File.expand_path(dir) }
       @search_paths += spec_dir.collect { |dir| File.expand_path(dir) }
 
-      @search_paths.uniq!
       @search_paths
     end
 
@@ -142,19 +127,6 @@ module Jasmine::Headless
       search_paths.each { |path| @sprockets_environment.append_path(path) }
 
       @sprockets_environment.unregister_postprocessor('application/javascript', Sprockets::SafetyColons)
-
-      # ...and unregister ones we don't want/need
-      @sprockets_environment.instance_eval do
-        EXCLUDED_FORMATS.each do |extension|
-          register_engine ".#{extension}", Jasmine::Headless::NilTemplate
-        end
-
-        register_engine '.coffee', Jasmine::Headless::CoffeeTemplate
-        register_engine '.js', Jasmine::Headless::JSTemplate
-        register_engine '.css', Jasmine::Headless::CSSTemplate
-        register_engine '.jst', Jasmine::Headless::JSTTemplate
-      end
-
       @sprockets_environment
     end
 
@@ -222,7 +194,7 @@ module Jasmine::Headless
       'spec_files' => 'spec_dir'
     }
 
-    def use_config
+    def use_config!
       @config = @options[:config].dup
       @searches = {}
       @potential_files_to_filter = []
@@ -235,13 +207,13 @@ module Jasmine::Headless
     end
 
     def add_files(patterns, type, dirs)
-      patterns.each do |pattern|
-        dirs.collect { |dir| expanded_dir(File.join(dir, pattern)) }.each do |files|
-          files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files'
+      dirs.product(patterns).each do |search|
+        files = expanded_dir(File.join(*search))
 
-          files.each do |path|
-            add_path(path, type)
-          end
+        files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files'
+
+        files.each do |path|
+          add_path(path, type)
         end
       end
 
@@ -255,8 +227,7 @@ module Jasmine::Headless
     end
 
     def expanded_dir(path)
-      file_list = Dir.glob(path).sort
-      file_list.find_all { |file|
+      Dir[path].find_all { |file|
         file[extension_filter] && !alert_if_bad_format?(file)
       }.collect {
         |file| File.expand_path(file)
@@ -269,7 +240,7 @@ module Jasmine::Headless
       self.class.extension_filter
     end
 
-    def add_path(path, type = nil)
+    def add_path(path, type)
       asset = sprockets_environment.find_asset(path)
 
       @required_files << asset
@@ -280,7 +251,7 @@ module Jasmine::Headless
     end
 
     def src_dir
-      @src_dir ||= config_dir_or_pwd('src_dir') + asset_paths
+      @src_dir ||= config_dir_or_pwd('src_dir')
     end
 
     def spec_dir
@@ -288,7 +259,7 @@ module Jasmine::Headless
     end
 
     def asset_paths
-      @asset_paths ||= config_dir('asset_paths')
+      @asset_paths ||= config_dir_or_pwd('asset_paths')
     end
 
     def spec_file_searches
@@ -296,15 +267,9 @@ module Jasmine::Headless
     end
 
     def config_dir_or_pwd(dir)
-      if (found = config_dir(dir)).empty?
-        found = [ Dir.pwd ]
-      end
+      found_dir = (@options[:config] && @options[:config][dir]) || Dir.pwd
 
-      found
-    end
-
-    def config_dir(dir)
-      [ @options[:config] && @options[:config][dir] ].flatten.compact.collect { |dir| File.expand_path(dir) }
+      [ found_dir ].flatten.collect { |dir| File.expand_path(dir) }
     end
 
     def filter_for_requested_specs(files)
@@ -316,17 +281,5 @@ module Jasmine::Headless
         end
       end
     end
-
-    def spec_helper
-      File.join(spec_dir, "helpers", "spec_helper")
-    end
-  end
-end
-
-module Jasmine::Headless
-  extend self
-
-  def register_engine(file_extension, template_class)
-    Jasmine::Headless::FilesList.register_engine(file_extension, template_class)
   end
 end
diff --git a/lib/jasmine/headless/options.rb b/lib/jasmine/headless/options.rb
index 53719c0..d62da56 100644
--- a/lib/jasmine/headless/options.rb
+++ b/lib/jasmine/headless/options.rb
@@ -13,21 +13,16 @@ module Jasmine
         :remove_html_file => true,
         :runner_output_filename => false,
         :jasmine_config => 'spec/javascripts/support/jasmine.yml',
+        :report => false,
         :do_list => false,
         :full_run => true,
         :enable_cache => true,
-        :files => [],
-        :reporters => [ [ 'Console' ] ],
-        :quiet => false,
-        :use_server => false,
-        :server_port => nil
+        :files => []
       }
 
       DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit')
       GLOBAL_DEFAULTS_FILE = File.expand_path('~/.jasmine-headless-webkit')
 
-      REPORT_DEPRECATED_MESSAGE = "--report is deprecated. Use --format HeadlessFileReporter --out <filename>"
-
       def self.from_command_line
         options = new
         options.process_command_line_args
@@ -40,7 +35,6 @@ module Jasmine
         srand
         @options[:seed] = rand(10000)
         read_defaults_files
-
         opts.each { |k, v| @options[k] = v if v }
       end
 
@@ -59,10 +53,7 @@ module Jasmine
         when '--keep'
           @options[:remove_html_file] = false
         when '--report'
-          warn REPORT_DEPRECATED_MESSAGE
-
-          add_reporter('File', arg)
-          add_reporter('Console')
+          @options[:report] = arg
         when '--runner-out'
           @options[:runner_output_filename] = arg
         when '--jasmine-config', '-j'
@@ -71,22 +62,8 @@ module Jasmine
           @options[:full_run] = false
         when '--list', '-l'
           @options[:do_list] = true
-        when '--quiet', '-q'
-          @options[:quiet] = true
         when '--seed'
           @options[:seed] = arg.to_i
-        when '--format', '-f'
-          add_reporter(arg)
-        when '--use-server'
-          @options[:use_server] = true
-        when '--server-port'
-          @options[:server_port] = arg.to_i
-        when '--out'
-          add_reporter_file(arg)
-        when '-h', '--help'
-          print_help
-
-          exit
         end
       end
 
@@ -103,103 +80,18 @@ module Jasmine
           [ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
           [ '--no-colors', GetoptLong::NO_ARGUMENT ],
           [ '--cache', GetoptLong::NO_ARGUMENT ],
-          [ '--no-cache', GetoptLong::NO_ARGUMENT ],
+          [ '--no-t stcache', GetoptLong::NO_ARGUMENT ],
           [ '--keep', GetoptLong::NO_ARGUMENT ],
           [ '--runner-out', GetoptLong::REQUIRED_ARGUMENT ],
           [ '--report', GetoptLong::REQUIRED_ARGUMENT ],
           [ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
           [ '--no-full-run', GetoptLong::NO_ARGUMENT ],
           [ '--list', '-l', GetoptLong::NO_ARGUMENT ],
-          [ '--seed', GetoptLong::REQUIRED_ARGUMENT ],
-          [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
-          [ '--out', GetoptLong::REQUIRED_ARGUMENT ],
-          [ '--use-server', GetoptLong::NO_ARGUMENT ],
-          [ '--server-port', GetoptLong::REQUIRED_ARGUMENT ],
-          [ '-h', '--help', GetoptLong::NO_ARGUMENT ],
-          [ '-q', '--quiet', GetoptLong::NO_ARGUMENT ]
+          [ '--seed', GetoptLong::REQUIRED_ARGUMENT ]
         )
 
         command_line_args.each { |*args| process_option(*args) }
       end
-
-      def reporters
-        file_index = 0
-
-        @options[:reporters].collect do |reporter, file|
-          output = [ reporter ]
-          if file
-            output << "report:#{file_index}"
-            output << file
-            file_index += 1
-          else
-            output << "stdout"
-          end
-
-          output
-        end
-      end
-
-      def file_reporters
-        reporters.find_all { |reporter| reporter[1]["report:"] }
-      end
-
-      private
-      def add_reporter(name, file = nil)
-        if !@added_reporter
-          @options[:reporters] = []
-          @added_reporter = true
-        end
-
-        if (parts = name.split(':')).length == 2
-          name, file = parts
-        end
-
-        @options[:reporters] << [ name ]
-
-        add_reporter_file(file) if file
-      end
-
-      def add_reporter_file(file)
-        @options[:reporters].last << file
-      end
-
-      def print_help
-        options = [
-          [ '-c, --colors', 'Enable colors (default: disabled)' ],
-          [ '-nc, --no-colors', 'Disable colors' ],
-          [ '--cache', 'Enable cache (default: enabled)' ],
-          [ '--no-cache', 'Disable cache' ],
-          [ '--keep', 'Keep runner files on failure' ],
-          [ '--runner-out <filename>', 'Write runner to specified filename' ],
-          [ '-j, --jasmine-config <config file>', 'Jasmine Yaml config to use' ],
-          [ '--no-full-run', 'Do not perform a full spec run after a successful targeted spec run' ],
-          [ '--use-server', 'Load tests from an HTTP server instead of from filesystem' ],
-          [ '-l, --list', 'List files in the order they will be required' ],
-          [ '--seed <seed>', 'Random order seed for spec file ordering' ],
-          [ '-f, --format <reporter<:filename>>', 'Specify an output reporter and possibly output filename' ],
-          [ '--out <filename>', 'Specify output filename for last defined reporter' ],
-          [ '-q, --quiet', "Silence most non-test related warnings" ],
-          [ '-h, --help', "You're looking at it" ]
-        ]
-
-        longest_length = options.collect(&:first).collect(&:length).max
-
-        puts <<-HELP
-Usage: #{$0} [ options ] [ spec files ]
-
-Options:
-#{options.collect { |option, description| "  #{option.ljust(longest_length)}  #{description}" }.join("\n")}
-
-Available reporters:
-  Console  Write out spec results to the console in a progress format (default)
-  Verbose  Write out spec results to the console in a verbose format
-  File     Write spec results in jasmine-headless-webkit ReportFile format
-  Tap      Write spec results in TAP format
-
-Add reporters to the jasmine.HeadlessReporter object to access them
-  (ex: jasmine.HeadlessReporter.Teamcity for the Teamcity reporter)
-HELP
-      end
     end
   end
 end
diff --git a/lib/jasmine/headless/report.rb b/lib/jasmine/headless/report.rb
index 3da241c..d620b73 100644
--- a/lib/jasmine/headless/report.rb
+++ b/lib/jasmine/headless/report.rb
@@ -60,13 +60,8 @@ module Jasmine::Headless
       }.collect(&:filename).uniq.compact
     end
 
-    def seed
-      if seed = report.find { |entry| entry.respond_to?(:seed) }
-        seed.seed
-      end
-    end
-
     private
+
     def last_total
       @report.reverse.find { |entry| entry.respond_to?(:total) }
     end
diff --git a/lib/jasmine/headless/report_message.rb b/lib/jasmine/headless/report_message.rb
index 83505a4..218ba17 100644
--- a/lib/jasmine/headless/report_message.rb
+++ b/lib/jasmine/headless/report_message.rb
@@ -6,7 +6,6 @@ module Jasmine::Headless
     autoload :Console, 'jasmine/headless/report_message/console'
     autoload :Error, 'jasmine/headless/report_message/error'
     autoload :Total, 'jasmine/headless/report_message/total'
-    autoload :Seed, 'jasmine/headless/report_message/seed'
   end
 end
 
diff --git a/lib/jasmine/headless/report_message/console.rb b/lib/jasmine/headless/report_message/console.rb
index 2fb8e85..25c64ef 100644
--- a/lib/jasmine/headless/report_message/console.rb
+++ b/lib/jasmine/headless/report_message/console.rb
@@ -1,7 +1,9 @@
 module Jasmine::Headless::ReportMessage
   class Console
-    def self.new_from_parts(parts)
-      new(parts.first)
+    class << self
+      def new_from_parts(parts)
+        new(parts.first)
+      end
     end
 
     attr_reader :message
diff --git a/lib/jasmine/headless/report_message/seed.rb b/lib/jasmine/headless/report_message/seed.rb
deleted file mode 100644
index a2f53f2..0000000
--- a/lib/jasmine/headless/report_message/seed.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module Jasmine::Headless::ReportMessage
-  class Seed
-    def self.new_from_parts(parts)
-      new(parts.first)
-    end
-
-    attr_reader :seed
-
-    def initialize(seed)
-      @seed = seed.to_i
-    end
-  end
-end
-
diff --git a/lib/jasmine/headless/report_message/spec.rb b/lib/jasmine/headless/report_message/spec.rb
index 218dabd..63c5b54 100644
--- a/lib/jasmine/headless/report_message/spec.rb
+++ b/lib/jasmine/headless/report_message/spec.rb
@@ -1,9 +1,11 @@
 module Jasmine::Headless::ReportMessage
   class Spec
-    def self.new_from_parts(parts)
-      file_info = parts.pop
+    class << self
+      def new_from_parts(parts)
+        file_info = parts.pop
 
-      new(parts.join(' '), file_info)
+        new(parts.join(' '), file_info)
+      end
     end
 
     attr_reader :statement, :file_info
diff --git a/lib/jasmine/headless/runner.rb b/lib/jasmine/headless/runner.rb
index 3ce7247..1337123 100644
--- a/lib/jasmine/headless/runner.rb
+++ b/lib/jasmine/headless/runner.rb
@@ -4,29 +4,11 @@ require 'coffee-script'
 require 'rainbow'
 
 require 'yaml'
-require 'erb'
 require 'sprockets'
 
+
 module Jasmine
   module Headless
-    class IndexHandler
-      class << self
-        attr_accessor :index
-      end
-
-      def initialize(app)
-        @app = app
-      end
-
-      def call(env)
-        if env['PATH_INFO'] == '/'
-          return [ 302, { 'Location' => self.class.index }, [ 'Redirecting...' ] ]
-        end
-
-        @app.call(env)
-      end
-    end
-
     class Runner
       JASMINE_DEFAULTS = {
         'spec_files' => [ '**/*[sS]pec.js' ],
@@ -43,108 +25,21 @@ module Jasmine
 
       attr_reader :options
 
-      def self.run(options = {})
-        new(options).run
-      end
-
-      def self.server_port
-        return @server_port if @server_port
-
-        require 'socket'
-
-        count = 100
-        begin
-          port = select_server_port
-
-          socket = TCPSocket.new(server_interface, port)
-          socket.close
-
-          count -= 1
-
-          raise "Could not create server port after 100 attempts!" if count == 0
-        rescue Errno::ECONNREFUSED
-          @server_port = port
-
-          break
-        ensure
-          begin
-            socket.close if socket
-          rescue IOError
-          end
-        end while true
-
-        @server_port
-      end
-
-      def self.server_port=(port)
-        @server_port = port
-      end
-
-      def self.select_server_port
-        21000 + rand(10000)
-      end
-
-      def self.server_interface
-        '127.0.0.1'
-      end
-
-      def self.server_uri
-        "http://#{server_interface}:#{server_port}"
-      end
-
-      def self.server_spec_path
-        self.server_uri + '/__JHW__/'
-      end
-
-      def self.ensure_server(options)
-        return if @server
-
-        require 'webrick'
-        require 'thread'
-        require 'rack'
-        require 'net/http'
-
-        port = server_port
-
-        @server = Thread.new do
-          Jasmine::Headless.warn "Powering up!"
-
-          app = Rack::Builder.new do
-            use IndexHandler
-
-            map '/__JHW__' do
-              run Rack::File.new(Dir.pwd)
-            end
-
-            map '/' do
-              run Rack::File.new('/')
-            end
-          end
-
-          Rack::Handler::WEBrick.run(
-            app,
-            :Port => port,
-            :Logger => Logger.new(StringIO.new),
-            :AccessLog => [
-              [ StringIO.new, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
-              [ StringIO.new, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
-            ]
-          )
-        end
-
-        while true do
-          begin
-            Net::HTTP.get(URI(server_uri))
-            break
-          rescue Errno::ECONNREFUSED => e
-          end
-
-          sleep 0.1
+      class << self
+        def run(options = {})
+          options = Options.new(options) if !options.kind_of?(Options)
+          new(options).run
         end
       end
 
       def initialize(options)
-        options = Options.new(options) if !options.kind_of?(Options)
+        if !File.file?(RUNNER)
+          $stderr.puts "No runner found, attempting to compile..."
+          Dir.chdir RUNNER_DIR do
+            system %{ruby extconf.rb}
+          end
+          raise NoRunnerError if !File.file?(RUNNER)
+        end
 
         @options = options
       end
@@ -164,30 +59,27 @@ module Jasmine
       end
 
       def jasmine_command(*targets)
-        command = [ RUNNER ]
-
-        command << "-s #{options[:seed]}"
-        command << '-c' if options[:colors]
-        command << '-q' if options[:quiet]
-
-        options.file_reporters.each do |reporter, identifier, file|
-          command << "-r #{file}"
-        end
-
-        command += targets
-        command.compact.join(' ')
+        [
+          RUNNER,
+          @options[:colors] ? '-c' : nil,
+          @options[:report] ? "-r #{@options[:report]}" : nil,
+          *targets
+        ].compact.join(" ")
       end
 
       def run
         Jasmine::Headless::CacheableAction.enabled = @options[:enable_cache]
-        Jasmine::Headless.show_warnings = !@options[:quiet]
         FilesList.reset!
 
-        self.class.server_port = options[:server_port]
+        files_list = Jasmine::Headless::FilesList.new(
+          :config => jasmine_config,
+          :only => @options[:files],
+          :seed => @options[:seed]
+        )
 
-        @_targets = template_writer.write
+        @_targets = template_writer.write!(files_list)
 
-        run_targets = absolute_run_targets(@_targets.dup)
+        run_targets = @_targets.dup
 
         if run_targets.length == 2
           if (!@options[:full_run] && files_list.filtered?) || files_list.has_spec_outside_scope?
@@ -195,13 +87,9 @@ module Jasmine
           end
         end
 
-        runner = lambda { system jasmine_command(run_targets) }
+        system jasmine_command(run_targets)
 
-        if options[:use_server]
-          wrap_in_server(run_targets, &runner)
-        else
-          runner.call
-        end
+        puts "\nTest ordering seed: --seed #{@options[:seed]}"
 
         @_status = $?.exitstatus
       ensure
@@ -210,17 +98,6 @@ module Jasmine
         end
       end
 
-      def absolute_run_targets(targets)
-        targets.flatten.collect do |target|
-          if options[:use_server]
-            target = self.class.server_spec_path + target
-          else
-            target = "file://" + File.expand_path(target)
-          end
-          target
-        end
-      end
-
       def runner_filename
         options[:runner_output_filename] || begin
           if (runner_output = jasmine_config['runner_output']) && !runner_output.empty?
@@ -231,29 +108,11 @@ module Jasmine
         end
       end
 
-      def files_list
-        @files_list ||= Jasmine::Headless::FilesList.new(
-          :config => jasmine_config,
-          :only => options[:files],
-          :seed => options[:seed],
-          :reporters => options.reporters
-        )
-      end
-
-      def wrap_in_server(run_targets)
-        self.class.ensure_server(options)
-        IndexHandler.index = run_targets.last
-
-        Jasmine::Headless.warn "HTTP powered specs! Located at #{run_targets.join(' ')}"
-
-        yield
-      end
-
       private
       def jasmine_config_data
         raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config])
 
-        YAML.load(ERB.new(File.read(@options[:jasmine_config])).result(binding))
+        YAML.load_file(@options[:jasmine_config])
       end
     end
   end
diff --git a/lib/jasmine/headless/spec_file_analyzer.rb b/lib/jasmine/headless/spec_file_analyzer.rb
index a7f1ccb..f32308d 100644
--- a/lib/jasmine/headless/spec_file_analyzer.rb
+++ b/lib/jasmine/headless/spec_file_analyzer.rb
@@ -33,11 +33,11 @@ module Jasmine::Headless
     end
 
     def serialize(data)
-      MultiJson.dump(data)
+      MultiJson.encode(data)
     end
 
     def unserialize(data)
-      MultiJson.load(data)
+      MultiJson.decode(data)
     end
   end
 end
diff --git a/lib/jasmine/headless/task.rb b/lib/jasmine/headless/task.rb
index 058a33c..3368c6b 100644
--- a/lib/jasmine/headless/task.rb
+++ b/lib/jasmine/headless/task.rb
@@ -14,9 +14,23 @@ module Jasmine
 
         desc 'Run Jasmine specs headlessly'
         task(name) { run_rake_task }
+
+        create_rails_compliant_task if defined?(Rails)
       end
 
       private
+      def create_rails_compliant_task
+        if Rails.respond_to?(:version) && Rails.version >= "3.1.0"
+          task 'assets:precompile:for_testing' => :environment do
+            $stderr.puts "This task is deprecated and will be removed after 2012-01-01"
+
+            Rails.application.assets.digest_class = Digest::JasmineTest
+
+            Rake::Task['assets:precompile'].invoke
+          end
+        end
+      end
+
       def run_rake_task
         case Jasmine::Headless::Runner.run(
           :colors => colors,
diff --git a/lib/jasmine/headless/template_writer.rb b/lib/jasmine/headless/template_writer.rb
index 81562a5..7d41161 100644
--- a/lib/jasmine/headless/template_writer.rb
+++ b/lib/jasmine/headless/template_writer.rb
@@ -1,32 +1,24 @@
 require 'multi_json'
 require 'erb'
 require 'tempfile'
-require 'forwardable'
 
 module Jasmine::Headless
   class TemplateWriter
     attr_reader :runner
 
-    extend Forwardable
-
-    def_delegators :runner, :files_list, :options
-    def_delegators :options, :reporters
-
     def initialize(runner)
       @runner = runner
     end
 
-    def write
+    def write!(files_list)
       output = [
         [ all_tests_filename, files_list.files_to_html ]
       ]
 
-      output.unshift([filtered_tests_filename, files_list.filtered_files_to_html ]) if files_list.filtered?
+      output.unshift([filtered_tests_filename , files_list.filtered_files_to_html ]) if files_list.filtered?
 
       output.each do |name, files|
-        template = template_for(files)
-
-        File.open(name, 'wb') { |fh| fh.print template }
+        File.open(name, 'w') { |fh| fh.print template_for(files, files_list.spec_file_line_numbers) }
       end
 
       output.collect(&:first)
@@ -40,24 +32,8 @@ module Jasmine::Headless
       all_tests_filename.gsub(%r{\.html$}, '.filter.html')
     end
 
-    def render
-      template_for(all_files)
-    end
-
-    def all_files
-      files_list.files_to_html
-    end
-
-    def jhw_reporters
-      reporters.collect do |reporter, output|
-        %{jasmine.getEnv().addReporter(new jasmine.HeadlessReporter.#{reporter}("#{output}"));}
-      end.join("\n")
-    end
-
     private
-    def template_for(files)
-      spec_lines = files_list.spec_file_line_numbers
-
+    def template_for(files, spec_lines)
       ERB.new(Jasmine::Headless.root.join('skel/template.html.erb').read).result(binding)
     end
   end
diff --git a/lib/jasmine/headless/unique_asset_list.rb b/lib/jasmine/headless/unique_asset_list.rb
index a099052..14ed9f4 100644
--- a/lib/jasmine/headless/unique_asset_list.rb
+++ b/lib/jasmine/headless/unique_asset_list.rb
@@ -3,7 +3,7 @@ module Jasmine::Headless
     def <<(asset)
       raise InvalidUniqueAsset.new("Not an asset: #{asset.inspect}") if !asset.respond_to?(:logical_path)
 
-      super if !self.any? { |other| asset.pathname == other.pathname }
+      super if !self.any? { |other| asset.logical_path == other.logical_path }
     end
 
     def flatten
diff --git a/lib/jasmine/headless/version.rb b/lib/jasmine/headless/version.rb
index 2960da5..8d91aed 100644
--- a/lib/jasmine/headless/version.rb
+++ b/lib/jasmine/headless/version.rb
@@ -1,5 +1,5 @@
 module Jasmine
   module Headless
-    VERSION = "0.9.0.rc.2"
+    VERSION = "0.8.4"
   end
 end
diff --git a/script/hooks/post-commit b/script/hooks/post-commit
deleted file mode 100755
index 490f85d..0000000
--- a/script/hooks/post-commit
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-penchant gemfile remote --switch-back
-
diff --git a/script/hooks/pre-commit b/script/hooks/pre-commit
index fc9f07f..e1b1e1c 100755
--- a/script/hooks/pre-commit
+++ b/script/hooks/pre-commit
@@ -2,9 +2,9 @@
 
 OLD_GIT_DIR=$GIT_DIR
 
-if [ "$(penchant gemfile-env)" != "remote deployment" ]; then
+if [ "$(penchant gemfile-env)" != "remote" ]; then
   unset GIT_DIR
-  penchant gemfile remote --deployment
+  penchant gemfile remote
   GIT_DIR=$OLD_GIT_DIR
   git add Gemfile*
 fi
diff --git a/script/initialize-environment b/script/initialize-environment
index dad92b2..222c8f1 100755
--- a/script/initialize-environment
+++ b/script/initialize-environment
@@ -5,7 +5,7 @@ if File.file?('Gemfile.erb')
 
   Dir.chdir '..' do
     File.readlines(File.join(pwd, 'Gemfile.erb')).find_all { |line| line[':git'] }.each do |line|
-      repo = line[%r{:git => (['"])([^'"]+)\1}, 2]
+      repo = line[%r{:git => (['"])(.*)\1}, 2]
 
       puts "Installing #{repo}"
       system %{git clone #{repo}}
diff --git a/skel/template.html.erb b/skel/template.html.erb
index 644dde9..0f240a4 100644
--- a/skel/template.html.erb
+++ b/skel/template.html.erb
@@ -6,13 +6,13 @@
     <script type="text/javascript" src="<%= Jasmine::Headless.root.join('vendor/assets/javascripts/prolog.js') %>"></script>
     <%= files.join("\n") %>
     <script type="text/javascript">
-      if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.dump(spec_lines) %>; }
+      if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.encode(spec_lines) %>; }
     </script>
   </head>
   <body>
     <script type="text/javascript">
       jasmine.getEnv().console = {
-        log: function(msg) { JHW.print('stdout', msg + "\n"); }
+        log: function(msg) { JHW.stdout.puts(msg) }
       }
 
       window._onload = window.onload;
@@ -23,7 +23,7 @@
         }
 
         if (window.JHW) {
-          <%= jhw_reporters %>
+          jasmine.getEnv().addReporter(new jasmine.HeadlessConsoleReporter());
         } else {
           types = [ 'HtmlReporter', 'TrivialReporter' ];
 
@@ -34,39 +34,6 @@
               break;
             }
           }
-
-          var location = window.location.href;
-
-          var getLastModified = function(callback) {
-            var http = new XMLHttpRequest();
-            var header;
-
-            http.open('HEAD', location, true);
-
-            http.onreadystatechange = function() {
-              if(http.readyState === http.DONE) {
-                callback(http.getResponseHeader('Last-Modified'));
-              }
-            };
-            http.send();
-          }
-
-          getLastModified(function(currentLastModified) {
-            var checker;
-            checker = function() {
-              setTimeout(function() {
-                getLastModified(function(newLastModified) {
-                  if (currentLastModified != newLastModified) {
-                    setTimeout(function() { window.location.reload(); }, 1000);
-                  } else {
-                    checker();
-                  }
-                });
-              }, 3000);
-            };
-
-            checker();
-          });
         }
 
         jasmine.getEnv().execute();
diff --git a/spec/bin/jasmine-headless-webkit_spec.rb b/spec/bin/jasmine-headless-webkit_spec.rb
new file mode 100644
index 0000000..72845c0
--- /dev/null
+++ b/spec/bin/jasmine-headless-webkit_spec.rb
@@ -0,0 +1,142 @@
+require 'spec_helper'
+require 'tempfile'
+
+describe "jasmine-headless-webkit" do
+  let(:report) { 'spec/report.txt' }
+
+  before do
+    FileUtils.rm_f report
+  end
+
+  after do
+    FileUtils.rm_f report
+  end
+
+  describe 'success' do
+    it "should succeed with error code 0" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report #{report}}
+      $?.exitstatus.should == 0
+
+      report.should be_a_report_containing(1, 0, false)
+    end
+  end
+
+
+  describe 'success but with js error' do
+    it "should succeed with error code 0" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml --report #{report}}
+      $?.exitstatus.should == 1
+
+      # returns are unpredictable due to changes in jasmine! >.<
+      # all we can do is ensure that we've actually failed
+      #
+      # report.should be_a_report_containing(0, 0, false)
+    end
+  end
+
+  describe 'failure' do
+    it "should fail with an error code of 1" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml --report #{report}}
+      $?.exitstatus.should == 1
+
+      report.should be_a_report_containing(1, 1, false)
+    end
+  end
+
+  describe 'with console.log' do
+    it "should succeed, but has a console.log so an error code of 2" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml --report #{report}}
+      $?.exitstatus.should == 2
+
+      report.should be_a_report_containing(1, 0, true)
+    end
+  end
+
+  describe 'with coffeescript error' do
+    it "should fail" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/coffeescript_error/coffeescript_error.yml --report #{report}}
+      $?.exitstatus.should == 1
+
+      File.exist?(report).should be_false
+    end
+  end
+
+  describe 'tries to leave page' do
+    it "should not leave the page nor loop" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/leave_page/leave_page.yml --report #{report}}
+      $?.exitstatus.should == 1
+    end
+  end
+
+  describe 'tries to click a button' do
+    it "should not leave the page nor loop" do
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/click_button/click_button.yml --report #{report}}
+      $?.exitstatus.should == 0
+
+      report.should be_a_report_containing(0, 0, false)
+    end
+  end
+
+  describe 'with filtered run' do
+    context "don't run a full run, just the filtered run" do
+      it "should succeed and run both" do
+        system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --no-full-run --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js}
+        $?.exitstatus.should == 0
+
+        report.should be_a_report_containing(1, 0, false)
+      end
+
+      it "should use a file outside the normal test run and only run one" do
+        system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_other_file.js}
+        $?.exitstatus.should == 0
+
+        report.should be_a_report_containing(1, 0, false)
+      end
+    end
+
+    context "do both runs" do
+      it "should fail and not run the second" do
+        system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml --report #{report} ./spec/jasmine/filtered_failure/failure_spec.js}
+        $?.exitstatus.should == 1
+
+        report.should be_a_report_containing(1, 1, false)
+      end
+
+      it "should succeed and run both" do
+        system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js}
+        $?.exitstatus.should == 0
+
+        report.should be_a_report_containing(2, 0, false)
+      end
+
+      it "should succeed and run both, with the first having a console.log call" do
+        system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success_with_console/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success_with_console/success_one_spec.js}
+        $?.exitstatus.should == 2
+
+        report.should be_a_report_containing(2, 0, true)
+      end
+    end
+  end
+
+  describe 'files' do
+    it 'should list all the files that will be found' do
+      files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/success/success.yml}
+      $?.exitstatus.should == 0
+
+      files.lines.to_a.should include(File.expand_path("./spec/jasmine/success/success.js\n"))
+      files.lines.to_a.should include(File.expand_path("./spec/jasmine/success/success_spec.js\n"))
+    end
+  end
+
+  describe 'runner-out' do
+    it 'should write out the runner HTML to the specified path and not run the test' do
+      runner_path = Tempfile.new('jhw')
+      runner_path.close
+
+      system %{bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --runner-out #{runner_path.path}}
+
+      File.size(runner_path.path).should_not == 0
+    end
+  end
+end
+
diff --git a/spec/jasmine/noisy/file.js.erb b/spec/jasmine/noisy/file.js.erb
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/jasmine/noisy/noisy.yml b/spec/jasmine/noisy/noisy.yml
deleted file mode 100644
index c001d27..0000000
--- a/spec/jasmine/noisy/noisy.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-src_dir: spec/jasmine/noisy
-src_files:
-- '**/*'
-
-spec_dir: spec/jasmine/noisy
-spec_files:
-- '**/*'
-
diff --git a/spec/jasmine/noisy/other_file.js b/spec/jasmine/noisy/other_file.js
deleted file mode 100644
index 213323b..0000000
--- a/spec/jasmine/noisy/other_file.js
+++ /dev/null
@@ -1,2 +0,0 @@
-window.prompt("hello");
-
diff --git a/spec/jasmine/two_files_from_src_files/app/app-file.js b/spec/jasmine/two_files_from_src_files/app/app-file.js
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/jasmine/two_files_from_src_files/app/app.js b/spec/jasmine/two_files_from_src_files/app/app.js
deleted file mode 100644
index a307af7..0000000
--- a/spec/jasmine/two_files_from_src_files/app/app.js
+++ /dev/null
@@ -1,2 +0,0 @@
-//= require app-file
-//
diff --git a/spec/jasmine/two_files_from_src_files/jasmine.yml b/spec/jasmine/two_files_from_src_files/jasmine.yml
deleted file mode 100644
index 494c646..0000000
--- a/spec/jasmine/two_files_from_src_files/jasmine.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-src_dir: spec/jasmine/two_files_from_src_files/app
-
-asset_paths:
-- "spec/jasmine/two_files_from_src_files/vendor"
-
-src_files: [ 'vendor.js', 'app.js' ]
-
diff --git a/spec/jasmine/two_files_from_src_files/vendor/vendor-file.js b/spec/jasmine/two_files_from_src_files/vendor/vendor-file.js
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/jasmine/two_files_from_src_files/vendor/vendor.js b/spec/jasmine/two_files_from_src_files/vendor/vendor.js
deleted file mode 100644
index f37a207..0000000
--- a/spec/jasmine/two_files_from_src_files/vendor/vendor.js
+++ /dev/null
@@ -1,2 +0,0 @@
-//= require vendor-file
-//
diff --git a/spec/jasmine/two_spec_files_same_basename/jasmine.yml b/spec/jasmine/two_spec_files_same_basename/jasmine.yml
deleted file mode 100644
index c214523..0000000
--- a/spec/jasmine/two_spec_files_same_basename/jasmine.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-src_dir: spec/jasmine/two_spec_files_same_basename
-src_files: []
-
-spec_dir: spec/jasmine/two_spec_files_same_basename
-spec_files: [ "**/*.{js,coffee}" ]
-
diff --git a/spec/jasmine/two_spec_files_same_basename/spec.coffee b/spec/jasmine/two_spec_files_same_basename/spec.coffee
deleted file mode 100644
index 9751cb2..0000000
--- a/spec/jasmine/two_spec_files_same_basename/spec.coffee
+++ /dev/null
@@ -1,4 +0,0 @@
-describe 'two', ->
-  it 'should pass', ->
-    expect(true).toEqual(true)
-
diff --git a/spec/jasmine/two_spec_files_same_basename/spec.js b/spec/jasmine/two_spec_files_same_basename/spec.js
deleted file mode 100644
index 6bee8a1..0000000
--- a/spec/jasmine/two_spec_files_same_basename/spec.js
+++ /dev/null
@@ -1,6 +0,0 @@
-describe("one", function() {
-  it('should pass', function() {
-    expect(true).toEqual(true);
-  });
-});
-
diff --git a/spec/jasmine/window_prompt/source.js b/spec/jasmine/window_prompt/source.js
deleted file mode 100644
index 220eb03..0000000
--- a/spec/jasmine/window_prompt/source.js
+++ /dev/null
@@ -1,2 +0,0 @@
-window.prompt("Yes! Hi!");
-
diff --git a/spec/jasmine/window_prompt/window_prompt.yml b/spec/jasmine/window_prompt/window_prompt.yml
deleted file mode 100644
index 13b11ef..0000000
--- a/spec/jasmine/window_prompt/window_prompt.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-src_dir: spec/jasmine/window_prompt
-src_files: 
-- '**/*.js'
-
diff --git a/spec/javascripts/headless_reporter_result_spec.coffee b/spec/javascripts/headless_reporter_result_spec.coffee
index f5f6fff..2c2d501 100644
--- a/spec/javascripts/headless_reporter_result_spec.coffee
+++ b/spec/javascripts/headless_reporter_result_spec.coffee
@@ -4,27 +4,11 @@ describe 'HeadlessReporterResult', ->
   splitName = "splitName"
   message = 'message'
 
-  context 'no lines', ->
-    beforeEach ->
-      result = new HeadlessReporterResult(name, splitName)
+  beforeEach ->
+    result = new HeadlessReporterResult(name, splitName)
 
-    describe '#addResult', ->
-      it 'should add a message', ->
-        result.addResult(message)
-
-        expect(result.results).toEqual([ message ])
-
-  context 'with lines', ->
-    beforeEach ->
-      HeadlessReporterResult.specLineNumbers = {
-        'one': {
-          'name': [ 1 ],
-          'of': [ 2, 9 ],
-          'test': [ 3, 10 ],
-          'other': [ 7 ]
-        }
-      }
-    it 'should find the best spec lines', ->
-      expect(HeadlessReporterResult.findSpecLine([ 'name', 'of', 'test' ]).lineNumber).toEqual(3)
-      expect(HeadlessReporterResult.findSpecLine([ 'other', 'of', 'test' ]).lineNumber).toEqual(10)
+  describe '#addResult', ->
+    it 'should add a message', ->
+      result.addResult(message)
 
+      expect(result.results).toEqual([ message ])
diff --git a/spec/javascripts/helpers/spec_helper.coffee b/spec/javascripts/helpers/spec_helper.coffee
deleted file mode 100644
index 4905362..0000000
--- a/spec/javascripts/helpers/spec_helper.coffee
+++ /dev/null
@@ -1,2 +0,0 @@
-window.context = window.describe
-
diff --git a/spec/javascripts/jasmine-extensions_spec.coffee b/spec/javascripts/jasmine.HeadlessConsoleReporter_spec.coffee
similarity index 70%
rename from spec/javascripts/jasmine-extensions_spec.coffee
rename to spec/javascripts/jasmine.HeadlessConsoleReporter_spec.coffee
index 8ed17fd..6696b95 100644
--- a/spec/javascripts/jasmine-extensions_spec.coffee
+++ b/spec/javascripts/jasmine.HeadlessConsoleReporter_spec.coffee
@@ -1,3 +1,38 @@
+describe 'HeadlessReporterResult', ->
+  beforeEach ->
+    HeadlessReporterResult.specLineNumbers = {
+      'one': {
+        'name': [ 1 ],
+        'of': [ 2, 9 ],
+        'test': [ 3, 10 ],
+        'other': [ 7 ]
+      }
+    }
+  it 'should find the best spec lines', ->
+    expect(HeadlessReporterResult.findSpecLine([ 'name', 'of', 'test' ]).lineNumber).toEqual(3)
+    expect(HeadlessReporterResult.findSpecLine([ 'other', 'of', 'test' ]).lineNumber).toEqual(10)
+
+describe 'jasmine.HeadlessConsoleReporter', ->
+  reporter = null
+
+  beforeEach ->
+    reporter = new jasmine.HeadlessConsoleReporter()
+
+  it 'should stop running specs if there are errors reported', ->
+    # otherwise it gets really confusing!
+
+    suite = { finish: -> null }
+    spec = new jasmine.Spec("env", suite, "test")
+
+    spyOn(reporter, 'hasError').andReturn(true)
+    spyOn(spec, 'finish')
+    spyOn(suite, 'finish')
+
+    reporter.reportSpecStarting(spec)
+    
+    expect(spec.finish).toHaveBeenCalled()
+    expect(suite.finish).toHaveBeenCalled()
+
 describe 'jasmine.Suite.prototype.getSuiteSplitName', ->
   it 'should flatten the description', ->
     suite = new jasmine.Suite({});
diff --git a/spec/javascripts/jasmine.HeadlessReporter.ConsoleBase_spec.coffee b/spec/javascripts/jasmine.HeadlessReporter.ConsoleBase_spec.coffee
deleted file mode 100644
index ed865be..0000000
--- a/spec/javascripts/jasmine.HeadlessReporter.ConsoleBase_spec.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-describe 'jasmine.HeadlessReporter.ConsoleBase', ->
-  reporter = null
-
-  beforeEach ->
-    reporter = new jasmine.HeadlessReporter.ConsoleBase()
-
-  describe '#formatResultLine', ->
-    context 'length = 1', ->
-      it 'should format', ->
-        reporter.length = 1
-        expect(reporter.formatResultLine(0)).toMatch(/test,/)
-
-    context 'length != 1', ->
-      it 'should format', ->
-        reporter.length = 2
-        expect(reporter.formatResultLine(0)).toMatch(/tests,/)
-
-    context 'failedCount = 1', ->
-      it 'should format', ->
-        reporter.failedCount = 1
-        expect(reporter.formatResultLine(0)).toMatch(/failure,/)
-
-    context 'failedCount != 1', ->
-      it 'should format', ->
-        reporter.failedCount = 0
-        expect(reporter.formatResultLine(0)).toMatch(/failures,/)
-
-    context 'runtime = 1', ->
-      it 'should format', ->
-        expect(reporter.formatResultLine(1)).toMatch(/sec./)
-
-    context 'runtime != 1', ->
-      it 'should format', ->
-        expect(reporter.formatResultLine(0)).toMatch(/secs./)
-
diff --git a/spec/javascripts/jasmine.HeadlessReporter.Console_spec.coffee b/spec/javascripts/jasmine.HeadlessReporter.Console_spec.coffee
deleted file mode 100644
index fa564be..0000000
--- a/spec/javascripts/jasmine.HeadlessReporter.Console_spec.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-describe 'jasmine.HeadlessReporter.Console', ->
-  describe '#reportSpecResults', ->
-
diff --git a/spec/javascripts/jasmine.HeadlessReporter.Tap_spec.coffee b/spec/javascripts/jasmine.HeadlessReporter.Tap_spec.coffee
deleted file mode 100644
index 47408db..0000000
--- a/spec/javascripts/jasmine.HeadlessReporter.Tap_spec.coffee
+++ /dev/null
@@ -1,19 +0,0 @@
-describe 'jasmine.HeadlessReporter.Tap', ->
-  beforeEach ->
-    @reporter = new jasmine.HeadlessReporter.Tap()
-
-  describe '#reportRunnerResults', ->
-    it 'should write nothing for nothing', ->
-      @reporter.output = []
-
-      @reporter.reportRunnerResults(null)
-
-      expect(@reporter.output[0]).not.toBeDefined()
-
-    it 'should report the length right', ->
-      @reporter.output = [ 'test' ]
-
-      @reporter.reportRunnerResults(null)
-
-      expect(@reporter.output[0]).toEqual('1..1')
-
diff --git a/spec/javascripts/jasmine.HeadlessReporter_spec.coffee b/spec/javascripts/jasmine.HeadlessReporter_spec.coffee
deleted file mode 100644
index 8a31685..0000000
--- a/spec/javascripts/jasmine.HeadlessReporter_spec.coffee
+++ /dev/null
@@ -1,27 +0,0 @@
-describe 'jasmine.HeadlessReporter', ->
-  reporter = null
-
-  beforeEach ->
-    reporter = new jasmine.HeadlessReporter()
-
-  it 'should stop running specs if there are errors reported', ->
-    # otherwise it gets really confusing!
-
-    suite = { finish: -> null }
-    spec = new jasmine.Spec("env", suite, "test")
-
-    spyOn(reporter, 'hasError').andReturn(true)
-    spyOn(spec, 'finish')
-    spyOn(suite, 'finish')
-
-    reporter.reportSpecStarting(spec)
-
-    expect(spec.finish).toHaveBeenCalled()
-    expect(suite.finish).toHaveBeenCalled()
-
-  describe '#reportRunnerStarting', ->
-    it 'should start getting time', ->
-      expect(reporter.startTime).not.toBeDefined()
-      reporter.reportRunnerStarting("runner")
-      expect(reporter.startTime).toBeDefined()
-
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index 7f26a68..fdbbc4c 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -1,9 +1,8 @@
 src_files:
-  - '**/*'
+  - 'spec/javascripts/support/jquery-1.6.2.min.js'
+  - 'vendor/assets/coffeescripts/*.coffee'
 
-spec_files: [ '**/*_spec.coffee' ]
-src_dir: vendor/assets/javascripts
-spec_dir: spec/javascripts
-helpers:
-  - 'helpers/**.*'
+spec_files: [ 'spec/javascripts/*_spec.coffee' ]
+src_dir: .
+spec_dir: .
 
diff --git a/spec/lib/jasmine/headless/cacheable_action_spec.rb b/spec/lib/jasmine/headless/cacheable_action_spec.rb
index b1d2d48..72b0281 100644
--- a/spec/lib/jasmine/headless/cacheable_action_spec.rb
+++ b/spec/lib/jasmine/headless/cacheable_action_spec.rb
@@ -95,28 +95,5 @@ describe Jasmine::Headless::CacheableAction do
       end
     end
   end
-
-  describe '#relative_cache_file' do
-    context 'file is an absolute windows file' do
-      let(:current_path) { 'C:/path' }
-      let(:filename) { "file.coffee" }
-      let(:windows_path) { File.join(current_path, filename) }
-      let(:cache_dir) { 'cache dir' }
-      let(:cache_type) { 'cache type' }
-
-      before do
-        cache_object.stubs(:file).returns(windows_path)
-
-        described_class.stubs(:cache_dir).returns(cache_dir)
-        described_class.stubs(:cache_type).returns(cache_type)
-
-        Dir.stubs(:pwd).returns(current_path)
-      end
-
-      subject { cache_object.relative_cache_file }
-
-      it { should == File.join(cache_dir, cache_type, filename) }
-    end
-  end
 end
 
diff --git a/spec/lib/jasmine/headless/file_checker_spec.rb b/spec/lib/jasmine/headless/file_checker_spec.rb
index d105222..0e14a11 100644
--- a/spec/lib/jasmine/headless/file_checker_spec.rb
+++ b/spec/lib/jasmine/headless/file_checker_spec.rb
@@ -1,41 +1,25 @@
 require 'spec_helper'
 
 describe Jasmine::Headless::FileChecker do
+  include FakeFS::SpecHelpers
+
   let(:test_class) do
     object = Object.new
     object.class.send(:include, Jasmine::Headless::FileChecker)
     object
   end
 
-  describe "#bad_format?" do
-    subject { test_class.bad_format?(file) }
-
-    before do
-      test_class.stubs(:excluded_formats).returns(%w{erb string})
+  context "bad_format?" do
+    it "should return false wth correct format" do
+      test_class.bad_format?('foobar.js').should be_false
     end
 
-    context 'nil' do
-      let(:file) { nil }
-
-      it { should be_nil }
+    it "should return false wth wrong format" do
+      test_class.bad_format?('foobar.js.erb').should be_true
     end
 
-    context 'allowed format' do
-      let(:file) { 'foobar.js' }
-
-      it { should be_false }
-    end
-
-    context 'unallowed format' do
-      let(:file) { 'foobar.erb' }
-
-      it { should be_true }
-    end
-
-    context 'check whole extension' do
-      let(:file) { 'foobar.string.js' }
-
-      it { should be_true }
+    it "should check for the whole extension" do
+      test_class.bad_format?('foobar.string.js').should be_false
     end
   end
 end
diff --git a/spec/lib/jasmine/headless/files_list_spec.rb b/spec/lib/jasmine/headless/files_list_spec.rb
index 542e8f8..d69b34b 100644
--- a/spec/lib/jasmine/headless/files_list_spec.rb
+++ b/spec/lib/jasmine/headless/files_list_spec.rb
@@ -6,188 +6,243 @@ describe Jasmine::Headless::FilesList do
   let(:files_list) { described_class.new }
 
   describe '#initialize' do
+    it "should have default files" do
+      files_list.files.should == [
+        File.join(Jasmine::Core.path, "jasmine.js"),
+        File.join(Jasmine::Core.path, "jasmine-html.js"),
+        File.join(Jasmine::Core.path, "jasmine.css"),
+        File.expand_path('vendor/assets/javascripts/jasmine-extensions.js'),
+        File.expand_path('vendor/assets/javascripts/intense.js'),
+        File.expand_path('vendor/assets/javascripts/headless_reporter_result.js'),
+        File.expand_path('vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js'),
+        File.expand_path('vendor/assets/javascripts/jsDump.js'),
+        File.expand_path('vendor/assets/javascripts/beautify-html.js'),
+      ]
+    end
+  end
+
+  def self.no_default_files!
     before do
-      described_class.any_instance.stubs(:load_initial_assets)
+      described_class.stubs(:default_files).returns([])
+    end
+  end
+
+  it 'should have tests for #use_config!'
+  it 'should have tests for #add_files'
+
+  describe '#spec_file_line_numbers' do
+    include FakeFS::SpecHelpers
+
+    no_default_files!
+
+    before do
+      files_list.stubs(:spec_files).returns(['test.coffee', 'test2.coffee'])
+
+      File.open('test.coffee', 'w') { |fh| fh.print "describe('cat')\ndescribe('cat')" }
+      File.open('test2.coffee', 'w') { |fh| fh.print "no matches" }
     end
 
-    describe '#spec_file_line_numbers' do
-      include FakeFS::SpecHelpers
+    it 'should generate filenames and line number info' do
+      files_list.spec_file_line_numbers.should == {
+        'test.coffee' => { 'cat' => [ 1, 2 ] }
+      }
+    end
+  end
 
-      before do
-        files_list.stubs(:spec_files).returns(['test.coffee', 'test2.coffee'])
+  describe '.get_paths_from_gemspec' do
+    include FakeFS::SpecHelpers
 
-        File.open('test.coffee', 'w') { |fh| fh.print "describe('cat')\ndescribe('cat')" }
-        File.open('test2.coffee', 'w') { |fh| fh.print "no matches" }
-      end
+    let(:gem_dir) { "dir" }
+    let(:gemspec) { stub(:gem_dir => gem_dir) }
 
-      it 'should generate filenames and line number info' do
-        files_list.spec_file_line_numbers.should == {
-          'test.coffee' => { 'cat' => [ 1, 2 ] }
-        }
+    let(:paths) do
+      %w{vendor lib app}.collect do |dir|
+        File.join(gem_dir, dir, 'assets/javascripts')
       end
     end
 
-    describe '#search_paths' do
-      let(:files_list) { described_class.new(:config => config) }
+    before do
+      paths.each { |path| FileUtils.mkdir_p path }
 
-      let(:config) { {
-        'src_dir' => src_dir,
-        'spec_dir' => spec_dir,
-        'asset_paths' => asset_paths
-      } }
+      described_class.instance_variable_set(:@asset_paths, [])
+    end
 
-      let(:src_dir) { 'src dir' }
-      let(:spec_dir) { 'spec dir' }
-      let(:asset_paths) { [] }
-      let(:path) { 'path' }
+    subject { described_class.get_paths_from_gemspec(gemspec) }
 
+    it { should =~ paths }
+  end
+
+  describe '#search_paths' do
+    no_default_files!
+
+    let(:files_list) { described_class.new(:config => config) }
+
+    let(:config) { {
+      'src_dir' => src_dir,
+      'spec_dir' => spec_dir,
+      'asset_paths' => asset_paths
+    } }
+
+    let(:src_dir) { 'src dir' }
+    let(:spec_dir) { 'spec dir' }
+    let(:asset_paths) { [] }
+    let(:path) { 'path' }
+
+    before do
+      Jasmine::Headless::FilesList.stubs(:asset_paths).returns([])
+    end
+
+    let(:vendor_path) { Jasmine::Headless.root.join('vendor/assets/javascripts').to_s }
+
+    context 'no vendored gem paths' do
+      it 'should take the src dir and spec dirs' do
+        files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(src_dir), File.expand_path(spec_dir) ]
+      end
+    end
+
+    context 'vendored gem paths' do
       before do
-        Jasmine::Headless::FilesList.stubs(:asset_paths).returns([])
+        Jasmine::Headless::FilesList.stubs(:asset_paths).returns([ path ])
       end
 
-      let(:vendor_path) { Jasmine::Headless.root.join('vendor/assets/javascripts').to_s }
+      it 'should add the vendor gem paths to the list' do
+        files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, path, File.expand_path(src_dir), File.expand_path(spec_dir) ]
+      end
+    end
+
+    context 'multiple dirs' do
+      let(:dir_1) { 'dir 1' }
+      let(:dir_2) { 'dir 2' }
+
+      context 'src_dir is an array' do
+        let(:src_dir) { [ dir_1, dir_2 ] }
 
-      context 'no vendored gem paths' do
         it 'should take the src dir and spec dirs' do
-          files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(src_dir), File.expand_path(spec_dir) ]
+          files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(dir_1), File.expand_path(dir_2), File.expand_path(spec_dir) ]
         end
       end
 
-      context 'vendored gem paths' do
-        before do
-          Jasmine::Headless::FilesList.stubs(:asset_paths).returns([ path ])
-        end
+      context 'asset_paths has entries' do
+        let(:src_dir) { dir_1 }
+        let(:asset_paths) { [ dir_2 ] }
 
-        it 'should add the vendor gem paths to the list' do
-          files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, path, File.expand_path(src_dir), File.expand_path(spec_dir) ]
-        end
-      end
-
-      context 'multiple dirs' do
-        let(:dir_1) { 'dir 1' }
-        let(:dir_2) { 'dir 2' }
-
-        context 'src_dir is an array' do
-          let(:src_dir) { [ dir_1, dir_2 ] }
-
-          it 'should take the src dir and spec dirs' do
-            files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(dir_1), File.expand_path(dir_2), File.expand_path(spec_dir) ]
-          end
-        end
-
-        context 'asset_paths has entries' do
-          let(:src_dir) { dir_1 }
-          let(:asset_paths) { [ dir_2 ] }
-
-          it 'should take the src dir and spec dirs' do
-            files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(dir_1), File.expand_path(dir_2), File.expand_path(spec_dir) ]
-          end
+        it 'should take the src dir and spec dirs' do
+          files_list.search_paths.should == [ Jasmine::Core.path, vendor_path, File.expand_path(dir_1), File.expand_path(dir_2), File.expand_path(spec_dir) ]
         end
       end
     end
+  end
 
-    describe '#files' do
-      let(:path_one) { 'one' }
-      let(:path_two) { 'two' }
-      let(:path_three) { 'three' }
+  describe '.asset_paths' do
+    include FakeFS::SpecHelpers
 
-      let(:file_one) { stub(:to_a => [ asset_one, asset_two ] ) }
-      let(:file_two) { stub(:to_a => [ asset_two, asset_three ] ) }
+    let(:dir_one) { 'dir_one' }
+    let(:dir_two) { 'dir_two' }
 
-      let(:asset_one) { stub(:pathname => Pathname(path_one), :to_ary => nil) }
-      let(:asset_two) { stub(:pathname => Pathname(path_two), :to_ary => nil) }
-      let(:asset_three) { stub(:pathname => Pathname(path_three), :to_ary => nil) }
+    let(:gem_one) { stub(:gem_dir => dir_one) }
+    let(:gem_two) { stub(:gem_dir => dir_two) }
 
-      before do
-        files_list.stubs(:required_files).returns(Jasmine::Headless::UniqueAssetList.new([ file_one, file_two ]))
-      end
+    before do
+      described_class.instance_variable_set(:@asset_paths, nil)
 
-      subject { files_list.files }
+      FileUtils.mkdir_p File.join(dir_two, 'vendor/assets/javascripts')
 
-      it { should == [ path_one, path_two, path_three ] }
+      Gem::Specification.stubs(:_all).returns([gem_one, gem_two])
     end
 
-    describe '#filtered_files' do
-      let(:spec_dir) { 'spec' }
+    it 'should return all matching gems with vendor/assets/javascripts directories' do
+      described_class.asset_paths.should == [ File.join(dir_two, 'vendor/assets/javascripts') ]
+    end
+  end
 
-      let(:file_one) { "#{spec_dir}/one" }
-      let(:file_two) { "#{spec_dir}/two" }
-      let(:file_three) { "#{spec_dir}/three" }
-      let(:file_four) { 'other/four' }
+  describe '#files' do
+    let(:path_one) { 'one' }
+    let(:path_two) { 'two' }
+    let(:path_three) { 'three' }
 
-      before do
-        files_list.stubs(:files).returns([
-                                         file_one,
-                                         file_two,
-                                         file_three,
-                                         file_four
-        ])
+    let(:file_one) { stub(:to_a => [ asset_one, asset_two ] ) }
+    let(:file_two) { stub(:to_a => [ asset_two, asset_three ] ) }
 
-        files_list.stubs(:potential_files_to_filter).returns([ file_one, file_two, file_three ])
-      end
+    let(:asset_one) { stub(:pathname => Pathname(path_one), :to_ary => nil) }
+    let(:asset_two) { stub(:pathname => Pathname(path_two), :to_ary => nil) }
+    let(:asset_three) { stub(:pathname => Pathname(path_three), :to_ary => nil) }
 
-      subject { files_list.filtered_files }
-
-      context 'empty filter' do
-        before do
-          files_list.stubs(:spec_filter).returns([])
-        end
-
-        it { should == [ file_one, file_two, file_three, file_four ] }
-      end
-
-      context 'with filter' do
-        before do
-          files_list.stubs(:spec_filter).returns([ "#{spec_dir}/one", '**/tw*' ])
-        end
-
-        it { should == [ file_one, file_two, file_four ] }
-      end
+    before do
+      files_list.stubs(:required_files).returns(Jasmine::Headless::UniqueAssetList.new([ file_one, file_two ]))
     end
 
-    describe '#add_files' do
-      let(:files_list) { described_class.new(:seed => 100) }
+    subject { files_list.files }
 
-      let(:dir) { 'tmp' }
+    it { should == [ path_one, path_two, path_three ] }
+  end
 
-      before do
-        FileUtils.mkdir_p dir
+  describe '#filtered_files' do
+    let(:spec_dir) { 'spec' }
 
-        10.times do |index|
-          File.open(File.join(dir, "file-#{index}.js"), 'wb')
-        end
+    let(:file_one) { "#{spec_dir}/one" }
+    let(:file_two) { "#{spec_dir}/two" }
+    let(:file_three) { "#{spec_dir}/three" }
+    let(:file_four) { 'other/four' }
 
-        File.open(File.join(dir, 'file.js.erb'), 'wb')
-      end
+    before do
+      files_list.stubs(:files).returns([
+        file_one,
+        file_two,
+        file_three,
+        file_four
+      ])
 
-      before do
-        files_list.send(:add_files, [ '*' ], 'spec_files', [ dir ])
-      end
-
-      it 'should load spec files in a random order' do
-        files_list.files.collect { |name| name[%r{\d+}] }.should == %w{6 7 1 0 5 3 4 8 2 9}
-
-        FileUtils.rm_rf dir
-      end
-
-      it 'should not load an excluded format' do
-        files_list.files.any? { |file| file['.erb'] }.should be_false
-      end
+      files_list.stubs(:potential_files_to_filter).returns([ file_one, file_two, file_three ])
     end
 
-    describe "#register_engine!" do
+    subject { files_list.filtered_files }
 
-      before(:each) do
-        Jasmine::Headless::FilesList.reset!
+    context 'empty filter' do
+      before do
+        files_list.stubs(:spec_filter).returns([])
       end
 
-      it "should register code added via configure blocks" do
-        template_class = mock()
-        described_class.register_engine ".foo", template_class
-        Sprockets.expects(:register_engine).with(".foo", template_class)
-        described_class.new
+      it { should == [ file_one, file_two, file_three, file_four ] }
+    end
+
+    context 'with filter' do
+      before do
+        files_list.stubs(:spec_filter).returns([ "#{spec_dir}/one", '**/tw*' ])
       end
 
+      it { should == [ file_one, file_two, file_four ] }
+    end
+  end
+
+  describe '#add_files' do
+    let(:files_list) { described_class.new(:seed => 100) }
+
+    no_default_files!
+
+    let(:dir) { 'tmp' }
+
+    before do
+      FileUtils.mkdir_p dir
+
+      10.times do |index|
+        File.open(File.join(dir, "file-#{index}.js"), 'wb')
+      end
+
+      File.open(File.join(dir, 'file.js.erb'), 'wb')
+    end
+
+    before do
+      files_list.send(:add_files, [ '*' ], 'spec_files', [ dir ])
+    end
+
+    it 'should load spec files in a random order' do
+      files_list.files.collect { |name| name[%r{\d+}] }.should == %w{6 7 1 0 5 3 4 8 2 9}
+
+      FileUtils.rm_rf dir
+    end
+
+    it 'should not load an excluded format' do
+      files_list.files.any? { |file| file['.erb'] }.should be_false
     end
   end
 end
diff --git a/spec/lib/jasmine/headless/options_spec.rb b/spec/lib/jasmine/headless/options_spec.rb
index 0a14222..237423d 100644
--- a/spec/lib/jasmine/headless/options_spec.rb
+++ b/spec/lib/jasmine/headless/options_spec.rb
@@ -43,35 +43,6 @@ describe Jasmine::Headless::Options do
       options[:colors].should be_true
       options[:jasmine_config].should == 'test'
     end
-
-    context 'legacy reporter' do
-      let(:file) { 'file' }
-
-      before do
-        options.expects(:warn)
-      end
-
-      it 'should add a legacy reporter' do
-        options[:reporters] = []
-
-        options.process_option("--report", file)
-
-        options[:reporters].should == [ [ 'File', file ], [ 'Console' ] ]
-      end
-    end
-
-    context 'short reporter' do
-      let(:reporter) { 'reporter' }
-      let(:file) { 'file' }
-
-      it 'should add a reporter' do
-        options[:reporters] = []
-
-        options.process_option("--format", "#{reporter}:#{file}")
-
-        options[:reporters].should == [ [ reporter, file ] ]
-      end
-    end
   end
 
   describe '#read_defaults_files' do
@@ -139,56 +110,8 @@ describe Jasmine::Headless::Options do
       end
     end
 
-    let(:test_reporter) { 'TestReporter' }
-    let(:file) { 'file' }
-
-    context 'no reporters' do
-      it 'should have the default reporter' do
-        options[:reporters].should == [ [ 'Console' ] ]
-      end
-    end
-
-    context 'one reporter' do
-      context 'stdout' do
-        before do
-          ARGV.replace([ "--format", test_reporter ])
-        end
-
-        it 'should have the new reporter on stdout' do
-          options[:reporters].should == [ [ test_reporter ] ]
-
-          options.reporters.should == [ [ test_reporter, 'stdout' ] ]
-        end
-      end
-
-      context 'file' do
-        before do
-          ARGV.replace([ "--format", test_reporter, '--out', file ])
-        end
-
-        it 'should have the new reporter on stdout' do
-          options[:reporters].should == [ [ test_reporter, file ] ]
-
-          options.reporters.should == [ [ test_reporter, 'report:0', file ] ]
-        end
-      end
-    end
-
     after do
       ARGV.replace(@argv)
     end
   end
-
-  describe '#file_reporters' do
-    subject { options.file_reporters }
-
-    let(:stdout_reporter) { [ 'Console', 'stdout' ] }
-    let(:file_reporter) { [ 'File', 'report:0', 'file' ] }
-
-    before do
-      options.stubs(:reporters).returns([ stdout_reporter, file_reporter ])
-    end
-
-    it { should == [ file_reporter ] }
-  end
 end
diff --git a/spec/lib/jasmine/headless/report_message/seed_spec.rb b/spec/lib/jasmine/headless/report_message/seed_spec.rb
deleted file mode 100644
index 604ec45..0000000
--- a/spec/lib/jasmine/headless/report_message/seed_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'spec_helper'
-
-describe Jasmine::Headless::ReportMessage::Seed do
-  let(:seed) { described_class.new(seed_value) }
-  let(:seed_value) { '1' }
-
-  subject { seed }
-
-  its(:seed) { should == seed_value.to_i }
-
-  describe '.new_from_parts' do
-    subject { described_class.new_from_parts(parts) }
-
-    let(:parts) { [ seed_value ] }
-
-    its(:seed) { should == seed_value.to_i }
-  end
-end
diff --git a/spec/lib/jasmine/headless/report_spec.rb b/spec/lib/jasmine/headless/report_spec.rb
index 179b186..9899a9c 100644
--- a/spec/lib/jasmine/headless/report_spec.rb
+++ b/spec/lib/jasmine/headless/report_spec.rb
@@ -2,9 +2,6 @@ require 'spec_helper'
 
 describe Jasmine::Headless::Report do
   include FakeFS::SpecHelpers
-  
-  let(:report) { described_class.new(file) }
-  let(:file) { 'file' }
 
   let(:file) { 'report.txt' }
 
@@ -78,18 +75,5 @@ REPORT
       end
     end
   end
-
-  describe '#seed' do
-    subject { report.seed }
-
-    let(:seed) { stub(:seed => seed_number) }
-    let(:seed_number) { 1 }
-
-    before do
-      report.stubs(:report).returns([ seed ])
-    end
-
-    it { should == seed_number }
-  end
 end
 
diff --git a/spec/lib/jasmine/headless/runner_spec.rb b/spec/lib/jasmine/headless/runner_spec.rb
index b042d95..6c2787c 100644
--- a/spec/lib/jasmine/headless/runner_spec.rb
+++ b/spec/lib/jasmine/headless/runner_spec.rb
@@ -36,17 +36,14 @@ describe Jasmine::Headless::Runner do
 
     context 'file exists' do
       before do
-        File.open(config_filename, 'w') { |fh| fh.print YAML.dump('test' => 'hello', 'erb' => '<%= "erb" %>') }
+        File.open(Jasmine::Headless::Runner::RUNNER, 'w')
+        File.open(config_filename, 'w') { |fh| fh.print YAML.dump('test' => 'hello') }
       end
 
       it 'should load the jasmine config' do
         runner.jasmine_config['test'].should == 'hello'
         runner.jasmine_config['spec_dir'].should == 'spec/javascripts'
       end
-
-      it 'should execute ERB in the config file' do
-        runner.jasmine_config['erb'].should == 'erb'
-      end
     end
 
     context 'file does not exist' do
@@ -57,48 +54,51 @@ describe Jasmine::Headless::Runner do
   end
 
   describe '#jasmine_command' do
-    subject { runner.jasmine_command(target) }
+    let(:opts) { {
+      :colors => true,
+      :report => 'test'
+    } }
 
-    let(:target) { 'target' }
+    it 'should have the right options' do
+      runner.jasmine_command.should match(/jasmine-webkit-specrunner/)
+      runner.jasmine_command.should match(/-c/)
+      runner.jasmine_command.should match(/-r test/)
+      runner.jasmine_command('file.js').should match(/file.js/)
+    end
+  end
 
-    let(:options) { {} }
-    let(:reporters) { [] }
+  context 'real tests' do
+    let(:report) { 'spec/report.txt' }
 
     before do
-      runner.stubs(:options).returns(options)
-      options.stubs(:file_reporters).returns(reporters)
+      FileUtils.rm_f report
     end
 
-    def self.it_should_have_basics
-      it { should include(target) }
+    after do
+      FileUtils.rm_f report
     end
 
-    context 'colors' do
-      before do
-        options[:colors] = true
-      end
+    it 'should succeed with error code 0' do
+      Jasmine::Headless::Runner.run(
+        :jasmine_config => 'spec/jasmine/success/success.yml',
+        :report => report
+      ).should == 0
 
-      it_should_have_basics
-      it { should include('-c') }
+      report.should be_a_report_containing(1, 0, false)
     end
 
-    context 'reporters' do
-      let(:reporter) { [ 'Reporter', 'identifier', file ] }
-      let(:reporters) { [ reporter ] }
-
-      let(:file) { 'file' }
-
-      it_should_have_basics
-      it { should include("-r #{file}") }
+    it 'should succeed but with javascript error' do
+      Jasmine::Headless::Runner.run(:jasmine_config => 'spec/jasmine/success_with_error/success_with_error.yml').should == 1
     end
 
-    context 'quiet' do
-      before do
-        options[:quiet] = true
-      end
+    it 'should fail on one test' do
+      Jasmine::Headless::Runner.run(
+        :jasmine_config => 'spec/jasmine/failure/failure.yml',
+        :report => report
+      ).should == 1
 
-      it_should_have_basics
-      it { should include("-q") }
+      report.should be_a_report_containing(1, 1, false)
+      report.should contain_a_failing_spec(['failure', 'should fail with error code of 1'])
     end
   end
 
@@ -167,81 +167,4 @@ describe Jasmine::Headless::Runner do
       runner.jasmine_config['spec_files'].should == described_class::JASMINE_DEFAULTS['spec_files']
     end
   end
-
-  describe '#files_list' do
-    subject { runner.files_list }
-
-    let(:options) { { :files => only, :seed => seed } }
-
-    let(:only) { 'only' }
-    let(:seed) { 12345 }
-    let(:jasmine_config) { 'jasmine config' }
-    let(:reporters) { [] }
-
-    before do
-      runner.stubs(:options).returns(options)
-      runner.stubs(:jasmine_config).returns(jasmine_config)
-
-      options.stubs(:reporters).returns(reporters)
-    end
-
-    it { should be_a_kind_of(Jasmine::Headless::FilesList) }
-
-    it 'should have settings' do
-      subject.options[:config].should == jasmine_config
-      subject.options[:only].should == only
-      subject.options[:seed].should == seed
-      subject.options[:reporters].should == reporters
-    end
-  end
-
-  describe '.server_port' do
-    before do
-      described_class.instance_variable_set(:@server_port, nil)
-    end
-
-    context 'port in use' do
-      require 'socket'
-
-      before do
-        described_class.stubs(:select_server_port).returns(5000, 5001)
-      end
-
-      it 'should try another port' do
-        server = TCPServer.new(described_class.server_interface, 5000)
-
-        described_class.server_port.should == 5001
-      end
-    end
-  end
-
-  describe '#absolute_run_targets' do
-    let(:opts) { {} }
-
-    subject { runner.absolute_run_targets(targets) }
-
-    let(:targets) { [ target ] }
-    let(:target) { 'target' }
-
-    before do
-      runner.stubs(:options).returns(:use_server => use_server)
-    end
-
-    context 'server' do
-      let(:use_server) { true }
-      let(:server_spec_path) { 'server spec path' }
-
-      before do
-        described_class.stubs(:server_spec_path).returns(server_spec_path)
-      end
-
-      it { should == [ server_spec_path + target ] }
-    end
-
-    context 'no server' do
-      let(:use_server) { false }
-
-      it { should == [ 'file://' + File.expand_path(target) ] }
-    end
-  end
 end
diff --git a/spec/lib/jasmine/headless/template_writer_spec.rb b/spec/lib/jasmine/headless/template_writer_spec.rb
index b153b7c..2a9c380 100644
--- a/spec/lib/jasmine/headless/template_writer_spec.rb
+++ b/spec/lib/jasmine/headless/template_writer_spec.rb
@@ -43,50 +43,46 @@ describe Jasmine::Headless::TemplateWriter do
     end
   end
 
-  describe '#render' do
-    subject { template_writer.render }
-
-    let(:all_files) { 'all files' }
-    let(:template) { 'template' }
+  describe '#write!' do
+    include FakeFS::SpecHelpers
 
     before do
-      template_writer.stubs(:all_files).returns(all_files)
+      Jasmine::Headless::FilesList.stubs(:default_files).returns([])
 
-      template_writer.expects(:template_for).with(all_files).returns(template)
+      File.stubs(:read).returns(nil)
+
+      runner.stubs(:keep_runner).returns(true)
+      runner.stubs(:runner_filename).returns(false)
+
+      Sprockets::Environment.any_instance.stubs(:find_asset).returns(stub(:body => ''))
     end
 
-    it { should == template }
-  end
-
-  describe '#all_files' do
-    subject { template_writer.all_files }
-
-    let(:files_list) { stub }
-    let(:files) { 'files' }
+    let(:files_list) { Jasmine::Headless::FilesList.new }
 
     before do
-      template_writer.stubs(:files_list).returns(files_list)
-
-      files_list.stubs(:files_to_html).returns(files)
+      files_list.stubs(:files).returns([ 'file.js' ])
+      files_list.stubs(:filtered_files).returns([ 'file.js' ])
     end
 
-    it { should == files }
-  end
-
-  describe '#jhw_reporters' do
-    subject { template_writer.jhw_reporters }
-
-    let(:reporter) { 'reporter' }
-    let(:output) { 'output' }
-
-    before do
-      template_writer.stubs(:reporters).returns([
-        [ reporter, output ]
-      ])
+    context 'no filter' do
+      it 'should write one file' do
+        template_writer.write!(files_list).should == [
+          "jhw.#{$$}.html"
+        ]
+      end
     end
 
-    it { should include(reporter) }
-    it { should include(output) }
+    context 'filtered files' do
+      before do
+        files_list.stubs(:files).returns([ 'file.js', 'file2.js' ])
+      end
+
+      it 'should write two files' do
+        template_writer.write!(files_list).should == [
+          "jhw.#{$$}.filter.html", "jhw.#{$$}.html"
+        ]
+      end
+    end
   end
 end
 
diff --git a/spec/lib/jasmine/headless/unique_asset_list_spec.rb b/spec/lib/jasmine/headless/unique_asset_list_spec.rb
index 511922f..4759292 100644
--- a/spec/lib/jasmine/headless/unique_asset_list_spec.rb
+++ b/spec/lib/jasmine/headless/unique_asset_list_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
 describe Jasmine::Headless::UniqueAssetList do
   let(:list) { described_class.new }
 
-  let(:first) { stub(:logical_path => 'one', :pathname => 'one') }
-  let(:second) { stub(:logical_path => 'two', :pathname => 'two') }
-  let(:third) { stub(:logical_path => 'two', :pathname => 'two') }
+  let(:first) { stub(:logical_path => 'one') }
+  let(:second) { stub(:logical_path => 'two') }
+  let(:third) { stub(:logical_path => 'two') }
 
   it 'should raise an exception on a non-asset' do
     expect { list << "whatever" }.to raise_error(StandardError)
diff --git a/spec/lib/jasmine/headless_spec.rb b/spec/lib/jasmine/headless_spec.rb
index ca15d2f..51f5efc 100644
--- a/spec/lib/jasmine/headless_spec.rb
+++ b/spec/lib/jasmine/headless_spec.rb
@@ -1,38 +1,2 @@
 require 'spec_helper'
 
-describe Jasmine::Headless do
-  describe '.warn' do
-    let(:output) { StringIO.new }
-
-    before do
-      described_class.stubs(:output).returns(output)
-    end
-
-    context 'warnings enabled' do
-      before do
-        described_class.stubs(:show_warnings?).returns(true)
-      end
-
-      it 'should work' do
-        described_class.warn("warning")
-
-        output.rewind
-        output.read.should == "warning\n"
-      end
-    end
-
-    context 'warnings disabled' do
-      before do
-        described_class.stubs(:show_warnings?).returns(false)
-      end
-
-      it 'should work' do
-        described_class.warn("warning")
-
-        output.rewind
-        output.read.should == ""
-      end
-    end
-  end
-end
-
diff --git a/spec/skel/template.html.erb_spec.rb b/spec/skel/template.html.erb_spec.rb
deleted file mode 100644
index e5ae2ca..0000000
--- a/spec/skel/template.html.erb_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'spec_helper'
-
-describe 'skel/template.html.erb' do
-  describe 'reporters' do
-
-  end
-end
-
diff --git a/vendor/assets/javascripts/intense.coffee b/vendor/assets/coffeescripts/intense.coffee
similarity index 69%
rename from vendor/assets/javascripts/intense.coffee
rename to vendor/assets/coffeescripts/intense.coffee
index f344f78..db00e5c 100644
--- a/vendor/assets/javascripts/intense.coffee
+++ b/vendor/assets/coffeescripts/intense.coffee
@@ -11,16 +11,16 @@ window.Intense = {
   methods:
     foreground: (color) ->
       if Intense.useColors
-        '\x1b' + "[3#{Intense.colors[color]}m#{this}" + '\x1b' + "[0m"
+        "\033[3#{Intense.colors[color]}m#{this}\033[0m"
       else
         this
     bright: ->
       if Intense.useColors
-        '\x1b' + "[1m#{this}" + '\x1b' + "[0m"
+        "\033[1m#{this}\033[0m"
       else
         this
   useColors: true
-  moveBack: (count = 1) -> '\x1b' + "[#{count}D"
+  moveBack: (count = 1) -> "\033[#{count}D"
 }
 
 for method, code of Intense.methods
diff --git a/vendor/assets/javascripts/jasmine-extensions.coffee b/vendor/assets/coffeescripts/jasmine-extensions.coffee
similarity index 88%
rename from vendor/assets/javascripts/jasmine-extensions.coffee
rename to vendor/assets/coffeescripts/jasmine-extensions.coffee
index 397e167..92dd70b 100644
--- a/vendor/assets/javascripts/jasmine-extensions.coffee
+++ b/vendor/assets/coffeescripts/jasmine-extensions.coffee
@@ -30,7 +30,15 @@ if window.JHW
     this.env.reporter.reportSpecResults(this)
 
   jasmine.Spec.prototype.fail = (e) ->
-    e = JHW.createCoffeeScriptFileException(e)
+    if e and e.sourceURL and window.CoffeeScriptToFilename
+      filename = e.sourceURL.split('/').pop()
+      if realFilename = window.CoffeeScriptToFilename[filename]
+        e = {
+          name: e.name,
+          message: e.message,
+          lineNumber: "~" + String(e.line),
+          sourceURL: realFilename
+        }
 
     expectationResult = new jasmine.ExpectationResult({
       passed: false,
@@ -39,8 +47,6 @@ if window.JHW
     })
     @results_.addResult(expectationResult)
 
-    this.env.reporter.reportException(e)
-
   jasmine.NestedResults.isValidSpecLine = (line) ->
     line.match(/^\s*expect/) != null || line.match(/^\s*return\s*expect/) != null
 
@@ -86,7 +92,7 @@ if window.JHW
 
       this.addResult_(result)
 
-    for method in [ "reportSpecWaiting", "reportSpecRunning", "reportException" ]
+    for method in [ "reportSpecWaiting", "reportSpecRunning" ]
       generator = (method) ->
         (args...) ->
           for reporter in @subReporters_
diff --git a/vendor/assets/coffeescripts/jasmine.HeadlessConsoleReporter.coffee b/vendor/assets/coffeescripts/jasmine.HeadlessConsoleReporter.coffee
new file mode 100644
index 0000000..01ab8c4
--- /dev/null
+++ b/vendor/assets/coffeescripts/jasmine.HeadlessConsoleReporter.coffee
@@ -0,0 +1,118 @@
+if !jasmine?
+  throw new Error("jasmine not loaded!")
+
+class jasmine.HeadlessConsoleReporter
+  constructor: (@callback = null) ->
+    @results = []
+    @failedCount = 0
+    @length = 0
+    @timer = null
+    @position = 0
+    @positions = "|/-\\"
+
+  reportRunnerResults: (runner) ->
+    return if this.hasError()
+
+    runtime = (new Date() - @startTime) / 1000.0
+
+    JHW.stdout.print("\n")
+
+    resultLine = this._formatResultLine(runtime)
+
+    if @failedCount == 0
+      JHW.stdout.puts("PASS: #{resultLine}".foreground('green'))
+    else
+      JHW.stdout.puts("FAIL: #{resultLine}".foreground('red'))
+      JHW.hasSpecFailure()
+
+    output = "TOTAL||#{@length}||#{@failedCount}||#{runtime}||#{if JHW._hasErrors then "T" else "F"}"
+
+    JHW.report.puts(output)
+
+    for result in @results
+      JHW.stdout.puts(result.toString())
+
+    if window.JHW
+      window.onbeforeunload = null
+
+    JHW.finishSuite()
+
+  reportRunnerStarting: (runner) ->
+    @startTime = new Date()
+    JHW.stdout.puts("\nRunning Jasmine specs...".bright()) if !this.hasError()
+
+  reportSpecResults: (spec) ->
+    return if this.hasError()
+    JHW.ping()
+
+    results = spec.results()
+
+    @length++
+    if results.passed()
+      JHW.stdout.print('.'.foreground('green'))
+      JHW.report.puts("PASS||" + spec.getJHWSpecInformation())
+    else
+      JHW.stdout.print('F'.foreground('red'))
+      JHW.report.puts("FAIL||" + spec.getJHWSpecInformation())
+
+      @failedCount++
+      failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
+      testCount = 1
+
+      for result in results.getItems()
+        if result.type == 'expect' and !result.passed_
+          if foundLine = result.expectations[testCount - 1]
+            [ result.line, result.lineNumber ] = foundLine
+          failureResult.addResult(result)
+        testCount += 1
+      @results.push(failureResult)
+
+  reportSpecStarting: (spec) ->
+    if this.hasError()
+      spec.finish()
+      spec.suite.finish()
+
+  reportSpecWaiting: ->
+    runner = null
+
+    if !@timer
+      @timer = true
+      first = true
+
+      runner = =>
+        @timer = setTimeout(
+          =>
+            if @timer
+              JHW.stdout.print(Intense.moveBack()) if !first
+              JHW.stdout.print(@positions.substr(@position, 1).foreground('yellow'))
+              @position += 1
+              @position %= @positions.length
+              first = false
+              runner()
+          , 750
+        )
+      runner()
+
+  reportSpecRunning: ->
+    if @timer
+      clearTimeout(@timer)
+      @timer = null
+      JHW.stdout.print(Intense.moveBack())
+
+  reportSuiteResults: (suite) ->
+  hasError: ->
+    JHW._hasErrors
+
+  _formatResultLine: (runtime) ->
+    line = []
+    line.push(@length)
+    line.push((if @length == 1 then "test" else "tests") + ',')
+
+    line.push(@failedCount)
+    line.push((if @failedCount == 1 then "failure" else "failures") + ',')
+
+    line.push(runtime)
+    line.push((if runtime == 1.0 then "sec" else "secs") + '.')
+
+    line.join(' ')
+
diff --git a/vendor/assets/coffeescripts/prolog.coffee b/vendor/assets/coffeescripts/prolog.coffee
index a1fcd2e..09fbcf7 100644
--- a/vendor/assets/coffeescripts/prolog.coffee
+++ b/vendor/assets/coffeescripts/prolog.coffee
@@ -26,74 +26,47 @@ if window.JHW
       console.log(data)
       data
 
-  puts = (message) ->
-    JHW.print('stdout', message + "\n")
-
-  warn = (message) ->
-    puts(message) if !JHW.isQuiet()
-
-  # handle unloading
   window.onbeforeunload = (e) ->
     e = e || window.event
 
     JHW.hasError()
-    warn "The code tried to leave the test page. Check for unhandled form submits and link clicks."
+    JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.')
 
-    e.returnValue = 'string' if e
+    if e
+      e.returnValue = 'string'
 
     return 'string'
 
-  # script errors
-  JHW._hasErrors = false
-  JHW._handleError = (message, lineNumber, sourceURL) ->
-    JHW.print('stderr', message + "\n")
-    JHW._hasErrors = true
-    false
-
-  # dialogs
-  window.confirm = ->
-    warn "#{"[confirm]".foreground('red')} You should mock window.confirm. Returning true."
-
-    true
-
-  window.prompt =  ->
-    warn "#{"[prompt]".foreground('red')} You should mock window.prompt. Returning true."
-
+  window.confirm = (message) ->
+    JHW.stderr.puts("#{"[confirm]".foreground('red')} jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.")
     true
 
   window.alert = (message) ->
-    warn "[alert] ".foreground('red') + message
+    JHW.stderr.puts("[alert] ".foreground('red') + message)
 
-  # color support
-  JHW._setColors = (useColors) -> Intense.useColors = useColors
+  JHW._hasErrors = false
+  JHW._handleError = (message, lineNumber, sourceURL) ->
+    JHW.stderr.puts(message)
+    JHW._hasErrors = true
+    false
+
+  JHW._setColors = (useColors) ->
+    Intense.useColors = useColors
+
+  createHandle = (handle) ->
+    JHW[handle] =
+      print: (content) -> JHW.print(handle, content)
+      puts: (content) -> JHW.print(handle, content + "\n")
+
+  createHandle(handle) for handle in [ 'stdout', 'stderr', 'report' ]
 
-  # console.log support
   JHW._usedConsole = false
+
   JHW.log = (msg) ->
     JHW.hasUsedConsole()
-
-    for reporter in jasmine.getEnv().reporter.subReporters_
-      reporter.consoleLogUsed(msg) if reporter.consoleLogUsed?
-
+    JHW.report.puts("CONSOLE||#{msg}")
     JHW._usedConsole = true
-
-    puts msg
-
-  JHW.createCoffeeScriptFileException = (e) ->
-    if e and e.sourceURL
-      filename = e.sourceURL.split('/').pop()
-
-      e =
-        name: e.name
-        message: e.message
-        sourceURL: e.sourceURL
-        lineNumber: e.line
-
-      if window.CoffeeScriptToFilename and realFilename = window.CoffeeScriptToFilename[filename]
-        e.sourceURL = realFilename
-        e.lineNumber = "~" + String(e.line)
-
-    e
+    JHW.stdout.puts(msg)
 
 window.CoffeeScriptToFilename = {}
 window.CSTF = window.CoffeeScriptToFilename
diff --git a/vendor/assets/javascripts/headless_reporter_result.js b/vendor/assets/javascripts/headless_reporter_result.js
index 2ff7348..7fdc972 100644
--- a/vendor/assets/javascripts/headless_reporter_result.js
+++ b/vendor/assets/javascripts/headless_reporter_result.js
@@ -1,4 +1,3 @@
-(function() {
 
   window.HeadlessReporterResult = (function() {
 
@@ -75,5 +74,3 @@
     return HeadlessReporterResult;
 
   })();
-
-}).call(this);
diff --git a/vendor/assets/javascripts/intense.js b/vendor/assets/javascripts/intense.js
new file mode 100644
index 0000000..8341721
--- /dev/null
+++ b/vendor/assets/javascripts/intense.js
@@ -0,0 +1,44 @@
+(function() {
+  var code, method, _ref;
+
+  window.Intense = {
+    colors: {
+      black: 0,
+      red: 1,
+      green: 2,
+      yellow: 3,
+      blue: 4,
+      magenta: 5,
+      cyan: 6,
+      white: 7
+    },
+    methods: {
+      foreground: function(color) {
+        if (Intense.useColors) {
+          return "\033[3" + Intense.colors[color] + "m" + this + "\033[0m";
+        } else {
+          return this;
+        }
+      },
+      bright: function() {
+        if (Intense.useColors) {
+          return "\033[1m" + this + "\033[0m";
+        } else {
+          return this;
+        }
+      }
+    },
+    useColors: true,
+    moveBack: function(count) {
+      if (count == null) count = 1;
+      return "\033[" + count + "D";
+    }
+  };
+
+  _ref = Intense.methods;
+  for (method in _ref) {
+    code = _ref[method];
+    String.prototype[method] = code;
+  }
+
+}).call(this);
diff --git a/vendor/assets/javascripts/jasmine-extensions.js b/vendor/assets/javascripts/jasmine-extensions.js
new file mode 100644
index 0000000..da5394c
--- /dev/null
+++ b/vendor/assets/javascripts/jasmine-extensions.js
@@ -0,0 +1,129 @@
+(function() {
+  var generator, getSplitName, method, pauseAndRun, _i, _len, _ref;
+  var __slice = Array.prototype.slice;
+
+  if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
+    throw new Error("jasmine not laoded!");
+  }
+
+  if (window.JHW) {
+    getSplitName = function(parts) {
+      parts.push(String(this.description).replace(/[\n\r]/g, ' '));
+      return parts;
+    };
+    jasmine.Suite.prototype.getSuiteSplitName = function() {
+      return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
+    };
+    jasmine.Spec.prototype.getSpecSplitName = function() {
+      return this.getSplitName(this.suite.getSuiteSplitName());
+    };
+    jasmine.Suite.prototype.getSplitName = getSplitName;
+    jasmine.Spec.prototype.getSplitName = getSplitName;
+    jasmine.Spec.prototype.getJHWSpecInformation = function() {
+      var parts, specLineInfo;
+      parts = this.getSpecSplitName();
+      specLineInfo = HeadlessReporterResult.findSpecLine(parts);
+      if (specLineInfo.file) {
+        parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
+      } else {
+        parts.push('');
+      }
+      return parts.join("||");
+    };
+    jasmine.Spec.prototype.finishCallback = function() {
+      JHW.ping();
+      return this.env.reporter.reportSpecResults(this);
+    };
+    jasmine.Spec.prototype.fail = function(e) {
+      var expectationResult, filename, realFilename;
+      if (e && e.sourceURL && window.CoffeeScriptToFilename) {
+        filename = e.sourceURL.split('/').pop();
+        if (realFilename = window.CoffeeScriptToFilename[filename]) {
+          e = {
+            name: e.name,
+            message: e.message,
+            lineNumber: "~" + String(e.line),
+            sourceURL: realFilename
+          };
+        }
+      }
+      expectationResult = new jasmine.ExpectationResult({
+        passed: false,
+        message: e ? jasmine.util.formatException(e) : 'Exception',
+        trace: {
+          stack: e.stack
+        }
+      });
+      return this.results_.addResult(expectationResult);
+    };
+    jasmine.NestedResults.isValidSpecLine = function(line) {
+      return line.match(/^\s*expect/) !== null || line.match(/^\s*return\s*expect/) !== null;
+    };
+    jasmine.NestedResults.parseFunction = function(func) {
+      var line, lineCount, lines, _i, _len, _ref;
+      lines = [];
+      lineCount = 0;
+      _ref = func.split("\n");
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        line = _ref[_i];
+        if (jasmine.NestedResults.isValidSpecLine(line)) {
+          line = line.replace(/^\s*/, '').replace(/\s*$/, '').replace(/^return\s*/, '');
+          lines.push([line, lineCount]);
+        }
+        lineCount += 1;
+      }
+      return lines;
+    };
+    jasmine.NestedResults.parseAndStore = function(func) {
+      if (!jasmine.NestedResults.ParsedFunctions[func]) {
+        jasmine.NestedResults.ParsedFunctions[func] = jasmine.NestedResults.parseFunction(func);
+      }
+      return jasmine.NestedResults.ParsedFunctions[func];
+    };
+    jasmine.NestedResults.ParsedFunctions = [];
+    if (!jasmine.WaitsBlock.prototype._execute) {
+      jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
+      jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
+      pauseAndRun = function(onComplete) {
+        JHW.timerPause();
+        jasmine.getEnv().reporter.reportSpecWaiting();
+        return this._execute(function() {
+          jasmine.getEnv().reporter.reportSpecRunning();
+          JHW.timerDone();
+          return onComplete();
+        });
+      };
+      jasmine.WaitsBlock.prototype.execute = pauseAndRun;
+      jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
+      jasmine.NestedResults.prototype.addResult_ = jasmine.NestedResults.prototype.addResult;
+      jasmine.NestedResults.prototype.addResult = function(result) {
+        result.expectations = [];
+        result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString());
+        return this.addResult_(result);
+      };
+      _ref = ["reportSpecWaiting", "reportSpecRunning"];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        method = _ref[_i];
+        generator = function(method) {
+          return function() {
+            var args, reporter, _j, _len2, _ref2, _results;
+            args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
+            _ref2 = this.subReporters_;
+            _results = [];
+            for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+              reporter = _ref2[_j];
+              if (reporter[method] != null) {
+                _results.push(reporter[method].apply(reporter, args));
+              } else {
+                _results.push(void 0);
+              }
+            }
+            return _results;
+          };
+        };
+        jasmine.MultiReporter.prototype[method] = generator(method);
+      }
+    }
+  }
+
+}).call(this);
diff --git a/vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js b/vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js
new file mode 100644
index 0000000..c276b3a
--- /dev/null
+++ b/vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js
@@ -0,0 +1,136 @@
+
+  if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
+    throw new Error("jasmine not loaded!");
+  }
+
+  jasmine.HeadlessConsoleReporter = (function() {
+
+    function HeadlessConsoleReporter(callback) {
+      this.callback = callback != null ? callback : null;
+      this.results = [];
+      this.failedCount = 0;
+      this.length = 0;
+      this.timer = null;
+      this.position = 0;
+      this.positions = "|/-\\";
+    }
+
+    HeadlessConsoleReporter.prototype.reportRunnerResults = function(runner) {
+      var output, result, resultLine, runtime, _i, _len, _ref;
+      if (this.hasError()) return;
+      runtime = (new Date() - this.startTime) / 1000.0;
+      JHW.stdout.print("\n");
+      resultLine = this._formatResultLine(runtime);
+      if (this.failedCount === 0) {
+        JHW.stdout.puts(("PASS: " + resultLine).foreground('green'));
+      } else {
+        JHW.stdout.puts(("FAIL: " + resultLine).foreground('red'));
+        JHW.hasSpecFailure();
+      }
+      output = "TOTAL||" + this.length + "||" + this.failedCount + "||" + runtime + "||" + (JHW._hasErrors ? "T" : "F");
+      JHW.report.puts(output);
+      _ref = this.results;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        result = _ref[_i];
+        JHW.stdout.puts(result.toString());
+      }
+      if (window.JHW) window.onbeforeunload = null;
+      return JHW.finishSuite();
+    };
+
+    HeadlessConsoleReporter.prototype.reportRunnerStarting = function(runner) {
+      this.startTime = new Date();
+      if (!this.hasError()) {
+        return JHW.stdout.puts("\nRunning Jasmine specs...".bright());
+      }
+    };
+
+    HeadlessConsoleReporter.prototype.reportSpecResults = function(spec) {
+      var failureResult, foundLine, result, results, testCount, _i, _len, _ref;
+      if (this.hasError()) return;
+      JHW.ping();
+      results = spec.results();
+      this.length++;
+      if (results.passed()) {
+        JHW.stdout.print('.'.foreground('green'));
+        return JHW.report.puts("PASS||" + spec.getJHWSpecInformation());
+      } else {
+        JHW.stdout.print('F'.foreground('red'));
+        JHW.report.puts("FAIL||" + spec.getJHWSpecInformation());
+        this.failedCount++;
+        failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
+        testCount = 1;
+        _ref = results.getItems();
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          result = _ref[_i];
+          if (result.type === 'expect' && !result.passed_) {
+            if (foundLine = result.expectations[testCount - 1]) {
+              result.line = foundLine[0], result.lineNumber = foundLine[1];
+            }
+            failureResult.addResult(result);
+          }
+          testCount += 1;
+        }
+        return this.results.push(failureResult);
+      }
+    };
+
+    HeadlessConsoleReporter.prototype.reportSpecStarting = function(spec) {
+      if (this.hasError()) {
+        spec.finish();
+        return spec.suite.finish();
+      }
+    };
+
+    HeadlessConsoleReporter.prototype.reportSpecWaiting = function() {
+      var first, runner;
+      var _this = this;
+      runner = null;
+      if (!this.timer) {
+        this.timer = true;
+        first = true;
+        runner = function() {
+          return _this.timer = setTimeout(function() {
+            if (_this.timer) {
+              if (!first) JHW.stdout.print(Intense.moveBack());
+              JHW.stdout.print(_this.positions.substr(_this.position, 1).foreground('yellow'));
+              _this.position += 1;
+              _this.position %= _this.positions.length;
+              first = false;
+              return runner();
+            }
+          }, 750);
+        };
+        return runner();
+      }
+    };
+
+    HeadlessConsoleReporter.prototype.reportSpecRunning = function() {
+      if (this.timer) {
+        clearTimeout(this.timer);
+        this.timer = null;
+        return JHW.stdout.print(Intense.moveBack());
+      }
+    };
+
+    HeadlessConsoleReporter.prototype.reportSuiteResults = function(suite) {};
+
+    HeadlessConsoleReporter.prototype.hasError = function() {
+      return JHW._hasErrors;
+    };
+
+    HeadlessConsoleReporter.prototype._formatResultLine = function(runtime) {
+      var line;
+      line = [];
+      line.push(this.length);
+      line.push((this.length === 1 ? "test" : "tests") + ',');
+      line.push(this.failedCount);
+      line.push((this.failedCount === 1 ? "failure" : "failures") + ',');
+      line.push(runtime);
+      line.push((runtime === 1.0 ? "sec" : "secs") + '.');
+      return line.join(' ');
+    };
+
+    return HeadlessConsoleReporter;
+
+  })();
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.Console.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.Console.coffee
deleted file mode 100644
index 0a4e75f..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.Console.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-#= require jasmine.HeadlessReporter.ConsoleBase
-#
-class jasmine.HeadlessReporter.Console extends jasmine.HeadlessReporter.ConsoleBase
-  displaySuccess: (spec) =>
-    this.print('.'.foreground('green'))
-
-  displayFailure: (spec) =>
-    this.print('F'.foreground('red'))
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.ConsoleBase.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.ConsoleBase.coffee
deleted file mode 100644
index 0c729aa..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.ConsoleBase.coffee
+++ /dev/null
@@ -1,92 +0,0 @@
-#= require jasmine.HeadlessReporter
-
-class jasmine.HeadlessReporter.ConsoleBase extends jasmine.HeadlessReporter
-  constructor: (@callback = null) ->
-    super(@callback)
-
-    @position = 0
-    @positions = "|/-\\"
-
-  formatResultLine: (runtime) ->
-    line = []
-    line.push(@length)
-    line.push((if @length == 1 then "test" else "tests") + ',')
-
-    line.push(@failedCount)
-    line.push((if @failedCount == 1 then "failure" else "failures") + ',')
-
-    line.push(runtime)
-    line.push((if runtime == 1.0 then "sec" else "secs") + '.')
-
-    line.join(' ')
-
-  reportRunnerResults: (runner) ->
-    super()
-
-    this.print("\n")
-
-    resultLine = this.formatResultLine(this._runtime())
-
-    if @failedCount == 0
-      this.puts("PASS: #{resultLine}".foreground('green'))
-    else
-      this.puts("FAIL: #{resultLine}".foreground('red'))
-
-    for result in @results
-      this.puts(result.toString())
-
-    this.puts("\nTest ordering seed: --seed #{JHW.getSeed()}")
-
-  reportRunnerStarting: (runner) ->
-    super(runner)
-    this.puts("\nRunning Jasmine specs...".bright()) if !this.hasError()
-
-  reportSpecWaiting: ->
-    if !@timer
-      @timer = true
-      @first = true
-
-      this._waitRunner()
-
-  reportSpecRunning: ->
-    if @timer
-      clearTimeout(@timer)
-      @timer = null
-      this.print(Intense.moveBack())
-
-  reportSpecResults: (spec) ->
-    super(spec)
-
-    this._reportSpecResult(spec, {
-      success: (results) =>
-        this.displaySuccess(spec)
-      failure: (results) =>
-        this.displayFailure(spec)
-
-        this.reportFailureResult(results, new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName()))
-    })
-
-  reportFailureResult: (results, failureResult) ->
-    testCount = 1
-
-    for result in results.getItems()
-      if result.type == 'expect' and !result.passed_
-        if foundLine = result.expectations[testCount - 1]
-          [ result.line, result.lineNumber ] = foundLine
-        failureResult.addResult(result)
-      testCount += 1
-    @results.push(failureResult)
-
-  _waitRunner: =>
-    @timer = setTimeout(
-      =>
-        if @timer
-          this.print(Intense.moveBack()) if !@first
-          this.print(@positions.substr(@position, 1).foreground('yellow'))
-          @position += 1
-          @position %= @positions.length
-          @first = false
-          this._waitRunner()
-      , 750
-    )
-
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.File.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.File.coffee
deleted file mode 100644
index d862d1a..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.File.coffee
+++ /dev/null
@@ -1,24 +0,0 @@
-#= require jasmine.HeadlessReporter
-#
-class jasmine.HeadlessReporter.File extends jasmine.HeadlessReporter
-  reportRunnerResults: (runner) ->
-    super(runner)
-
-    output = "TOTAL||#{@length}||#{@failedCount}||#{this._runtime()}||#{if JHW._hasErrors then "T" else "F"}"
-
-    this.puts(output)
-    this.puts("SEED||#{JHW.getSeed()}")
-
-  consoleLogUsed: (msg) ->
-    this.puts("CONSOLE||#{msg}")
-
-  reportSpecResults: (spec) ->
-    super(spec)
-
-    this._reportSpecResult(spec, {
-      success: (results) =>
-        this.puts("PASS||" + spec.getJHWSpecInformation())
-      failure: (results) =>
-        this.puts("FAIL||" + spec.getJHWSpecInformation())
-    })
-
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.Tap.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.Tap.coffee
deleted file mode 100644
index 3aa90fe..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.Tap.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-#= require jasmine.HeadlessReporter
-
-class jasmine.HeadlessReporter.Tap extends jasmine.HeadlessReporter
-  constructor: (@outputTarget = null) ->
-    super(@outputTarget)
-
-    @output = []
-
-  reportRunnerResults: (runner) ->
-    super(runner)
-
-    @output.unshift("1..#{@output.length}") if @output.length > 0
-
-    this.puts(@output.join("\n"))
-
-  reportSpecResults: (spec) ->
-    super(spec)
-
-    index = @output.length + 1
-    description = spec.getSpecSplitName().join(' ')
-
-    this._reportSpecResult(spec, {
-      success: (results) =>
-        @output.push("ok #{index} #{description}")
-      failure: (results) =>
-        @output.push("not ok #{index} #{description}")
-    })
-
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.Verbose.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.Verbose.coffee
deleted file mode 100644
index 591796f..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.Verbose.coffee
+++ /dev/null
@@ -1,64 +0,0 @@
-#= require jasmine.HeadlessReporter.ConsoleBase
-#
-class jasmine.HeadlessReporter.Verbose extends jasmine.HeadlessReporter.ConsoleBase
-  @prereport = false
-
-  displaySuccess: (spec) =>
-    this.displaySpec(spec, 'green')
-
-  displayFailure: (spec) =>
-    this.displaySpec(spec, 'red')
-
-  displaySpec: (spec, color) =>
-    currentLastNames = (@lastNames || []).slice(0)
-    @lastNames = spec.getSpecSplitName()
-
-    for line in this.indentSpec(@lastNames, currentLastNames, color)
-      if line? and !_.isEmpty(line)
-        this.puts(line)
-
-  indentSpec: (current, last, color) =>
-    last = last.slice(0)
-
-    lines = []
-
-    for name in current
-      if last.shift() != name
-        lines.push(name)
-      else
-        lines.push(null)
-
-    this.indentLines(lines, color)
-
-  indentLines: (lines, color) =>
-    indent = ''
-
-    output = []
-
-    for line in lines
-      if line?
-        outputLine = indent
-        outputLine += this.colorLine(line, color)
-
-        output.push(outputLine)
-      indent += '  '
-
-    output
-
-  colorLine: (line, color) =>
-    line.foreground(color)
-
-  reportSpecStarting: (spec) =>
-    if jasmine.HeadlessReporter.Verbose.prereport
-      this.puts(spec.getSpecSplitName().join(' '))
-
-  reportException: (e) =>
-    e = JHW.createCoffeeScriptFileException(e)
-
-    if e.sourceURL && e.lineNumber
-      output = "#{e.sourceURL}:#{e.lineNumber} #{e.message}"
-    else
-      output = e.message ? e
-
-    this.puts(output.foreground('yellow'))
-
diff --git a/vendor/assets/javascripts/jasmine.HeadlessReporter.coffee b/vendor/assets/javascripts/jasmine.HeadlessReporter.coffee
deleted file mode 100644
index 2a3a35a..0000000
--- a/vendor/assets/javascripts/jasmine.HeadlessReporter.coffee
+++ /dev/null
@@ -1,58 +0,0 @@
-if !jasmine?
-  throw new Error("jasmine not loaded!")
-
-class jasmine.HeadlessReporter
-  constructor: (@outputTarget = null) ->
-    @results = []
-    @failedCount = 0
-    @length = 0
-    @timer = null
-
-  hasError: ->
-    JHW._hasErrors
-
-  reportSpecStarting: (spec) ->
-    if this.hasError()
-      spec.finish()
-      spec.suite.finish()
-
-  reportSuiteResults: (suite) ->
-
-  reportRunnerStarting: (runner) ->
-    @startTime = new Date()
-
-  reportRunnerResults: (runner) ->
-    return if this.hasError()
-
-    if @failedCount != 0
-      JHW.hasSpecFailure()
-
-    JHW.finishSuite()
-
-    if window.JHW
-      window.onbeforeunload = null
-
-  reportSpecResults: (spec) ->
-    return if this.hasError()
-    JHW.ping()
-
-  _reportSpecResult: (spec, options) ->
-    results = spec.results()
-
-    @length++
-
-    if results.passed()
-      options.success(results, spec)
-    else
-      @failedCount++
-      options.failure(results, spec)
-
-  _runtime: ->
-    (new Date() - @startTime) / 1000.0
-
-  print: (output) =>
-    JHW.print(@outputTarget, output)
-
-  puts: (output) =>
-    JHW.print(@outputTarget, output + "\n")
-
diff --git a/vendor/assets/javascripts/prolog.js b/vendor/assets/javascripts/prolog.js
index e977e42..733c35e 100644
--- a/vendor/assets/javascripts/prolog.js
+++ b/vendor/assets/javascripts/prolog.js
@@ -1,5 +1,5 @@
 (function() {
-  var puts, warn;
+  var createHandle, handle, _i, _len, _ref;
 
   if (window.JHW) {
     window.console = {
@@ -37,67 +37,50 @@
         return data;
       }
     };
-    puts = function(message) {
-      return JHW.print('stdout', message + "\n");
-    };
-    warn = function(message) {
-      if (!JHW.isQuiet()) return puts(message);
-    };
     window.onbeforeunload = function(e) {
       e = e || window.event;
       JHW.hasError();
-      warn("The code tried to leave the test page. Check for unhandled form submits and link clicks.");
+      JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.');
       if (e) e.returnValue = 'string';
       return 'string';
     };
-    JHW._hasErrors = false;
-    JHW._handleError = function(message, lineNumber, sourceURL) {
-      JHW.print('stderr', message + "\n");
-      JHW._hasErrors = true;
-      return false;
-    };
-    window.confirm = function() {
-      warn("" + ("[confirm]".foreground('red')) + " You should mock window.confirm. Returning true.");
-      return true;
-    };
-    window.prompt = function() {
-      warn("" + ("[prompt]".foreground('red')) + " You should mock window.prompt. Returning true.");
+    window.confirm = function(message) {
+      JHW.stderr.puts("" + ("[confirm]".foreground('red')) + " jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.");
       return true;
     };
     window.alert = function(message) {
-      return warn("[alert] ".foreground('red') + message);
+      return JHW.stderr.puts("[alert] ".foreground('red') + message);
+    };
+    JHW._hasErrors = false;
+    JHW._handleError = function(message, lineNumber, sourceURL) {
+      JHW.stderr.puts(message);
+      JHW._hasErrors = true;
+      return false;
     };
     JHW._setColors = function(useColors) {
       return Intense.useColors = useColors;
     };
+    createHandle = function(handle) {
+      return JHW[handle] = {
+        print: function(content) {
+          return JHW.print(handle, content);
+        },
+        puts: function(content) {
+          return JHW.print(handle, content + "\n");
+        }
+      };
+    };
+    _ref = ['stdout', 'stderr', 'report'];
+    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+      handle = _ref[_i];
+      createHandle(handle);
+    }
     JHW._usedConsole = false;
     JHW.log = function(msg) {
-      var reporter, _i, _len, _ref;
       JHW.hasUsedConsole();
-      _ref = jasmine.getEnv().reporter.subReporters_;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        reporter = _ref[_i];
-        if (reporter.consoleLogUsed != null) reporter.consoleLogUsed(msg);
-      }
+      JHW.report.puts("CONSOLE||" + msg);
       JHW._usedConsole = true;
-      return puts(msg);
-    };
-    JHW.createCoffeeScriptFileException = function(e) {
-      var filename, realFilename;
-      if (e && e.sourceURL) {
-        filename = e.sourceURL.split('/').pop();
-        e = {
-          name: e.name,
-          message: e.message,
-          sourceURL: e.sourceURL,
-          lineNumber: e.line
-        };
-        if (window.CoffeeScriptToFilename && (realFilename = window.CoffeeScriptToFilename[filename])) {
-          e.sourceURL = realFilename;
-          e.lineNumber = "~" + String(e.line);
-        }
-      }
-      return e;
+      return JHW.stdout.puts(msg);
     };
   }