diff --git a/appveyor.yml b/appveyor.yml
index 2d6618705..852b08abb 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,8 +24,7 @@ test_script:
 
 environment:
   matrix:
-    - ruby_version: '19'
-    - ruby_version: '20'
+    - ruby_version: '200'
     - ruby_version: '21'
     - ruby_version: '22'
 
diff --git a/features/01_getting_started_with_aruba/run_commands.feature b/features/01_getting_started_with_aruba/run_commands.feature
index bbed97733..4e07c6214 100644
--- a/features/01_getting_started_with_aruba/run_commands.feature
+++ b/features/01_getting_started_with_aruba/run_commands.feature
@@ -53,7 +53,46 @@ Feature: Run commands with Aruba
     When I successfully run `cucumber`
     Then the features should all pass
 
-  @requires-ruby
+  
+  @requires-cmd
+  Scenario: Batch Program
+    Given an executable named "bin/aruba-test-cli.bat" with:
+    """bash
+    echo "Hello, Aruba!"
+    """
+    And a file named "features/hello_aruba.feature" with:
+    """
+    Feature: Getting Started With Aruba
+      Scenario: First Run of Command
+        Given I successfully run `aruba-test-cli`
+        Then the output should contain:
+        \"\"\"
+        Hello, Aruba!
+        \"\"\"
+    """
+    When I successfully run `cucumber`
+    Then the features should all pass
+
+  @requires-cmd
+  Scenario: Batch Program run via cmd
+    Given a file named "features/hello_aruba.feature" with:
+    """
+    Feature: Getting Started With Aruba
+      Scenario: First Run of Command
+        Given a file named "cli.bat" with:
+        \"\"\"
+        echo "Hello, Aruba!"
+        \"\"\"
+        When I successfully run `cmd.exe /c cli.bat`
+        Then the output should contain:
+        \"\"\"
+        Hello, Aruba!
+        \"\"\"
+    """
+    When I successfully run `cucumber`
+    Then the features should all pass
+
+  @requires-ruby @unsupported-on-platform-windows
   Scenario: Ruby Program
     Given an executable named "bin/aruba-test-cli" with:
     """ruby
diff --git a/features/02_configure_aruba/command_runtime_environment.feature b/features/02_configure_aruba/command_runtime_environment.feature
index 1d1cc337c..a3cf1cee9 100644
--- a/features/02_configure_aruba/command_runtime_environment.feature
+++ b/features/02_configure_aruba/command_runtime_environment.feature
@@ -23,7 +23,7 @@ Feature: Define default process environment
     ENV['LONG_LONG_VARIABLE'] = 'y'
 
     Aruba.configure do |config|
-      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' } 
+      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' }
     end
 
     RSpec.describe 'Environment command', :type => :aruba do
@@ -44,7 +44,7 @@ Feature: Define default process environment
     ENV['LONG_LONG_VARIABLE'] = 'y'
 
     Aruba.configure do |config|
-      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' } 
+      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' }
     end
 
     RSpec.describe 'Environment command', :type => :aruba do
@@ -67,7 +67,7 @@ Feature: Define default process environment
     ENV['LONG_LONG_VARIABLE'] = 'y'
 
     Aruba.configure do |config|
-      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' } 
+      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' }
     end
 
     RSpec.describe 'Environment command', :type => :aruba do
@@ -90,7 +90,7 @@ Feature: Define default process environment
     ENV['LONG_LONG_VARIABLE'] = 'y'
 
     Aruba.configure do |config|
-      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' } 
+      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' }
     end
 
     RSpec.describe 'Environment command', :type => :aruba do
@@ -113,7 +113,7 @@ Feature: Define default process environment
     ENV['LONG_LONG_VARIABLE'] = 'y'
 
     Aruba.configure do |config|
-      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' } 
+      config.command_runtime_environment = { 'LONG_LONG_VARIABLE' => 'x' }
     end
 
     RSpec.describe 'Environment command', :type => :aruba do
diff --git a/features/05_use_rspec_matchers/path/have_permissions.feature b/features/05_use_rspec_matchers/path/have_permissions.feature
index b0a9d6e60..88bbabff5 100644
--- a/features/05_use_rspec_matchers/path/have_permissions.feature
+++ b/features/05_use_rspec_matchers/path/have_permissions.feature
@@ -1,3 +1,4 @@
+@unsupported-on-platform-windows
 Feature: Check if path has permissions in filesystem
 
   If you need to check if a given path has some permissions in filesystem, you
diff --git a/features/step_definitions/hooks.rb b/features/step_definitions/hooks.rb
index b0e67136e..b824f48f9 100644
--- a/features/step_definitions/hooks.rb
+++ b/features/step_definitions/hooks.rb
@@ -136,3 +136,23 @@
     skip_this_scenario
   end
 end
+
+Before('@requires-bash') do |scenario|
+  next if Aruba.platform.which('bash')
+
+  if Cucumber::VERSION < '2'
+    scenario.skip_invoke!
+  else
+    skip_this_scenario
+  end
+end
+
+Before('@requires-cmd') do |scenario|
+  next if Aruba.platform.which('cmd')
+
+  if Cucumber::VERSION < '2'
+    scenario.skip_invoke!
+  else
+    skip_this_scenario
+  end
+end
\ No newline at end of file
diff --git a/features/support/env.rb b/features/support/env.rb
index 92194fe0e..e1cdc6550 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -25,4 +25,4 @@
 
   # set environment variable so child processes will merge their coverage data with parent process's coverage data.
   ENV['RUBYOPT'] = "-r#{simplecov_setup_pathname} #{ENV['RUBYOPT']}"
-end
+end
\ No newline at end of file
diff --git a/fixtures/spawn_process/stderr.sh b/fixtures/spawn_process/stderr.sh
deleted file mode 100755
index f42392209..000000000
--- a/fixtures/spawn_process/stderr.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-echo $* >&2
diff --git a/lib/aruba/configuration.rb b/lib/aruba/configuration.rb
index 14be27866..ce3953fda 100644
--- a/lib/aruba/configuration.rb
+++ b/lib/aruba/configuration.rb
@@ -28,7 +28,7 @@ class Configuration < BasicConfiguration
     option_accessor :io_wait_timeout, contract: { Num => Num }, default: 0.1
     option_accessor :startup_wait_time, contract: { Num => Num }, default: 0
     option_accessor :fixtures_directories, contract: { Array => ArrayOf[String] }, default: %w(features/fixtures spec/fixtures test/fixtures fixtures)
-    option_accessor :command_runtime_environment, contract: { Hash => Hash }, default: ENV.to_hash
+    option_accessor :command_runtime_environment, contract: { Hash => Hash }, default: {}
     # rubocop:disable Metrics/LineLength
     option_accessor(:command_search_paths, contract: { ArrayOf[String] => ArrayOf[String] }) { |config| [File.join(config.root_directory.value, 'bin'), File.join(config.root_directory.value, 'exe')] }
     # rubocop:enable Metrics/LineLength
diff --git a/lib/aruba/platforms/local_environment.rb b/lib/aruba/platforms/local_environment.rb
index 3f6d638df..2f5403289 100644
--- a/lib/aruba/platforms/local_environment.rb
+++ b/lib/aruba/platforms/local_environment.rb
@@ -14,7 +14,7 @@ class LocalEnvironment
       # @yield
       #   The block of code which should with local ENV
       def call(env)
-        old_env = ENV.to_hash.dup
+        old_env = Aruba.platform.environment_variables.hash_from_env
 
         ENV.clear
         ENV.update env
diff --git a/lib/aruba/platforms/unix_command_string.rb b/lib/aruba/platforms/unix_command_string.rb
index 9058e9c5e..a396417ca 100644
--- a/lib/aruba/platforms/unix_command_string.rb
+++ b/lib/aruba/platforms/unix_command_string.rb
@@ -6,14 +6,17 @@ module Aruba
   # Platforms
   module Platforms
     # This is a command which should be run
-    class UnixCommandString < SimpleDelegator
-      def initialize(cmd)
-        __setobj__ cmd
+    #
+    # @private
+    class UnixCommandString
+      def initialize(command, *arguments)
+        @command = command
+        @arguments = arguments
       end
 
       # Convert to array
       def to_a
-        [__getobj__]
+        [@command, *@arguments]
       end
     end
   end
diff --git a/lib/aruba/platforms/unix_environment_variables.rb b/lib/aruba/platforms/unix_environment_variables.rb
index 964a270de..9e68b75a6 100644
--- a/lib/aruba/platforms/unix_environment_variables.rb
+++ b/lib/aruba/platforms/unix_environment_variables.rb
@@ -73,7 +73,7 @@ def initialize(env = ENV)
       def update(other_env)
         actions << UpdateAction.new(other_env)
 
-        UnixEnvironmentVariables.new(to_h)
+        self
       end
 
       # Fetch variable from environment
@@ -184,11 +184,7 @@ def respond_to_missing?(name, _private)
       # @return [Hash]
       #   A new hash from environment
       def to_h
-        if RUBY_VERSION < '2.0'
-          Marshal.load(Marshal.dump(prepared_environment.to_hash))
-        else
-          Marshal.load(Marshal.dump(prepared_environment.to_h))
-        end
+        actions.inject(hash_from_env.merge(env)) { |a, e| e.call(a) }
       end
 
       # Reset environment
@@ -200,14 +196,14 @@ def clear
         value
       end
 
+      def self.hash_from_env
+        ENV.to_hash
+      end
+
       private
 
-      def prepared_environment
-        if RUBY_VERSION == '1.9.3'
-          actions.inject(ENV.to_hash.merge(env)) { |a, e| e.call(a) }
-        else
-          actions.each_with_object(ENV.to_hash.merge(env)) { |e, a| a = e.call(a) }
-        end
+      def hash_from_env
+        self.class.hash_from_env
       end
     end
   end
diff --git a/lib/aruba/platforms/windows_command_string.rb b/lib/aruba/platforms/windows_command_string.rb
index 80e128173..42bf93e75 100644
--- a/lib/aruba/platforms/windows_command_string.rb
+++ b/lib/aruba/platforms/windows_command_string.rb
@@ -1,5 +1,3 @@
-require 'delegate'
-
 # Aruba
 module Aruba
   # Platforms
@@ -9,14 +7,28 @@ module Platforms
     # This adds `cmd.exec` in front of commmand
     #
     # @private
-    class WindowsCommandString < SimpleDelegator
+    class WindowsCommandString
+      def initialize(command, *arguments)
+        @command = command
+        @arguments = arguments
+      end
+
       # Convert to array
       def to_a
-        [cmd_path, '/c', __getobj__]
+        [cmd_path, '/c', [escaped_command, *escaped_arguments].join(' ')]
       end
 
       private
 
+      def escaped_arguments
+        @arguments.map { |arg| arg.gsub(/"/, '"""') }.
+          map { |arg| arg =~ / / ? "\"#{arg}\"" : arg }
+      end
+
+      def escaped_command
+        @command.gsub(/ /, '""" """')
+      end
+
       def cmd_path
         Aruba.platform.which('cmd.exe')
       end
