<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,7 +1,30 @@
 module Clipper
   module Accessors
+
+    class StringSerializer
+      def self.load(value)
+        value.to_s
+      end
+    end
+
+    class IntegerSerializer
+      def self.load(value)
+        Integer(value)
+      end
+    end
+
     class TypedAccessor
 
+      ##
+      # Defines mappings from native types to Clipper Serializers.
+      # 
+      # @api private
+      ##
+      @@native_serializers = {
+        String =&gt; Clipper::Accessors::StringSerializer,
+        Integer =&gt; Clipper::Accessors::IntegerSerializer
+      }.freeze
+
       attr_reader :target, :name, :type
 
       def initialize(target, name, type)
@@ -18,17 +41,12 @@ module Clipper
       end
 
       def typecast(value)
+        return value if value.is_a?(@type)
+
         case
-        when @type == String then typecast_to_string(value)
-        when @type == Integer then typecast_to_integer(value)
-        when Serializable &gt; @type then
-          case value
-          when @type then value
-          when nil then @type.load(Serializable::EmptyReader.new)
-          when Hash then @type.load(Serializable::HashReader.new(value))
-          else
-            raise SerializationError.new(&quot;Don't know how to load value #{value.inspect}&quot;)
-          end
+        when @type === value then value
+        when serializer = @@native_serializers[@type] then serializer.load(value)
+        when Serializable &gt; @type then @type.load(value)
         else
           raise SerializationError.new(&quot;Don't know how to serialize #{@type.inspect}&quot;)
         end
@@ -61,16 +79,10 @@ module Clipper
       alias == eql?
 
       private
-      class SerializationError &lt; StandardError
-      end
 
-      def typecast_to_string(value)
-        value.to_s
+      class SerializationError &lt; StandardError
       end
 
-      def typecast_to_integer(value)
-        Integer(value)
-      end
     end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/clipper/accessors/typed_accessor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,14 +1,11 @@
 module Clipper
 
-  @validation_context_map = {}
-
-  def self.constrain(target, context_name, &amp;block)
-    @validation_context_map[context_name] ||= {}
-    @validation_context_map[context_name][target] = Clipper::Validations::Context.new(target, context_name, &amp;block)
+  def self.validation_context_map
+    @validation_context_map ||= {}
   end
 
   def self.validate(instance, context_name = 'default')
-    if context_map = @validation_context_map[context_name]
+    if context_map = validation_context_map[context_name]
       if context = context_map[instance.class]
         return context.validate(instance)
       else
@@ -19,4 +16,19 @@ module Clipper
     end
   end
 
+  module Validations
+
+    def self.included(target)
+      target.extend(ClassMethods)
+    end
+
+    module ClassMethods
+      def constrain(context_name, &amp;block)
+        Clipper::validation_context_map[context_name] ||= {}
+        Clipper::validation_context_map[context_name][self] = Clipper::Validations::Context.new(self, context_name, &amp;block)
+      end
+
+    end
+
+  end # module Validations
 end # module Clipper
\ No newline at end of file</diff>
      <filename>lib/clipper/validations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,6 +5,7 @@ class Integration::ValidationsTest &lt; Test::Unit::TestCase
 
   def setup
     @user = Class.new do
+      include Clipper::Validations
       attr_accessor :id, :name, :email, :password, :password_confirmation, :age, :gender, :title
     end
 
@@ -12,7 +13,7 @@ class Integration::ValidationsTest &lt; Test::Unit::TestCase
 
   def test_constraint_declarations
     assert_nothing_raised do
-      Clipper::constrain(@user, &quot;test_constraint_declarations&quot;) do |check|
+      @user.constrain(&quot;test_constraint_declarations&quot;) do |check|
         check.size(&quot;name&quot;, 50) { |instance| instance.active? }
         check.required(&quot;name&quot;)
   
@@ -31,7 +32,7 @@ class Integration::ValidationsTest &lt; Test::Unit::TestCase
   end
 
   def test_default_validation_returns_invalid_result
-    Clipper::constrain(@user, 'default') do |check|
+    @user.constrain('default') do |check|
       check.required('name')
     end
 
@@ -42,7 +43,7 @@ class Integration::ValidationsTest &lt; Test::Unit::TestCase
   end
 
   def test_default_validation_returns_valid_result
-    Clipper::constrain(@user, 'default') do |check|
+    @user.constrain('default') do |check|
       check.required('name')
     end
   
@@ -54,11 +55,11 @@ class Integration::ValidationsTest &lt; Test::Unit::TestCase
   end
   
   def test_multiple_context_validation
-    Clipper::constrain(@user, 'default') do |check|
+    @user.constrain('default') do |check|
       check.required('name')
     end
   
-    Clipper::constrain(@user, 'email_marketing') do |check|
+    @user.constrain('email_marketing') do |check|
       check.required('name')
       check.required('email')
     end</diff>
      <filename>tests/integration/validations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,8 +10,12 @@ class SerializableTest &lt; Test::Unit::TestCase
 
     def self.load(reader)
       city = new
-      city.name = reader[:name].value
-      city.state_abbreviation = reader[:state_abbreviation].value
+
+      if reader
+        city.name = reader[:name]
+        city.state_abbreviation = reader[:state_abbreviation]
+      end
+
       city
     end
 </diff>
      <filename>tests/unit/accessors/serializable_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9b53372c608352c64ff1f88458afbefefca7f315</id>
    </parent>
    <parent>
      <id>182ff96100a46daafed202ad12d107e7413542de</id>
    </parent>
  </parents>
  <author>
    <name>Sam Smoot</name>
    <email>ssmoot@gmail.com</email>
  </author>
  <url>http://github.com/wiecklabs/clipper/commit/9c884236f2e974d5d2b592765f6f552f6fe41a5e</url>
  <id>9c884236f2e974d5d2b592765f6f552f6fe41a5e</id>
  <committed-date>2009-06-22T14:16:44-07:00</committed-date>
  <authored-date>2009-06-22T14:16:44-07:00</authored-date>
  <message>Merge branch 'master' of git@github.com:wiecklabs/clipper</message>
  <tree>fce6d5148a1ff92fec3ee33d0a7da23f344ba8c9</tree>
  <committer>
    <name>Sam Smoot</name>
    <email>ssmoot@gmail.com</email>
  </committer>
</commit>
