Index: ruby/trunk/lib/models/rm/common/generic.rb
===================================================================
--- ruby/trunk/lib/models/rm/common/generic.rb	(revision 156)
+++ ruby/trunk/lib/models/rm/common/generic.rb	(revision 157)
@@ -46,9 +46,45 @@
 
         class Revision_History
-          
+          attr_reader :items
+
+          def initialize(items)
+            self.items = items
+          end
+
+          def items=(items)
+            if items.nil? or items.empty?
+              raise ArgumentError, 'item(s) is/are mandatory'
+            end
+            @items  = items
+          end
+
+          def most_recent_version
+            return @items.last.version_id.value
+          end
+
+          def most_recent_version_time_committed
+            return @items.last.audits.first.time_committed.value
+          end
         end # of Revision_History
 
         class Revision_History_Item
-          
+          attr_reader :version_id, :audits
+
+          def initialize(args = { })
+            self.version_id = args[:version_id]
+            self.audits = args[:audits]
+          end
+
+          def audits=(audits)
+            if audits.nil? or audits.empty?
+              raise ArgumentError, 'audits is mandatory'
+            end
+            @audits = audits
+          end
+
+          def version_id=(version_id)
+            raise ArgumentError, 'version_id is mandatory' if version_id.nil?
+            @version_id = version_id
+          end
         end # of Revision_History_Item
 
@@ -137,4 +173,21 @@
           end
         end
+
+        class Attestation < Audit_Details
+          attr_reader :reason
+          attr_accessor :proof, :items
+
+          def initialize(args = { })
+            super(args)
+            self.reason = args[:reason]
+            self.proof = args[:proof]
+            self.items = args[:items]
+          end
+
+          def reason=(reason)
+            raise ArgumentError, 'reason is mandatory' if reason.nil?
+            @reason = reason
+          end
+        end
       end # of Generic
     end # of Common
Index: ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb
===================================================================
--- ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb	(revision 156)
+++ ruby/trunk/lib/models/rm/data_types/quantity/date_time.rb	(revision 157)
@@ -11,4 +11,5 @@
         module Date_Time
           class DV_Temporal < OpenEHR::RM::Data_Types::Quantity::DV_Absolute_Quantity
+            include Comparable
             attr_reader :value
 
@@ -29,4 +30,8 @@
               end
               @value = value
+            end
+
+            def <=>(other)
+              self.magnitude <=> other.magnitude
             end
           end
@@ -151,6 +156,11 @@
 
             def magnitude
-              return DateTime.new(@year,@month,@day,@hour,@minute,@second) - 
-                DateTime.new(0000,1,1,0,0,0) + @fractional_second
+              seconds = DateTime.new(@year,@month,@day,@hour,@minute,@second) - 
+                DateTime.new(0000,1,1,0,0,0)
+              if @fractional_second.nil?
+                return seconds
+              else
+                return seconds + @fractional_second
+              end
             end
 
Index: ruby/trunk/lib/models/rm/support/identification.rb
===================================================================
--- ruby/trunk/lib/models/rm/support/identification.rb	(revision 156)
+++ ruby/trunk/lib/models/rm/support/identification.rb	(revision 157)
@@ -174,4 +174,42 @@
         end
 
+        class Object_Version_ID < UID_Based_ID
+          attr_reader :object_id, :creating_system_id, :version_tree_id
+
+          def initialize(value)
+            super(value)
+          end
+
+          def value=(value)
+            super(value)
+            if /^(\w+)::(\w+)::((\d|\.)+)$/ =~ value
+              self.object_id = UID.new($1)
+              self.creating_system_id = UID.new($2)
+              self.version_tree_id = Version_Tree_ID.new($3)
+            else
+              raise ArgumentError, 'invalid format'
+            end
+          end
+
+          def object_id=(object_id)
+            raise ArgumentError, 'object_id is mandatory' if object_id.nil?
+            @object_id = object_id
+          end
+
+          def creating_system_id=(creating_system_id)
+            if creating_system_id.nil?
+              raise ArgumentError, 'creating_system_id is mandatory'
+            end
+            @creating_system_id = creating_system_id
+          end
+
+          def version_tree_id=(version_tree_id)
+            if version_tree_id.nil?
+              raise ArgumentError, 'version_tree_id is mandatory'
+            end
+            @version_tree_id = version_tree_id
+          end
+        end
+
         class Locatable_Ref < Object_Ref
           attr_reader :namespace, :type, :id, :path
@@ -284,5 +322,5 @@
         class ISO_OID <UID
 
-        end
+        end        
       end # of Identification
     end # of Support
Index: ruby/trunk/lib/models/tests/rm/test_common.rb
===================================================================
--- ruby/trunk/lib/models/tests/rm/test_common.rb	(revision 156)
+++ ruby/trunk/lib/models/tests/rm/test_common.rb	(revision 157)
@@ -10,4 +10,5 @@
 include OpenEHR::RM::Data_Types::Basic
 include OpenEHR::RM::Data_Types::Quantity
+include OpenEHR::RM::Data_Types::URI
 
 class RM_Common_Resource_Test < Test::Unit::TestCase
@@ -45,5 +46,5 @@
     provider = Party_Identified.new(:name => 'NERV')
     location = Party_Identified.new(:name => 'GEOFRONT')
-    object_id = Object_ID.new('0.0.4')
+    object_version_id = Object_Version_ID.new('ABC::DEF::1.3.4')
     party_ref = Party_Ref.new('local', 'ORGANISATION', object_id)
     assert_nothing_raised(Exception){
@@ -180,7 +181,38 @@
                                          :change_type => dv_coded_text,
                                          :description => dv_text)}