diff --git a/lib/aruba/platforms/windows_environment_variables.rb b/lib/aruba/platforms/windows_environment_variables.rb
index d782fcae2..96b11dd1d 100644
--- a/lib/aruba/platforms/windows_environment_variables.rb
+++ b/lib/aruba/platforms/windows_environment_variables.rb
@@ -28,16 +28,12 @@ module Platforms
     #   env["PATH"]
     #   # => nil
     class WindowsEnvironmentVariables < UnixEnvironmentVariables
-      def initialize(env = ENV.to_hash)
-        @actions = []
-
-        @env = env.each_with_object({}) { |(k, v), a| a[k.to_s.upcase] = v }
+      def initialize(env = ENV)
+        super(upcase_env env)
       end
 
       def update(other_env, &block)
-        other_env = other_env.each_with_object({}) { |(k, v), a| a[k.to_s.upcase] = v }
-
-        super(other_env, &block)
+        super(upcase_env(other_env), &block)
       end
 
       def fetch(name, default = UnixEnvironmentVariables::UNDEFINED)
@@ -67,6 +63,20 @@ def prepend(name, value)
       def delete(name)
         super(name.upcase)
       end
+
+      def self.hash_from_env
+        upcase_env(ENV)
+      end
+
+      def self.upcase_env(env)
+        env.each_with_object({}) { |(k, v), a| a[k.to_s.upcase] = v }
+      end
+
+      private
+
+      def upcase_env(env)
+        self.class.upcase_env(env)
+      end
     end
   end
 end
