Patch by MSP-Greg
1. changes from using InternetExplorer.Application to MSXML, adds guard
2. refactors code to minimize requires if not windows
diff --git a/spec/ruby/library/win32ole/fixtures/classes.rb b/spec/ruby/library/win32ole/fixtures/classes.rb
index 830b1be0b5..6556c8e914 100644
--- a/spec/ruby/library/win32ole/fixtures/classes.rb
+++ b/spec/ruby/library/win32ole/fixtures/classes.rb
@@ -1,4 +1,8 @@
+require 'win32ole'
+  
 module WIN32OLESpecs
+  MSXML_AVAILABLE = !!WIN32OLE_TYPELIB.typelibs.find { |t| t.name.start_with?('Microsoft XML') }
+
   def self.new_ole(name)
     retried = false
     begin
diff --git a/spec/ruby/library/win32ole/fixtures/event.xml b/spec/ruby/library/win32ole/fixtures/event.xml
new file mode 100644
index 0000000000..23f3d2b126
--- /dev/null
+++ b/spec/ruby/library/win32ole/fixtures/event.xml
@@ -0,0 +1,4 @@
+
+  Ruby
+  trunk
+
diff --git a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
index 201fac9940..7d14f19da2 100644
--- a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
@@ -1,19 +1,19 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#_getproperty" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#_getproperty" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "gets name" do
-      @ie._getproperty(0, [], []).should =~ /explorer/i
+      it "gets validateOnParse" do
+        @xml_dom._getproperty(65, [], []).should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
index b38a55021b..9809f89e7c 100644
--- a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE#_invoke" do
     before :each do
diff --git a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
index 58c183e82c..4e0cf5ca55 100644
--- a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE.codepage=" do
     it "sets codepage" do
diff --git a/spec/ruby/library/win32ole/win32ole/connect_spec.rb b/spec/ruby/library/win32ole/win32ole/connect_spec.rb
index f9293e3c99..590ef7688c 100644
--- a/spec/ruby/library/win32ole/win32ole/connect_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/connect_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE.connect" do
     it "creates WIN32OLE object given valid argument" do
diff --git a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
index ed0216ce71..cacc7a2b22 100644
--- a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE.const_load when passed Shell.Application OLE object" do
     before :each do
diff --git a/spec/ruby/library/win32ole/win32ole/constants_spec.rb b/spec/ruby/library/win32ole/win32ole/constants_spec.rb
index 05d0ef99a5..978b7ade92 100644
--- a/spec/ruby/library/win32ole/win32ole/constants_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/constants_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE class" do
     it "defines constant CP_ACP" do
diff --git a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
index 3121b7ebd4..2e18b6ab11 100644
--- a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE.create_guid" do
     it "generates guid with valid format" do
diff --git a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
index 60c5cd59b6..29543a5de7 100644
--- a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
@@ -1,19 +1,19 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#invoke" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#invoke" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "get name by invoking 'Name' OLE method" do
-      @ie.invoke('Name').should =~ /explorer/i
+      it "get name by invoking 'validateOnParse' OLE method" do
+        @xml_dom.invoke('validateOnParse').should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/locale_spec.rb b/spec/ruby/library/win32ole/win32ole/locale_spec.rb
index 9b9005a37f..a0376ce123 100644
--- a/spec/ruby/library/win32ole/win32ole/locale_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/locale_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE.locale" do
     it "gets locale" do
diff --git a/spec/ruby/library/win32ole/win32ole/new_spec.rb b/spec/ruby/library/win32ole/win32ole/new_spec.rb
index ebc8a34993..cb45488288 100644
--- a/spec/ruby/library/win32ole/win32ole/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/new_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLESpecs.new_ole" do
     it "creates a WIN32OLE object from OLE server name" do
diff --git a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
index 8a510519f2..eb18758665 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
@@ -1,27 +1,27 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#ole_func_methods" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#ole_func_methods" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit if @ie
-    end
+      after :all do
+        @xml_dom =nil
+      end
 
