Index: actionwebservice/test/scaffolded_controller_test.rb
===================================================================
--- actionwebservice/test/scaffolded_controller_test.rb	(revision 3693)
+++ actionwebservice/test/scaffolded_controller_test.rb	(working copy)
@@ -2,8 +2,11 @@
 
 ActionController::Routing::Routes.draw do |map|
   map.connect '', :controller => 'scaffolded'
+  map.connect ':controller/:action/:id'
 end
 
+ActionController::Base.template_root = '.'
+
 class ScaffoldPerson < ActionWebService::Struct
   member :id,   :int
   member :name, :string
Index: actionwebservice/test/client_soap_test.rb
===================================================================
--- actionwebservice/test/client_soap_test.rb	(revision 3693)
+++ actionwebservice/test/client_soap_test.rb	(working copy)
@@ -88,6 +88,16 @@
     assert_equal(true, @client.struct_pass([new_person]))
     assert_equal([[new_person]], @container.value_struct_pass)
   end
+  
+  def test_nil_struct_return
+    assert_nil @client.nil_struct_return
+  end
+  
+  def test_inner_nil
+    outer = @client.inner_nil
+    assert_equal 'outer', outer.name
+    assert_nil outer.inner
+  end
 
   def test_client_container
     assert_equal(50, ClientContainer.new.get_client.client_container)
Index: actionwebservice/test/abstract_client.rb
===================================================================
--- actionwebservice/test/abstract_client.rb	(revision 3693)
+++ actionwebservice/test/abstract_client.rb	(working copy)
@@ -12,12 +12,23 @@
       firstnames == other.firstnames && lastname == other.lastname
     end
   end
+  
+  class Inner < ActionWebService::Struct
+    member :name, :string
+  end
+  
+  class Outer < ActionWebService::Struct
+    member :name, :string
+    member :inner, Inner
+  end
 
   class API < ActionWebService::API::Base
     api_method :void
-    api_method :normal,         :expects => [:int, :int], :returns => [:int]
-    api_method :array_return,   :returns => [[Person]]
-    api_method :struct_pass,    :expects => [[Person]], :returns => [:bool]
+    api_method :normal,           :expects => [:int, :int], :returns => [:int]
+    api_method :array_return,     :returns => [[Person]]
+    api_method :struct_pass,      :expects => [[Person]], :returns => [:bool]
+    api_method :nil_struct_return,:returns => [Person] 
+    api_method :inner_nil,        :returns => [Outer]
     api_method :client_container, :returns => [:int]
     api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}]
     api_method :thrower
@@ -65,6 +76,14 @@
       @value_struct_pass = @method_params
       true
     end
+    
+    def nil_struct_return
+      nil
+    end
+    
+    def inner_nil
+      Outer.new :name => 'outer', :inner => nil
+    end
 
     def client_container
       50
Index: actionwebservice/test/client_xmlrpc_test.rb
===================================================================
--- actionwebservice/test/client_xmlrpc_test.rb	(revision 3693)
+++ actionwebservice/test/client_xmlrpc_test.rb	(working copy)
@@ -12,7 +12,7 @@
       test_request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
       test_request.env['RAW_POST_DATA'] = req.body
       response = ActionController::TestResponse.new
-      @controller.process(test_request, response)
+      @controller.process(test_request, response) 
       res.header['content-type'] = 'text/xml'
       res.body = response.body
       # puts res.body
@@ -83,14 +83,24 @@
     assert_equal(true, @client.struct_pass([new_person]))
     assert_equal([[new_person]], @container.value_struct_pass)
   end
+  
+  def test_nil_struct_return
+    assert_equal false, @client.nil_struct_return
+  end
 
+  def test_inner_nil
+    outer = @client.inner_nil
+    assert_equal 'outer', outer.name
+    assert_nil outer.inner
+  end
+
   def test_client_container
     assert_equal(50, ClientContainer.new.get_client.client_container)
   end
 
   def test_named_parameters
     assert(@container.value_named_parameters.nil?)
-    assert_equal(true, @client.named_parameters("xxx", 7))
+    assert_equal(false, @client.named_parameters("xxx", 7))
     assert_equal(["xxx", 7], @container.value_named_parameters)
   end
 
Index: actionwebservice/lib/action_web_service/scaffolding.rb
===================================================================
--- actionwebservice/lib/action_web_service/scaffolding.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/scaffolding.rb	(working copy)
@@ -71,8 +71,18 @@
                 post_params = params['method_params'] ? params['method_params'].dup : nil
                 params = []
                 if @scaffold_method.expects