diff --git a/lib/aruba/processes/basic_process.rb b/lib/aruba/processes/basic_process.rb
index 93970a333..9091f08e3 100644
--- a/lib/aruba/processes/basic_process.rb
+++ b/lib/aruba/processes/basic_process.rb
@@ -14,7 +14,9 @@ class BasicProcess
       attr_reader :exit_status, :environment, :working_directory, :main_class,
         :io_wait_timeout, :exit_timeout, :startup_wait_time, :stop_signal
 
-      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, environment = ENV.to_hash.dup, main_class = nil, stop_signal = nil, startup_wait_time = 0)
+      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory,
+                     environment = Aruba.platform.environment_variables.hash_from_env,
+                     main_class = nil, stop_signal = nil, startup_wait_time = 0)
         @cmd               = cmd
         @working_directory = working_directory
         @environment       = environment
@@ -120,8 +122,6 @@ def inspect
 
       alias to_s inspect
 
-      private
-
       def command
         Shellwords.split(commandline).first
       end
@@ -132,6 +132,8 @@ def arguments
         []
       end
 
+      private
+
       def truncate(string, max_length)
         return string if string.length <= max_length
         string[0, max_length - 1] + ' ...'
diff --git a/lib/aruba/processes/in_process.rb b/lib/aruba/processes/in_process.rb
index 4c578ccb5..db1ce31b6 100644
--- a/lib/aruba/processes/in_process.rb
+++ b/lib/aruba/processes/in_process.rb
@@ -40,7 +40,9 @@ def exit(exitstatus)
       # @private
       attr_reader :main_class
 