-    it "raises ArgumentError if argument is given" do
-      lambda { @ie.ole_func_methods(1) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if argument is given" do
+        lambda { @xml_dom.ole_func_methods(1) }.should raise_error ArgumentError
+      end
 
-    it "returns an array of WIN32OLE_METHODs" do
-      @ie.ole_func_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
-    end
+      it "returns an array of WIN32OLE_METHODs" do
+        @xml_dom.ole_func_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+      end
 
-    it "contains a 'AddRef' method for Internet Explorer" do
-      @ie.ole_func_methods.map { |m| m.name }.include?('AddRef').should be_true
+      it "contains a 'AddRef' method for Internet Explorer" do
+        @xml_dom.ole_func_methods.map { |m| m.name }.include?('AddRef').should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
index 52c5df7fc6..a991624a23 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
@@ -1,7 +1,5 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
 
   describe "WIN32OLE#ole_get_methods" do
 
diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
index 3f2083225f..da55868304 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
@@ -1,8 +1,5 @@
-require_relative '../fixtures/classes'
-require_relative 'shared/ole_method'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative 'shared/ole_method'
 
   describe "WIN32OLE#ole_method_help" do
     it_behaves_like :win32ole_ole_method, :ole_method_help
diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
index 7b7be496c9..ea514e8846 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
@@ -1,12 +1,8 @@
-require_relative '../fixtures/classes'
-require_relative 'shared/ole_method'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative 'shared/ole_method'
 
   describe "WIN32OLE#ole_method" do
     it_behaves_like :win32ole_ole_method, :ole_method
-
   end
 
 end
diff --git a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
index 4f406a2ce8..0d54962977 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
@@ -1,27 +1,27 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#ole_methods" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#ole_methods" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "raises ArgumentError if argument is given" do
-      lambda { @ie.ole_methods(1) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if argument is given" do
+        lambda { @xml_dom.ole_methods(1) }.should raise_error ArgumentError
+      end
 
-    it "returns an array of WIN32OLE_METHODs" do
-      @ie.ole_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
-    end
+      it "returns an array of WIN32OLE_METHODs" do
+        @xml_dom.ole_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+      end
 
-    it "contains a 'AddRef' method for Internet Explorer" do
-      @ie.ole_methods.map { |m| m.name }.include?('AddRef').should be_true
+      it "contains a 'validateOnParse' method for Internet Explorer" do
+        @xml_dom.ole_methods.map { |m| m.name }.include?('validateOnParse').should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
index cd2be503f0..e967e837ac 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
@@ -1,23 +1,23 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#ole_obj_help" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#ole_obj_help" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "raises ArgumentError if argument is given" do
-      lambda { @ie.ole_obj_help(1) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if argument is given" do
+        lambda { @xml_dom.ole_obj_help(1) }.should raise_error ArgumentError
+      end
 
-    it "returns an instance of WIN32OLE_TYPE" do
-      @ie.ole_obj_help.kind_of?(WIN32OLE_TYPE).should be_true
+      it "returns an instance of WIN32OLE_TYPE" do
+        @xml_dom.ole_obj_help.kind_of?(WIN32OLE_TYPE).should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
index a58bbc8afe..9edc22d16c 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
@@ -1,27 +1,27 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe "WIN32OLE#ole_put_methods" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe "WIN32OLE#ole_put_methods" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "raises ArgumentError if argument is given" do
-      lambda { @ie.ole_put_methods(1) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if argument is given" do
+        lambda { @xml_dom.ole_put_methods(1) }.should raise_error ArgumentError
+      end
 
-    it "returns an array of WIN32OLE_METHODs" do
-      @ie.ole_put_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
-    end
+      it "returns an array of WIN32OLE_METHODs" do
+        @xml_dom.ole_put_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+      end
 
-    it "contains a 'Height' method for Internet Explorer" do
-      @ie.ole_put_methods.map { |m| m.name }.include?('Height').should be_true
+      it "contains a 'preserveWhiteSpace' method" do
+        @xml_dom.ole_put_methods.map { |m| m.name }.include?('preserveWhiteSpace').should be_true
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
index f6ece7af5a..d5c7d1d6ed 100644
--- a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
@@ -1,8 +1,5 @@
-require_relative '../fixtures/classes'
-require_relative 'shared/setproperty'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative 'shared/setproperty'
 
   describe "WIN32OLE#setproperty" do
     it_behaves_like :win32ole_setproperty, :setproperty
diff --git a/spec/ruby/library/win32ole/win32ole/shared/ole_method.rb b/spec/ruby/library/win32ole/win32ole/shared/ole_method.rb
index 9fdb5f2055..ec5354ae9d 100644
--- a/spec/ruby/library/win32ole/win32ole/shared/ole_method.rb
+++ b/spec/ruby/library/win32ole/win32ole/shared/ole_method.rb
@@ -1,38 +1,25 @@
-require_relative '../../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe :win32ole_ole_method, shared: true do
-    before :each do
-      # This part is unstable, so retrying 3 times.
-      tries = 0
-      begin
-        @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-      rescue WIN32OLERuntimeError => e
-        # WIN32OLERuntimeError: failed to create WIN32OLE object from `InternetExplorer.Application'
-        #     HRESULT error code:0x800704a6
-        #       A system shutdown has already been scheduled.
-        if tries < 3
-          tries += 1
-          $stderr.puts "win32ole_ole_method retry (#{tries}): #{e.class}: #{e.message}"
-          retry
-        end
+    describe :win32ole_ole_method, shared: true do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
       end
-    end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "raises ArgumentError if no argument is given" do
-      lambda { @ie.send(@method) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if no argument is given" do
+        lambda { @xml_dom.send(@method) }.should raise_error ArgumentError
+      end
 
-    it "returns the WIN32OLE_METHOD 'Quit' if given 'Quit'" do
-      result = @ie.send(@method, "Quit")
-      result.kind_of?(WIN32OLE_METHOD).should be_true
-      result.name.should == 'Quit'
+      it "returns the WIN32OLE_METHOD 'abort' if given 'abort'" do
+        result = @xml_dom.send(@method, "abort")
+        result.kind_of?(WIN32OLE_METHOD).should be_true
+        result.name.should == 'abort'
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole/shared/setproperty.rb b/spec/ruby/library/win32ole/win32ole/shared/setproperty.rb
index f272da4b4e..311415d89b 100644
--- a/spec/ruby/library/win32ole/win32ole/shared/setproperty.rb
+++ b/spec/ruby/library/win32ole/win32ole/shared/setproperty.rb
@@ -1,25 +1,24 @@
-require_relative '../../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-  describe :win32ole_setproperty, shared: true do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+    describe :win32ole_setproperty, shared: true do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-    after :each do
-      @ie.Quit
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    it "raises ArgumentError if no argument is given" do
-      lambda { @ie.send(@method) }.should raise_error ArgumentError
-    end
+      it "raises ArgumentError if no argument is given" do
+        lambda { @xml_dom.send(@method) }.should raise_error ArgumentError
+      end
 
-    it "sets height to 500 and returns nil" do
-      height = 500
-      result = @ie.send(@method, 'Height', height)
-      result.should == nil
+      it "sets async true and returns nil" do
+        result = @xml_dom.send(@method, 'async', true)
+        result.should == nil
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
index bceaa737e1..454748f828 100644
--- a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
@@ -1,33 +1,33 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
+  
+    describe "WIN32OLE_EVENT.new" do
+      before :all do
+        @xml_dom = WIN32OLESpecs.new_ole('MSXML.DOMDocument')
+      end
 
-  describe "WIN32OLE_EVENT.new" do
-    before :each do
-      @ie = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-    end
+      after :all do
+        @xml_dom = nil
+      end
 
-    after :each do
-      @ie.Quit if @ie
-    end
+      it "raises TypeError given invalid argument" do
+        lambda { WIN32OLE_EVENT.new "A" }.should raise_error TypeError
+      end
 
-    it "raises TypeError given invalid argument" do
-      lambda { WIN32OLE_EVENT.new "A" }.should raise_error TypeError
-    end
+      it "raises RuntimeError if event does not exist" do
+        lambda { WIN32OLE_EVENT.new(@xml_dom, 'A') }.should raise_error RuntimeError
+      end
 
-    it "raises RuntimeError if event does not exist" do
-      lambda { WIN32OLE_EVENT.new(@ie, 'A') }.should raise_error RuntimeError
-    end
-
-    it "raises RuntimeError if OLE object has no events" do
-      dict = WIN32OLESpecs.new_ole('Scripting.Dictionary')
-      lambda { WIN32OLE_EVENT.new(dict) }.should raise_error RuntimeError
-    end
+      it "raises RuntimeError if OLE object has no events" do
+        dict = WIN32OLESpecs.new_ole('Scripting.Dictionary')
+        lambda { WIN32OLE_EVENT.new(dict) }.should raise_error RuntimeError
+      end
 
-    it "creates WIN32OLE_EVENT object" do
-      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
-      ev.should be_kind_of WIN32OLE_EVENT
+      it "creates WIN32OLE_EVENT object" do
+        ev = WIN32OLE_EVENT.new(@xml_dom)
+        ev.should be_kind_of WIN32OLE_EVENT
+      end
     end
   end
 end
diff --git a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
index 00b8fcc035..da676dda4d 100644
--- a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
@@ -1,62 +1,71 @@
-require_relative '../fixtures/classes'
-
 platform_is :windows do
-  require 'win32ole'
-
-  def default_handler(event, *args)
-    @event += event
-  end
-
-  def alternate_handler(event, *args)
-    @event2 = "alternate"
-  end
-
-  def handler3(event, *args)
-    @event3 += event
-  end
+  require_relative '../fixtures/classes'
+  guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
 
-
-  describe "WIN32OLE_EVENT#on_event with no argument" do
-    before :each do
-      @ie     = WIN32OLESpecs.new_ole('InternetExplorer.Application')
-      @ev     = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
-      @event  = ''
-      @event2 = ''
-      @event3 = ''
-      @ie.StatusBar = true
+    def handler_global(event, *args)
+      @event_global += event
     end
 
-    after :each do
-      @ie.Quit
+    def handler_specific(*args)
+      @event_specific = "specific"
     end
 
-    it "sets event handler properly, and the handler is invoked by event loop" do
-      @ev.on_event { |*args| default_handler(*args) }
-      @ie.StatusText='hello'
-      WIN32OLE_EVENT.message_loop
-      @event.should =~ /StatusTextChange/
+    def handler_spec_alt(*args)
+      @event_spec_alt = "spec_alt"
     end
 
-    it "accepts a String argument, sets event handler properly, and the handler is invoked by event loop" do
-      @ev.on_event("StatusTextChange") { |*args| @event = 'foo' }
-      @ie.StatusText='hello'
-      WIN32OLE_EVENT.message_loop
-      @event.should =~ /foo/
-    end
+    describe "WIN32OLE_EVENT#on_event" do
+    
+      before :all do
+        @fn_xml = File.absolute_path "../fixtures/event.xml", __dir__
+      end
+    
+      before :each do
+        @xml_dom = WIN32OLESpecs.new_ole 'MSXML.DOMDocument'
+        @xml_dom.async = true
+        @ev = WIN32OLE_EVENT.new @xml_dom
+        @event_global   = ''
+        @event_specific = ''
+        @event_spec_alt = ''
+      end
 
-    it "registers multiple event handlers for the same event" do
-      @ev.on_event("StatusTextChange") { |*args| default_handler(*args) }
-      @ev.on_event("StatusTextChange") { |*args| alternate_handler(*args) }
-      @ie.StatusText= 'hello'
-      WIN32OLE_EVENT.message_loop
-      @event2.should == 'alternate'
-    end
+      after :each do
+        @xml_dom = nil
+        @ev = nil
+      end
+
+      it "sets global event handler properly, and the handler is invoked by event loop" do
+        @ev.on_event { |*args| handler_global(*args) }
+        @xml_dom.loadXML "Rubytrunk"
+        WIN32OLE_EVENT.message_loop
+        @event_global.should =~ /onreadystatechange/
+      end
+
+      it "accepts a String argument and the handler is invoked by event loop" do
+        @ev.on_event("onreadystatechange") { |*args| @event = 'foo' }
+        @xml_dom.loadXML "Rubytrunk"
+        WIN32OLE_EVENT.message_loop
+        @event.should =~ /foo/
+      end
+
+      it "accepts a Symbol argument and the handler is invoked by event loop" do
+        @ev.on_event(:onreadystatechange) { |*args| @event = 'bar' }
+        @xml_dom.loadXML "Rubytrunk"
+        WIN32OLE_EVENT.message_loop
+        @event.should =~ /bar/
+      end
 
-    it "accepts a Symbol argument, sets event handler properly, and the handler is invoked by event loop" do
-      @ev.on_event(:StatusTextChange) { |*args| @event = 'foo' }
-      @ie.StatusText='hello'
-      WIN32OLE_EVENT.message_loop
-      @event.should =~ /foo/
+      it "accepts a specific event handler and overrides a global event handler" do
+        @ev.on_event                       { |*args| handler_global(*args)   }
+        @ev.on_event("onreadystatechange") { |*args| handler_specific(*args) }
+        @ev.on_event("onreadystatechange") { |*args| handler_spec_alt(*args) }
+        @xml_dom.load @fn_xml
+        WIN32OLE_EVENT.message_loop
+        @event_global.should == 'ondataavailable'
+        @event_global.should_not =~ /onreadystatechange/
+        @event_specific.should == ''
+        @event_spec_alt.should == "spec_alt"
+      end
     end
   end
 end