-                  @scaffold_method.expects.length.times do |i|
-                    params << post_params[i.to_s]
+                  @scaffold_method.expects.each_with_index do |spec, i|
+                    case spec.type
+                    when :date
+                      date = post_params[i.to_s]
+                      params << (date['2'] + '/' + date['3'] + '/' + date['1'])
+                    when :datetime, :time
+                      date = post_params[i.to_s]
+                      params << (date['2'] + '/' + date['3'] + '/' + date['1'] + ' ' +
+                                 date['4'] + ':' + date['5'] + ':' + date['6'])
+                    else    
+                      params << post_params[i.to_s]                                            
+                    end
                   end
                 end
                 params = @scaffold_method.cast_expects(params)
@@ -130,14 +140,8 @@
             end
 
             def reset_invocation_response
-              template = response.template
-              if @invocation_cgi
-                @response = ::ActionController::CgiResponse.new(@invocation_cgi)
-              else
-                @response = ::ActionController::TestResponse.new
-              end
-              response.template = template
-              @performed_render = false
+              erase_render_results
+              @response.headers = ::ActionController::AbstractResponse::DEFAULT_HEADERS.merge("cookie" => [])
             end
 
             def public_method_name(service_name, method_name)
@@ -173,7 +177,7 @@
     end
 
     module Helpers # :nodoc:
-      def method_parameter_input_fields(method, type, field_name_base)
+      def method_parameter_input_fields(method, type, field_name_base, idx)
         if type.array?
           return content_tag('em', "Typed array input fields not supported yet (#{type.name})")
         end
@@ -184,7 +188,7 @@
             nested_content = method_parameter_input_fields(
               method,
               member_type,
-              field_name_base + '[' + member_name.to_s + ']')
+              "#{field_name_base}[#{idx}][#{member_name}]")
             if member_type.custom?
               parameters << content_tag('li', label)
               parameters << content_tag('ul', nested_content)
@@ -196,18 +200,30 @@
         else
           case type.type
           when :int
-            text_field_tag field_name_base
+            text_field_tag "#{field_name_base}[#{idx}]"
           when :string
-            text_field_tag field_name_base
+            text_field_tag "#{field_name_base}[#{idx}]"
+          when :base64
+            text_area_tag "#{field_name_base}[#{idx}]", nil, :size => "40x5"
           when :bool
-            radio_button_tag(field_name_base, "true") + " True" +
-            radio_button_tag(field_name_base, "false") + "False"
+            radio_button_tag("#{field_name_base}[#{idx}]", "true") + " True" +
+            radio_button_tag("#{field_name_base}[#{idx}]", "false") + "False"
           when :float
-            text_field_tag field_name_base
-          when :time
-            select_datetime Time.now, 'name' => field_name_base
+            text_field_tag "#{field_name_base}[#{idx}]"
+          when :time, :datetime
+            time = Time.now
+            i = 0
+            %w|year month day hour minute second|.map do |name|
+              i += 1
+              send("select_#{name}", time, :prefix => "#{field_name_base}[#{idx}][#{i}]", :discard_type => true)
+            end.join
           when :date
-            select_date Date.today, 'name' => field_name_base
+            date = Date.today
+            i = 0
+            %w|year month day|.map do |name|
+              i += 1
+              send("select_#{name}", date, :prefix => "#{field_name_base}[#{idx}][#{i}]", :discard_type => true)
+            end.join
           end
         end
       end
Index: actionwebservice/lib/action_web_service/casting.rb
===================================================================
--- actionwebservice/lib/action_web_service/casting.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/casting.rb	(working copy)
@@ -41,6 +41,11 @@
         def cast(value, signature_type) # :nodoc:
           return value if signature_type.nil? # signature.length != params.length
           return nil if value.nil?
+          # XMLRPC protocol doesn't support nil values. It uses false instead.
+          # It should never happen for SOAP.
+          if signature_type.structured? && value.equal?(false)
+            return nil
+          end
           unless signature_type.array? || signature_type.structured?
             return value if canonical_type(value.class) == signature_type.type
           end
Index: actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml
===================================================================
--- actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml	(revision 3693)
+++ actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml	(working copy)
@@ -10,15 +10,13 @@
 </p>
 
 <% if @scaffold_method.expects %>
-<% i = 0 %>
 
 <strong>Method Parameters:</strong><br />