-      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, environment = ENV.to_hash.dup, main_class = nil, stop_signal = nil, startup_wait_time = 0)
+      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory,
+                     environment = Aruba.platform.environment_variables.hash_from_env,
+                     main_class = nil, stop_signal = nil, startup_wait_time = 0)
         @cmd               = cmd
         @argv              = arguments
         @stdin             = StringIO.new
diff --git a/lib/aruba/processes/spawn_process.rb b/lib/aruba/processes/spawn_process.rb
index 4e4a48b2a..65cf13e3e 100644
--- a/lib/aruba/processes/spawn_process.rb
+++ b/lib/aruba/processes/spawn_process.rb
@@ -48,7 +48,9 @@ def self.match?(_mode)
       #
       # @param [Numeric] startup_wait_time
       #   The amount of seconds to wait after Aruba has started a command.
-      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, environment = ENV.to_hash.dup, main_class = nil, stop_signal = nil, startup_wait_time = 0)
+      def initialize(cmd, exit_timeout, io_wait_timeout, working_directory,
+                     environment = Aruba.platform.environment_variables.hash_from_env,
+                     main_class = nil, stop_signal = nil, startup_wait_time = 0)
         super
 
         @process      = nil
@@ -69,7 +71,7 @@ def start
 
         @started = true
 
-        @process = ChildProcess.build(*command_string.to_a, *arguments)
+        @process = ChildProcess.build(*command_string.to_a)
         @stdout_file = Tempfile.new('aruba-stdout-')
         @stderr_file = Tempfile.new('aruba-stderr-')
 
@@ -237,7 +239,7 @@ def send_signal(signal)
       # @return [Aruba::Platforms::FilesystemStatus]
       #   This returns a File::Stat-object
       def filesystem_status
-        Aruba.platform.filesystem_status.new(command_string.to_s)
+        Aruba.platform.filesystem_status.new(command_path)
       end
 
       # Content of command
@@ -246,7 +248,7 @@ def filesystem_status
       #   The content of the script/command. This might be binary output as
       #   string if your command is a binary executable.
       def content
-        File.read command_string.to_s
+        File.read command_path
       end
 
       def interactive?
@@ -256,12 +258,13 @@ def interactive?
       private
 
       def command_string