-#    change_type = OpenEHR::RM::Data_Types::Text::DV_Text.new('audit_type')
-#    time_committed = OpenEHR::RM::Data_Types::Quantity::Date_Time::DV_Date_Time.new(2008)
-#    assert_nothing_raised(Exception){@audit_details = OpenEHR::RM::Common::Generic::Audit_Details.new('rails',@party_proxy, change_type, time_committed)}
+    dv_text = DV_Text.new('authorisation')
+    dv_ehr_uri = DV_EHR_URI.new('ehr://test/')
+    assert_nothing_raised(Exception){
+      @attestation = Attestation.new(:system_id => 'NERV',
+                                     :committer => @party_proxy,
+                                     :time_committed => dv_date_time,
+                                     :change_type => dv_coded_text,
+                                     :reason => dv_text,
+                                     :description => dv_text,
+                                     :proof => 'hashedstring',
+                                     :items => Set[dv_ehr_uri])}
+    object_version_id = Object_Version_ID.new('SHOGOUKI::NERV::1.1.1')
+    audit_details2 = Audit_Details.new(:system_id => 'MAGI',
+                                       :committer => @party_proxy,
+                                       :time_committed => dv_date_time2,
+                                       :change_type => dv_coded_text)
+    assert_nothing_raised(Exception){
+      @revision_history_item = Revision_History_Item.new(:audits => [@audit_details, audit_details2],
+                                                         :version_id => object_version_id)}
+    dv_date_time3 = DV_Date_Time.new('2009-07-14T12:00:00')
+    dv_date_time4 = DV_Date_Time.new('2009-07-15T00:00:00')
+    audit_details3 = Audit_Details.new(:system_id => 'MAGI',
+                                     :committer => @party_proxy,
+                                     :time_committed => dv_date_time3,
+                                     :change_type => dv_coded_text)
+    audit_details4 = Audit_Details.new(:system_id => 'MAGI',
+                                     :committer => @party_proxy,
+                                     :time_committed => dv_date_time4,
+                                     :change_type => dv_coded_text)
+    object_version_id = Object_Version_ID.new('NIGOUKI::NERV::2.2.2')
+    revision_history_item2 = Revision_History_Item.new(:audits => [audit_details3, audit_details4],
+                                                      :version_id => object_version_id)
+    assert_nothing_raised(Exception){
+      @revision_history = Revision_History.new([@revision_history_item, revision_history_item2])}
   end
 
@@ -191,4 +223,7 @@
     assert_instance_of Participation, @participation
     assert_instance_of Audit_Details, @audit_details
+    assert_instance_of Attestation, @attestation
+    assert_instance_of Revision_History_Item, @revision_history_item
+    assert_instance_of Revision_History, @revision_history
   end
 
@@ -230,4 +265,25 @@
     assert_equal 'test environment', @audit_details.description.value
   end
+
+  def test_attestation
+    assert_equal 'NERV', @attestation.system_id
+    assert_equal 'unknown', @attestation.committer.external_ref.namespace
+    assert_equal '249', @attestation.change_type.defining_code.code_string
+    assert_equal 7, @attestation.time_committed.month
+    assert_equal 'authorisation', @attestation.reason.value
+    assert_equal 'authorisation', @attestation.description.value
+    assert_equal 'hashedstring', @attestation.proof
+    assert_equal 'ehr://test/', @attestation.items.to_a[0].value
+  end
+
+  def test_revision_history_item
+    assert_equal 'SHOGOUKI::NERV::1.1.1', @revision_history_item.version_id.value
+    assert_equal 'MAGI', @revision_history_item.audits[0].system_id
+  end
+
+  def test_revision_history
+    assert_equal 'NIGOUKI::NERV::2.2.2', @revision_history.most_recent_version
+    assert_equal '2009-07-14T12:00:00', @revision_history.most_recent_version_time_committed
+  end
 end
 
Index: ruby/trunk/lib/models/tests/rm/test_support.rb
===================================================================
--- ruby/trunk/lib/models/tests/rm/test_support.rb	(revision 156)
+++ ruby/trunk/lib/models/tests/rm/test_support.rb	(revision 157)
@@ -24,4 +24,5 @@
     assert_nothing_raised(Exception){@access_group_ref = OpenEHR::RM::Support::Identification::Access_Group_Ref.new('unknown', 'ACCESS_GROUP', @object_id)}
     assert_nothing_raised(Exception){@version_tree_id = OpenEHR::RM::Support::Identification::Version_Tree_ID.new('1.2.3')}
+    assert_nothing_raised(Exception){@object_version_id = OpenEHR::RM::Support::Identification::Object_Version_ID.new('ABC::DEF::1.2.3')}
   end
   
@@ -39,4 +40,5 @@
     assert_instance_of OpenEHR::RM::Support::Identification::Access_Group_Ref, @access_group_ref
     assert_instance_of OpenEHR::RM::Support::Identification::Version_Tree_ID, @version_tree_id
+    assert_instance_of OpenEHR::RM::Support::Identification::Object_Version_ID, @object_version_id
   end
 
@@ -218,4 +220,11 @@
   end
 
+  def test_object_version_id
+    assert_equal 'ABC::DEF::1.2.3', @object_version_id.value
+    assert_equal 'ABC', @object_version_id.object_id.value
+    assert_equal 'DEF', @object_version_id.creating_system_id.value
+    assert_equal '1', @object_version_id.version_tree_id.trunk_version
+  end
+
   def test_locatable_ref
 # test constructor