-<% @scaffold_method.expects.each do |type| %>
+<% @scaffold_method.expects.each_with_index do |type, i| %>
   <p>
   <label for="method_params[<%= i %>]"><%= method_parameter_label(type.name, type) %> </label><br />
-  <%= method_parameter_input_fields(@scaffold_method, type, "method_params[#{i}]") %>
+  <%= method_parameter_input_fields(@scaffold_method, type, "method_params", i) %>
   </p>
-  <% i += 1 %>
 <% end %>
 
 <% end %>
Index: actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb
===================================================================
--- actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb	(working copy)
@@ -32,7 +32,9 @@
         end
 
         def ruby_to_soap(obj)
-          SOAP::Mapping.obj2soap(obj, @registry)
+          soap = SOAP::Mapping.obj2soap(obj, @registry)
+          soap.elename = XSD::QName.new if SOAP::Version >= "1.5.5" && soap.elename == XSD::QName::EMPTY
+          soap
         end
 
         def register_type(type)
@@ -68,7 +70,9 @@
         alias :lookup_type :register_type
 
         def annotate_arrays(binding, value)
-          if binding.type.array?
+          if value.nil?
+            return
+          elsif binding.type.array?
             mark_typed_array(value, binding.element_binding.qname)
             if binding.element_binding.type.custom?
               value.each do |element|
Index: actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb
===================================================================
--- actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb	(working copy)
@@ -50,10 +50,10 @@
         end
 
         def encode_response(method_name, return_value, return_type, protocol_options={})
-          return_value = true if return_value.nil?
-          if return_type
+          if return_value && return_type
             return_value = value_to_xmlrpc_wire_format(return_value, return_type)
           end
+          return_value = false if return_value.nil?
           raw_response = XMLRPC::Marshal.dump_response(return_value)
           Response.new(raw_response, 'text/xml', return_value)
         end
Index: actionwebservice/lib/action_web_service/api.rb
===================================================================
--- actionwebservice/lib/action_web_service/api.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/api.rb	(working copy)
@@ -14,6 +14,10 @@
     # See ActionWebService::Container::Direct::ClassMethods for an example
     # of use.
     class Base
+      # Action WebService API subclasses should be reloaded by the dispatcher in Rails
+      # when Dependencies.mechanism = :load.
+      include Reloadable::Subclasses
+      
       # Whether to transform the public API method names into camel-cased names 
       class_inheritable_option :inflect_names, true
 
Index: actionwebservice/lib/action_web_service/support/signature_types.rb
===================================================================
--- actionwebservice/lib/action_web_service/support/signature_types.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/support/signature_types.rb	(working copy)
@@ -53,9 +53,9 @@
       case name
         when :int, :integer, :fixnum, :bignum
           :int
-        when :string
+        when :string, :text
           :string
-        when :base64
+        when :base64, :binary
           :base64
         when :bool, :boolean
           :bool
@@ -203,7 +203,7 @@
       elsif @type_class.respond_to?(:columns)
         i = -1
         @type_class.columns.each do |column|
-          yield column.name, canonical_signature_entry(column.klass, i += 1)
+          yield column.name, canonical_signature_entry(column.type, i += 1)
         end
       end
     end
Index: actionwebservice/lib/action_web_service/base.rb
===================================================================
--- actionwebservice/lib/action_web_service/base.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/base.rb	(working copy)
@@ -25,12 +25,16 @@
   #     api_method :delete_person, :expects => [:int]
   #   end
   #
-  #   class SearchCriteria < ActionStruct::Base
+  #   class SearchCriteria < ActionWebService::Struct
   #     member :firstname, :string
   #     member :lastname,  :string
   #     member :email,     :string
   #   end
   class Base
+    # Action WebService subclasses should be reloaded by the dispatcher in Rails
+    # when Dependencies.mechanism = :load.
+    include Reloadable::Subclasses
+
     # Whether to report exceptions back to the caller in the protocol's exception
     # format
     class_inheritable_option :web_service_exception_reporting, true
Index: actionwebservice/lib/action_web_service/client/soap_client.rb
===================================================================
--- actionwebservice/lib/action_web_service/client/soap_client.rb	(revision 3693)
+++ actionwebservice/lib/action_web_service/client/soap_client.rb	(working copy)
@@ -80,7 +80,7 @@
             if expects
               expects.each do |type|
                 type_binding = @protocol.marshaler.lookup_type(type)
-                param_def << ['in', type.name, type_binding.mapping]
+                param_def << ['in', type.name.to_s, type_binding.mapping]
               end
             end
             if returns