-        # gather fully qualified path
-        cmd = Aruba.platform.which(command, environment['PATH'])
+        fail LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) if command_path.nil?
 
-        fail LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) if cmd.nil?
+        Aruba.platform.command_string.new(command_path, *arguments)
+      end
 
-        Aruba.platform.command_string.new(cmd)
+      def command_path
+        @command_path ||= Aruba.platform.which(command, environment['PATH'])
       end
 
       def wait_for_io(time_to_wait)
diff --git a/lib/aruba/rspec.rb b/lib/aruba/rspec.rb
index 9f430d805..d89ac0704 100644
--- a/lib/aruba/rspec.rb
+++ b/lib/aruba/rspec.rb
@@ -13,7 +13,8 @@
       setup_aruba
 
       # Modify PATH to include project/bin
-      prepend_environment_variable 'PATH', aruba.config.command_search_paths.join(':') + ':'
+      prepend_environment_variable 'PATH',
+        aruba.config.command_search_paths.join(File::PATH_SEPARATOR) + File::PATH_SEPARATOR
 
       # Use configured home directory as HOME
       set_environment_variable 'HOME', aruba.config.home_directory
diff --git a/spec/aruba/matchers/command_spec.rb b/spec/aruba/matchers/command_spec.rb
index 68e76f1b9..ed6d5b699 100644
--- a/spec/aruba/matchers/command_spec.rb
+++ b/spec/aruba/matchers/command_spec.rb
@@ -71,20 +71,7 @@ def announcer(*args)
     end
 
     context 'when have output hello world on stderr' do
-      before :each do
-        string = <<-EOS.strip_heredoc
-        #!/usr/bin/env bash
-
-        echo $* >&2
-        EOS
-
-        File.open(expand_path('cmd.sh'), 'w') { |f| f.puts string }
-
-        File.chmod 0o755, expand_path('cmd.sh')
-        prepend_environment_variable 'PATH', "#{expand_path('.')}#{File::PATH_SEPARATOR}"
-      end
-
-      let(:cmd) { "cmd.sh #{output}" }
+      let(:cmd) { "ruby -e 'warn \"#{output}\"'" }
 
       before(:each) { run_command(cmd) }
 
@@ -108,20 +95,7 @@ def announcer(*args)
     end
 
     context 'when have output hello world on stderr' do
-      before :each do
-        string = <<-EOS.strip_heredoc
-        #!/usr/bin/env bash
-
-        echo $* >&2
-        EOS
-
-        File.open(expand_path('cmd.sh'), 'w') { |f| f.puts string }
-
-        File.chmod 0o755, expand_path('cmd.sh')
-        prepend_environment_variable 'PATH', "#{expand_path('.')}#{File::PATH_SEPARATOR}"
-      end
-
-      let(:cmd) { "cmd.sh #{output}" }
+      let(:cmd) { "ruby -e 'warn \"#{output}\"'" }
 
       before(:each) { run_command(cmd) }
 
@@ -145,20 +119,7 @@ def announcer(*args)
     end
 
     context 'when have output hello world on stderr' do
-      before :each do
-        string = <<-EOS.strip_heredoc
-        #!/usr/bin/env bash
-
-        echo $* >&2
-        EOS
-
-        File.open(expand_path('cmd.sh'), 'w') { |f| f.puts string }
-
-        File.chmod 0o755, expand_path('cmd.sh')
-        prepend_environment_variable 'PATH', "#{expand_path('.')}#{File::PATH_SEPARATOR}"
-      end
-
-      let(:cmd) { "cmd.sh #{output}" }
+      let(:cmd) { "ruby -e 'warn \"#{output}\"'" }
 
       before(:each) { run_command(cmd) }
 
diff --git a/spec/aruba/matchers/path_spec.rb b/spec/aruba/matchers/path_spec.rb
index 70f20f4ad..ff4152c65 100644
--- a/spec/aruba/matchers/path_spec.rb
+++ b/spec/aruba/matchers/path_spec.rb
@@ -81,7 +81,7 @@ def expand_path(*args)
         end
 
         context 'and permissions are given as octal number' do
-          let(:permissions) { 0o666 }
+          let(:permissions) { 0o644 }
 
           it { expect(file_name).to have_permissions permissions }
         end
diff --git a/spec/aruba/platforms/unix_command_string_spec.rb b/spec/aruba/platforms/unix_command_string_spec.rb
index 8fefc1c00..98a50df27 100644
--- a/spec/aruba/platforms/unix_command_string_spec.rb
+++ b/spec/aruba/platforms/unix_command_string_spec.rb
@@ -1,7 +1,8 @@
 require 'spec_helper'
 
 RSpec.describe Aruba::Platforms::UnixCommandString do
-  let(:command_string) { described_class.new(base_command) }
+  let(:command_string) { described_class.new(base_command, *arguments) }
+  let(:arguments) { [] }
 
   describe '#to_a' do
     context 'with a command with a path' do
@@ -13,5 +14,11 @@
       let(:base_command) { '/foo bar/baz' }
       it { expect(command_string.to_a).to eq [base_command] }
     end
+
+    context 'with a command and arguments' do
+      let(:base_command) { '/foo/bar' }
+      let(:arguments) { ['-w', 'baz quux'] }
+      it { expect(command_string.to_a).to eq [base_command, *arguments] }
+    end
   end
 end
diff --git a/spec/aruba/platforms/windows_command_string_spec.rb b/spec/aruba/platforms/windows_command_string_spec.rb
index 7c391478d..88141d0a0 100644
--- a/spec/aruba/platforms/windows_command_string_spec.rb
+++ b/spec/aruba/platforms/windows_command_string_spec.rb
@@ -1,8 +1,9 @@
 require 'spec_helper'
 
 RSpec.describe Aruba::Platforms::WindowsCommandString do
-  let(:command_string) { described_class.new(base_command) }
+  let(:command_string) { described_class.new(base_command, *arguments) }
   let(:cmd_path) { 'C:\Some Path\cmd.exe' }
+  let(:arguments) { [] }
 
   before do
     allow(Aruba.platform).to receive(:which).with('cmd.exe').and_return(cmd_path)
@@ -16,7 +17,13 @@
 
     context 'with a command with a path containing spaces' do
       let(:base_command) { 'C:\Foo Bar\Baz' }
-      it { expect(command_string.to_a).to eq [cmd_path, '/c', base_command] }
+      it { expect(command_string.to_a).to eq [cmd_path, '/c', 'C:\Foo""" """Bar\Baz'] }
+    end
+
+    context 'with a command and arguments' do
+      let(:base_command) { 'C:\Foo\Bar' }
+      let(:arguments) { ['-w', 'baz quux'] }
+      it { expect(command_string.to_a).to eq [cmd_path, '/c', "#{base_command} -w \"baz quux\""] }
     end
   end
 end
diff --git a/spec/aruba/processes/spawn_process_spec.rb b/spec/aruba/processes/spawn_process_spec.rb
index 664d82ac1..e1aa111ae 100644
--- a/spec/aruba/processes/spawn_process_spec.rb
+++ b/spec/aruba/processes/spawn_process_spec.rb
@@ -1,40 +1,43 @@
 require 'spec_helper'
 
 RSpec.describe Aruba::Processes::SpawnProcess do
-  subject(:process) { described_class.new(command, exit_timeout, io_wait, working_directory, environment, main_class) }
+  subject(:process) { described_class.new(command_line, exit_timeout, io_wait, working_directory) }
 
-  let(:command) { 'echo "yo"' }
+  let(:command_line) { 'echo "yo"' }
   let(:exit_timeout) { 1 }
   let(:io_wait) { 1 }
   let(:working_directory) { Dir.getwd }
-  let(:environment) { ENV.to_hash.dup }
-  let(:main_class) { nil }
 
   describe "#stdout" do
     before(:each) { process.start }
     before(:each) { process.stop }
 
     context 'when invoked once' do
-      it { expect(process.stdout).to eq "yo\n" }
+      it { expect(process.stdout.chomp).to eq 'yo' }
     end
 
     context 'when invoked twice' do
-      it { 2.times { expect(process.stdout).to eq "yo\n" } }
+      it { 2.times { expect(process.stdout.chomp).to eq 'yo' } }
     end
   end
 
   describe "#stderr" do
-    let(:command) { 'fixtures/spawn_process/stderr.sh yo' }
+    let(:command_line) { "ruby -e 'warn \"yo\"'" }
 
     before(:each) { process.start }
     before(:each) { process.stop }
 
     context 'when invoked once' do
-      it { expect(process.stderr).to eq "yo\n" }
+      it 'has the right args' do
+        expect(process.command).to eq 'ruby'
+        expect(process.arguments).to eq ['-e', 'warn "yo"']
+      end
+
+      it { expect(process.stderr.chomp).to eq 'yo'}
     end
 
     context 'when invoked twice' do
-      it { 2.times { expect(process.stderr).to eq "yo\n" } }
+      it { 2.times { expect(process.stderr.chomp).to eq 'yo'} }
     end
   end
 
@@ -62,79 +65,120 @@
     end
 
     context "when process run fails" do
-      let(:command) { 'does_not_exists' }
+      let(:command_line) { 'does_not_exists' }
 
       it { expect { process.start }.to raise_error Aruba::LaunchError }
     end
 
-    context "with a childprocess launch error" do
-      let(:child) { instance_double(ChildProcess::AbstractProcess) }
+    context 'when on unix' do
+      let(:child) { instance_double(ChildProcess::AbstractProcess).as_null_object }
+      let(:io) { instance_double(ChildProcess::AbstractIO).as_null_object }
+      let(:command_line) { 'foo' }
       let(:command) { 'foo' }
+      let(:command_path) { '/bar/foo' }
 
       before do
+        allow(Aruba.platform).to receive(:command_string).and_return Aruba::Platforms::UnixCommandString
+        allow(Aruba.platform).to receive(:which).with(command, anything).and_return(command_path)
         allow(ChildProcess).to receive(:build).and_return(child)
 
-        # STEP 1: Simlulate the program exists (but will fail to run, e.g. EACCESS?)
-        allow(Aruba.platform).to receive(:which).with(command, anything).and_return("/foo")
-
-        # STEP 2: Simulate the failure on Windows
-        allow(child).to receive(:start).and_raise(ChildProcess::LaunchError, "Foobar!")
-
-        # TODO: wrap the result of ChildProcess.build with a special Aruba
-        # class , so the remaining mocks below won't be needed
-        allow(child).to receive(:leader=)
-
-        io = instance_double(ChildProcess::AbstractIO)
-        allow(io).to receive(:stdout=)
-        allow(io).to receive(:stderr=)
-
         allow(child).to receive(:io).and_return(io)
+        allow(child).to receive(:environment).and_return({})
+      end
 
-        allow(child).to receive(:duplex=)
-        allow(child).to receive(:cwd=)
+      context 'with a childprocess launch error' do
+        before do
+          allow(child).to receive(:start).and_raise(ChildProcess::LaunchError, "Foobar!")
+        end
 
-        allow(child).to receive(:environment).and_return({})
+        it "reraises LaunchError as Aruba's LaunchError" do
+          expect { process.start }.
+            to raise_error(Aruba::LaunchError, "It tried to start #{command}. Foobar!")
+        end
       end
 
-      it "reraises LaunchError as Aruba's LaunchError" do
-        expect { process.start }.to raise_error(Aruba::LaunchError, "It tried to start foo. Foobar!")
+      context 'with a command with a space in the path' do
+        let(:command_path) { '/path with space/foo' }
+
+        before do
+          allow(Aruba.platform).to receive(:command_string).and_return Aruba::Platforms::UnixCommandString
+          allow(Aruba.platform).to receive(:which).with(command, anything).and_return(command_path)
+          allow(ChildProcess).to receive(:build).with(command_path).and_return(child)
+          allow(child).to receive(:io).and_return io
+          allow(child).to receive(:environment).and_return({})
+        end
+
+        it 'passes the command path as a single string to ChildProcess.build' do
+          process.start
+          expect(ChildProcess).to have_received(:build).with(command_path)
+        end
       end
-    end
 
-    context 'with a command with a space in the path on unix' do
-      let(:child) { instance_double(ChildProcess::AbstractProcess).as_null_object }
-      let(:io) { instance_double(ChildProcess::AbstractIO).as_null_object }
-      let(:command) { 'foo' }
-      let(:command_path) { '/path with space/foo' }
+      context 'with a command with arguments' do
+        let(:command_line) { 'foo -x "bar baz"' }
 
-      before do
-        allow(Aruba.platform).to receive(:command_string).and_return Aruba::Platforms::UnixCommandString
-        allow(Aruba.platform).to receive(:which).with(command, anything).and_return(command_path)
-        allow(ChildProcess).to receive(:build).with(command_path).and_return(child)
-        allow(child).to receive(:io).and_return io
-        allow(child).to receive(:environment).and_return({})
+        it 'passes the command and arguments as separate items to ChildProcess.build' do
+          process.start
+          expect(ChildProcess).to have_received(:build).
+            with(command_path, '-x', 'bar baz')
+        end
       end
-
-      it { expect { process.start }.to_not raise_error }
     end
 
-    context 'with a command with a space in the path on windows' do
+    context 'when on windows' do
       let(:child) { instance_double(ChildProcess::AbstractProcess).as_null_object }
       let(:io) { instance_double(ChildProcess::AbstractIO).as_null_object }
+      let(:command_line) { 'foo' }
       let(:command) { 'foo' }
-      let(:cmd_path) { 'C:\Some Path\cmd.exe' }
-      let(:command_path) { 'D:\Bar Baz\foo' }
+      let(:cmd_path) { 'C:\Bar\cmd.exe' }
+      let(:command_path) { 'D:\Foo\foo' }
 
       before do
         allow(Aruba.platform).to receive(:command_string).and_return Aruba::Platforms::WindowsCommandString
         allow(Aruba.platform).to receive(:which).with('cmd.exe').and_return(cmd_path)
         allow(Aruba.platform).to receive(:which).with(command, anything).and_return(command_path)
-        allow(ChildProcess).to receive(:build).with(cmd_path, '/c', command_path).and_return(child)
-        allow(child).to receive(:io).and_return io
+        allow(ChildProcess).to receive(:build).and_return(child)
+
+        allow(child).to receive(:io).and_return(io)
         allow(child).to receive(:environment).and_return({})
       end
 
-      it { expect { process.start }.to_not raise_error }
+      context 'with a childprocess launch error' do
+        before do
+          allow(child).to receive(:start).and_raise(ChildProcess::LaunchError, "Foobar!")
+        end
+
+        it "reraises LaunchError as Aruba's LaunchError" do
+          expect { process.start }.
+            to raise_error(Aruba::LaunchError, "It tried to start #{command}. Foobar!")
+        end
+      end
+
+      context 'with a command without a space in the path' do
+        it 'passes the command and shell paths as single strings to ChildProcess.build' do
+          process.start
+          expect(ChildProcess).to have_received(:build).with(cmd_path, '/c', command_path)
+        end
+      end
+
+      context 'with a command with a space in the path' do
+        let(:command_path) { 'D:\Bar Baz\foo' }
+
+        it 'escapes the spaces using excessive double quotes' do
+          process.start
+          expect(ChildProcess).to have_received(:build).with(cmd_path, '/c', 'D:\Bar""" """Baz\foo')
+        end
+      end
+
+      context 'with a command with arguments' do
+        let(:command_line) { "foo -x 'bar \"baz\"'" }
+
+        it 'passes the command and arguments as one string to ChildProcess.build, with escaped quotes' do
+          process.start
+          expect(ChildProcess).to have_received(:build).
+            with(cmd_path, '/c', "#{command_path} -x \"bar \"\"\"baz\"\"\"\"")
+        end
+      end
     end
   end
 end
diff --git a/spec/aruba/rspec_spec.rb b/spec/aruba/rspec_spec.rb
index e48e9394c..b36c3845b 100644
--- a/spec/aruba/rspec_spec.rb
+++ b/spec/aruba/rspec_spec.rb
@@ -19,7 +19,7 @@
     end
 
     it 'includes configured command search paths in PATH' do
-      expect(ENV['PATH']).to include aruba.config.command_search_paths.join(':')
+      expect(ENV['PATH']).to include aruba.config.command_search_paths.join(File::PATH_SEPARATOR)
     end
   end
 end