<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>readme.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,44 +1,12 @@
 h3. What's New?
 
-* 02/02/09 - mostly fixes and tweaks for CouchDB trunk (tested against revision 0.9.0a740000). This includes a couple of breaking API changes - count became limit, 409 rather than 412 is returned on document update conflict, and '/' in design docs is treated differently.
+RelaxDB 0.3 released - compatible with CouchDB 0.9. 
 
-* Potentially breaking change. Skipping validations is now done by adding attribute symbols to an object's list rather than passing them to @save@. For example @my_obj.validation_skip_list &lt;&lt; :foo@. This offers per object granularity over validations when working with bulk_save.
-
-* Potentially breaking change. @load@ now returns an array if passed an array of size one. Previously it would have returned a single object.
-
-* Update conflict hook and property
-
-* Semantic consistency for bulk_save and bulk_save! wrt to save and save!
-
-* Multiple exception handling improvements
-
-* @save_all@ that issues a bulk_save for an object and its has_one and has_many children
-
-* assignment of @has_many@ relationships
-
-* Validations may be skipped by passing the attribute symbol(s) to @save@ or @save!@.
-
-* Denormalisation via derived properties. Examples in spec/derived_properties_spec.rb.
-
-* Semantic changes for @ has_many#&lt;&lt; @. The parent object is now assigned to the child object *prior* to validation. This potentially breaking change was made to allow child objects to derive properties from a parent object.
-
-* Semantic consistency for load, load!, save and save!. The bang versions raise an exception when their more relaxed siblings would simply return nil.
-
-* Minimal support for CouchDB validation 
-
-* Time storage changes. All Time objects are now converted to UTC and formatted as @ %Y/%m/%d %H:%M:%S +0000 @. Storing all Times as UTC should have been happening anyway. Formatting Times as above (as opposed to ISO 8601 as was done prior to 0.2.3) allows the Time strings to be passed directly to Date.new in a JavaScript interpreter. 
-
-* Pagination! CouchDB offers great support for retrieving a subset of data, but the housekeeping is tricky. RelaxDB takes care of it.
-** Note that if you invoke paginate_by on an already created view, the necessary reduce function won't be automatically created. Take a look at SortedByView and create the reduce func by hand.
-* Support for multi key post
-** For example, @ Numbers.by_val :keys =&gt; [1,2,3,5]@
-* Works with CouchDB 0.9 trunk as of 2009/01/02. Note that pagination won't work correctly on trunk until issue &quot;COUCHDB-135&quot;:http://issues.apache.org/jira/browse/COUCHDB-135 is fixed.
-
-*Note*: Current versions require CouchDB 0.9 trunk. If you're working with CouchDB 0.8 or 0.8.1, please build from commit @ a8a2d496462 @.
+Version 0.3 includes many breaking changes. Most notable are simplified view syntax changes and the requirement that a design doc be specified up front.
 
 h2. Overview
 
-RelaxDB provides a Ruby interface to CouchDB. It offers a simple idiom for specifying object relationships. The underlying objects are persisted to the mighty CouchDB. Combined with the schema free nature of CouchDB, RelaxDB's current strength lies in quick prototyping of object models.
+RelaxDB provides a Ruby interface to CouchDB. It offers a simple idiom for specifying object relationships. The underlying objects are persisted to CouchDB and are retreived using CouchDB idioms.
 
 A few facilities are provided including pretty printing of GET requests and uploading of JavaScript views.
 
@@ -46,14 +14,21 @@ A basic merb plugin, &quot;merb_relaxdb&quot;:http://github.com/paulcarey/merb_relaxdb/tre
 
 For more complete documentation take a look at docs/spec_results.html and the corresponding specs.
 
-h2. Details 
+*Note*: While RelaxDB 0.3 is explicitly compatible with CouchDB 0.9, HEAD typically tracks CouchDB HEAD.
+
+h2. Details
 
 h3. Getting started
 
 &lt;pre&gt;
 &lt;code&gt;
-  RelaxDB.configure :host =&gt; &quot;localhost&quot;, :port =&gt; 5984
-  RelaxDB.use_db &quot;scratch&quot;
+  require 'rubygems'
+  require 'relaxdb'
+
+  RelaxDB.configure :host =&gt; &quot;localhost&quot;, :port =&gt; 5984, :design_doc =&gt; &quot;app&quot;
+  RelaxDB.use_db &quot;relaxdb_scratch&quot;
+  
+  RelaxDB.enable_view_creation # creates views when class definition is executed
 &lt;/code&gt;
 &lt;/pre&gt;
 
@@ -61,27 +36,37 @@ h3. Defining models
 
 &lt;pre&gt;
 &lt;code&gt;
-  class Writer &lt; RelaxDB::Document
-    property :name, :default =&gt; &quot;anon&quot;
-    
-    has_many :posts, :class =&gt; &quot;Post&quot;
-    has_many :ratings, :class =&gt; &quot;Post&quot;, :known_as =&gt; :critic
-  end
 
-  class Post &lt; RelaxDB::Document
-    property :created_at
-    property :contents
+class User &lt; RelaxDB::Document
+  property :name
+end
+
+class Invite &lt; RelaxDB::Document
+  
+  property :created_at
+  
+  property :event_name
+  
+  property :state, :default =&gt; &quot;awaiting_response&quot;,
+    :validator =&gt; lambda { |s| %w(accepted rejected awaiting_response).include? s }
+  
+  references :sender, :validator =&gt; :required
+  
+  references :recipient, :validator =&gt; :required
+  
+  property :sender_name,
+   :derived =&gt; [:sender, lambda { |p, o| o.sender.name } ]
+  
+  view_by :sender_name
+  view_by :sender_id
+  view_by :recipient_id, :created_at, :descending =&gt; true
   
-    belongs_to :writer  
-    has_many :ratings, :class =&gt; &quot;Rating&quot;
+  def on_update_conflict
+    puts &quot;conflict!&quot;
   end
+  
+end
 
-  class Rating &lt; RelaxDB::Document
-    property :thumbs_up, :validator =&gt; lambda { |tu| tu &gt;= 0 &amp;&amp; tu &lt; 3 }, :validation_msg =&gt; &quot;No no&quot;
-
-    belongs_to :post
-    belongs_to :critic
-  end
 &lt;/code&gt;
 &lt;/pre&gt;
 
@@ -89,16 +74,46 @@ h3. Exploring models
 
 &lt;pre&gt;
 &lt;code&gt;
-  paul = Writer.new(:name =&gt; &quot;paul&quot;).save
+# Saving objects
+
+sofa = User.new(:name =&gt; &quot;sofa&quot;).save!
+futon = User.new(:name =&gt; &quot;futon&quot;).save!
+
+i = Invite.new :sender =&gt; sofa, :recipient =&gt; futon, :event_name =&gt; &quot;CouchCamp&quot;
+i.save!
+
+# Loading and querying
+
+il = RelaxDB.load i._id
+puts i == il # true
+
+ir = Invite.by_sender_name &quot;sofa&quot;
+puts i == ir # true
+
+ix = Invite.by_sender_name(:key =&gt; &quot;sofa&quot;).first
+puts i == ix # true
+
+# Denormalization
+
+puts ix.sender_name # prints sofa, no requests to CouchDB made
+puts ix.sender.name # prints sofa, a single CouchDB request made
+
+# Saving with conflicts
+
+idup = i.dup
+i.save!
+idup.save # conflict printed
 
-  post = Post.new(:contents =&gt; &quot;foo&quot;)
-  paul.posts &lt;&lt; post                                          # post writer is set and post is saved
-  post.created_at                                             # right now
-  paul.ratings &lt;&lt; Rating.new(:thumbs_up =&gt; 3, :post =&gt; post)  # returns false as rating fails validation
-  paul.ratings.size                                           # 0
+# Saving with and without validations
+
+i = Invite.new :sender =&gt; sofa, :name =&gt; &quot;daily show&quot;
+i.save! rescue :ok # save! throws an exception on validation failure or conflict
+i.save # returns false rather than throwing an exception
+puts i.errors.inspect # {:recipient=&gt;&quot;invalid:&quot;}
+
+i.validation_skip_list &lt;&lt; :recipient # Any and all validations may be skipped
+i.save #&#160;succeeds
 
-  # Simple views are auto created
-  Rating.by_thumbs_up :key =&gt; 2, :limit =&gt; 1 # query params map directly to CouchDB
 &lt;/code&gt;
 &lt;/pre&gt;
 
@@ -106,72 +121,57 @@ h3. Paginating models
 
 &lt;pre&gt;
 &lt;code&gt;
-  # Controller (merb-action-args used for extracting view_params)
+  # Controller
 
-  def action(page_params={})
-    u_id = @user._id
-
-    @posts = Post.paginate_by(page_params, :writer_id, :created_at) do |p|
-      p.startkey([u_id, {}]).endkey([u_id]).descending(true).limit(5)
-    end
+  def show(page_params={})
+    uid = @user._id
+    @invites = Invite.paginate_by_sender_name :startkey =&gt; [uid, {}], 
+        :endkey =&gt; [uid], :descending =&gt; true, :limit =&gt; 5, :page_params =&gt; page_params
     render
   end
   
   # In your view
   
-  &lt;% @posts.each do |p| %&gt;
-    &lt;%= p.contents %&gt;
+  &lt;% @invites.each do |i| %&gt;
+    &lt;%= i.event_name %&gt;
   &lt;% end %&gt;
   
-  &lt;%= link_to &quot;prev&quot;, &quot;/posts/?#{@posts.prev_query}&quot; if @posts.prev_query %&gt;
-  &lt;%= link_to &quot;next&quot;, &quot;/posts/?#{@posts.next_query}&quot; if @posts.next_query %&gt;  
+  &lt;%= link_to &quot;prev&quot;, &quot;/invites/?#{@invites.prev_query}&quot; if @invites.prev_query %&gt;
+  &lt;%= link_to &quot;next&quot;, &quot;/invites/?#{@invites.next_query}&quot; if @invites.next_query %&gt;  
 &lt;/code&gt;
 &lt;/pre&gt;
 
-h3. Paginating over your own views
-
-&lt;pre&gt;
-&lt;code&gt;
-
-RelaxDB.paginate_view(page_params, &quot;Letter&quot;, &quot;by_letter_and_number&quot;, :letter, :number) do |p|
-  p.startkey([&quot;b&quot;]).endkey([&quot;b&quot;, {}]).limit(2)
-end
-
-&lt;/code&gt;
-&lt;/pre&gt;
-
-A more illustrative example is listed in the .paginate_view spec in spec/paginate_spec.rb
+More illustrative examples are listed in the .paginate_view spec in spec/paginate_spec.rb
 
 h3. Creating views by hand
 
 &lt;pre&gt;
 &lt;code&gt;
   $ cat view.js 
-  function Writer-allnames-map(doc) {
-    if(doc.class == &quot;Writer&quot;)
-      emit(null, doc.name);
+  function Invites_by_state-map(doc) {
+    if(doc.relaxdb_class === &quot;Invite&quot;)
+      emit(doc.state, doc);
   }
 
-  function Writer-allnames-reduce(keys, values) {
-    var allnames = &quot;&quot;;
-    for(var i = 0; i &lt; values.length; i++)
-      allnames += values[i];
-    return allnames;
+  function Invites_by_state-reduce(keys, values, rereduce) {
+    if (rereduce) {
+      return sum(values);
+    } else {
+      return values.length;
+    }
   }
   $
 
   RelaxDB::ViewUploader.upload(&quot;view.js&quot;)
-  RelaxDB.view(&quot;Writer&quot;, &quot;allnames&quot;)                          # paul
+  RelaxDB.view &quot;Invites_by_state&quot;, :key =&gt; &quot;accepted&quot;, :reduce =&gt; true
 &lt;/code&gt;
 &lt;/pre&gt;
 
 h3. Visualise
 
-The GraphCreator has been superceded by &quot;fuschia&quot;:http://github.com/paulcarey/fuschia/tree/master.
+&quot;Fuschia&quot;:http://github.com/paulcarey/fuschia/tree/master offers a web front end for visualising inter-document relationships.
 
 h2. Incomplete list of limitations
 
 * Destroying an object results in non transactional nullification of child/peer references
-* Objects can talk to only one database at a time
-* No caching is used. Although adding an LRU cache would be fairly straightforward, this hasn't been done as it's not yet clear what caching strategies will be most effective. 
-
+* Objects can talk to only one database at a time. Similarly for design docs.</diff>
      <filename>README.textile</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ require 'spec/rake/spectask'
 
 PLUGIN = &quot;relaxdb&quot;
 NAME = &quot;relaxdb&quot;
-GEM_VERSION = &quot;0.2.8&quot;
+GEM_VERSION = &quot;0.3.0&quot;
 AUTHOR = &quot;Paul Carey&quot;
 EMAIL = &quot;paul.p.carey@gmail.com&quot;
 HOMEPAGE = &quot;http://github.com/paulcarey/relaxdb/&quot;
@@ -28,7 +28,7 @@ spec = Gem::Specification.new do |s|
   
   s.require_path = 'lib'
   s.autorequire = PLUGIN
-  s.files = %w(LICENSE README.textile Rakefile) + Dir.glob(&quot;{docs,lib,spec}/**/*&quot;)
+  s.files = %w(LICENSE README.textile readme.rb Rakefile) + Dir.glob(&quot;{docs,lib,spec}/**/*&quot;)
 end
 
 Rake::GemPackageTask.new(spec) do |pkg|</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -184,420 +184,875 @@ a {
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
   &lt;dt id=&quot;example_group_2&quot;&gt;RelaxDB::BelongsToProxy belongs_to&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('1.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('0.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return nil when accessed before assignment&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('2.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('0.9');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be establishable via constructor attribute&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('3.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('1.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be establishable via constructor id&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('4.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('1.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should establish the parent relationship when supplied a parent and saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('5.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('2.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should establish the parent relationship when supplied a parent id and saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('6.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('2.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the same object on repeated invocations&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('7.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('3.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be nullified when the parent is destroyed&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('8.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('3.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be preserved across save / load boundary&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('9.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('4.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be able to reference itself via its parent&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('4.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be used reciprocally&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_3&quot;&gt;RelaxDB::BelongsToProxy belongs_to validator&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('5.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be passed the _id and object&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('5.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be used with a predefined validator&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('6.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be provided with a default error message when validation fails&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_4&quot;&gt;RelaxDB::Document callbacks&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_5&quot;&gt;RelaxDB::Document callbacks before_save&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('6.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be run before the object is saved&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('6.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent the object from being saved if it returns false&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('7.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should add a description to errors when false is returned&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('7.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not prevent the object from being saved if it returns nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('8.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a proc&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('8.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a method&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_6&quot;&gt;RelaxDB::Document callbacks after_save&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('9.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be run after the object is saved&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_3&quot;&gt;RelaxDB::DesignDocument&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_7&quot;&gt;RelaxDB::Document derived properties&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('9.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should have its value updated when the source is updated&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('10.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should have its value persisted&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('10.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should have its value updated when the source_id is updated for a saved event&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('11.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not raise an exception when the source is nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('11.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should only be updated for registered properties&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('12.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should have the existing value passed to the first lambda param&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('12.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should contintue to be derived post load&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_4&quot;&gt;RelaxDB::DesignDocument#save&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('10.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_8&quot;&gt;RelaxDB::Document derived properties multiple properties&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('12.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be derivable from the same source&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_9&quot;&gt;RelaxDB::DesignDocument&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_10&quot;&gt;RelaxDB::DesignDocument#save&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('13.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create a corresponding document in CouchDB&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_5&quot;&gt;RelaxDB::DesignDocument#destroy&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('11.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_11&quot;&gt;RelaxDB::DesignDocument#destroy&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('13.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should delete the corresponding document from CouchDB&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_6&quot;&gt;RelaxDB::Document&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_12&quot;&gt;Inheritance&lt;/dt&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_7&quot;&gt;RelaxDB::Document.new&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('12.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_13&quot;&gt;Inheritance properties&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('14.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should by inherited from a parent document&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('14.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should store its own properties&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('15.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;validators should behave as normal&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_14&quot;&gt;Inheritance _all views&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('15.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be rewritten&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('16.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should function with inheritance trees&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_15&quot;&gt;Inheritance _by views&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('16.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be rewritten for ancestors and generated for descendants&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_16&quot;&gt;Inheritance derived properties&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('17.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be stored&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_17&quot;&gt;Inheritance references&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('17.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should function as normal&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_18&quot;&gt;RelaxDB::Document&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_19&quot;&gt;RelaxDB::Document.new&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('18.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create an object with an id&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('13.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('18.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create an object with a nil revision&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('14.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should convert attributes that end in _at to dates&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('15.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('18.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should convert attributes that end in _at to Times&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('19.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will silently ignore parameters that don't specify class attributes&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('19.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create a document with a non conflicing state&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_8&quot;&gt;RelaxDB::Document#to_json&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('16.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_20&quot;&gt;RelaxDB::Document#initialize&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('20.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be overridden by inheriting classes&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_21&quot;&gt;RelaxDB::Document#to_json&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('20.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not output nil attributes&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('21.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should convert times to '%Y/%m/%d %H:%M:%S +0000' format&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_9&quot;&gt;RelaxDB::Document#save&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('17.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_22&quot;&gt;RelaxDB::Document#save&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('21.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set an object's revision&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('18.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('22.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should result in an object considered saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('19.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('22.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be invokable multiple times&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('20.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('23.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set created_at when first saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('21.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('23.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set created_at when first saved unless supplied to the constructor&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('24.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set document conflict state on conflicting save&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_10&quot;&gt;RelaxDB::Document loaded objects&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('22.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_23&quot;&gt;RelaxDB::Document#save!&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('24.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should save objects&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('25.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should raise ValidationFailure on validation failure&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('25.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should raise UpdateConflict on an update conflict&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_24&quot;&gt;RelaxDB::Document user defined property reader&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('25.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not effect normal operation&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('26.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not modify internal state&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_25&quot;&gt;RelaxDB::Document user defined property writer&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('26.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not be used&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_26&quot;&gt;RelaxDB::Document loaded objects&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('27.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should contain state as when saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('23.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('27.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be saveable&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_11&quot;&gt;RelaxDB::Document#destroy&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('24.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_27&quot;&gt;RelaxDB::Document#destroy&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('28.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should delete the corresponding document from CouchDB&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('25.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent the object from being resaved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('26.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;makeRed('rspec-header');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;makeRed('example_group_27');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('28.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec failed&quot;&gt;
+      &lt;span class=&quot;failed_spec_name&quot;&gt;should prevent the object from being resaved&lt;/span&gt;
+      &lt;div class=&quot;failure&quot; id=&quot;failure_1&quot;&gt;
+        &lt;div class=&quot;message&quot;&gt;&lt;pre&gt;expected Exception but nothing was raised&lt;/pre&gt;&lt;/div&gt;
+        &lt;div class=&quot;backtrace&quot;&gt;&lt;pre&gt;./spec/document_spec.rb:189:&lt;/pre&gt;&lt;/div&gt;
+    &lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;linenum&quot;&gt;187&lt;/span&gt;      &lt;span class=&quot;ident&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Atom&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;destroy!&lt;/span&gt;
+&lt;span class=&quot;linenum&quot;&gt;188&lt;/span&gt;    &lt;span class=&quot;comment&quot;&gt;# Exepcted failure - see http://issues.apache.org/jira/browse/COUCHDB-292      &lt;/span&gt;
+&lt;span class=&quot;offending&quot;&gt;&lt;span class=&quot;linenum&quot;&gt;189&lt;/span&gt;      &lt;span class=&quot;ident&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;save!&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;raise_error&lt;/span&gt;&lt;/span&gt;
+&lt;span class=&quot;linenum&quot;&gt;190&lt;/span&gt;    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
+&lt;span class=&quot;linenum&quot;&gt;191&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;
+      &lt;/div&gt;
+    &lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('29.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will result in undefined behaviour when invoked on unsaved objects&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_12&quot;&gt;RelaxDB::Document#all.destroy!&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('27.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_28&quot;&gt;RelaxDB::Document#all.destroy!&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('29.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should delete from CouchDB all documents of the corresponding class&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_13&quot;&gt;RelaxDB::Document ==&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('28.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_29&quot;&gt;RelaxDB::Document ==&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('30.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should define equality based on CouchDB id&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('29.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('30.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return false when passed a nil object&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_14&quot;&gt;RelaxDB::Document#all&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('30.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return all instances of that class&lt;/span&gt;&lt;/dd&gt;
+  &lt;dt id=&quot;example_group_30&quot;&gt;RelaxDB::Document.all&lt;/dt&gt;
     &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('31.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return all instances of that class&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('31.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an empty array when no instances exist&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_15&quot;&gt;RelaxDB::Document#all.sorted_by&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('32.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_31&quot;&gt;RelaxDB::Document.all.size&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('31.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the total number of docs in a single query&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('32.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return 0 when no docs exist&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_32&quot;&gt;RelaxDB::Document by_&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('32.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should sort ascending by default&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('33.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('33.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should sort desc when specified&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('34.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('33.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should sort date attributes lexicographically&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('34.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the count when queried with reduce=true&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_16&quot;&gt;RelaxDB::Document#all.sorted_by results&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('35.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_33&quot;&gt;RelaxDB::Document by_ results&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('34.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be an empty array when no docs match&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('35.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be retrievable by exact criteria&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('36.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('35.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be retrievable by relative criteria&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('37.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('36.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be retrievable by combined criteria&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('38.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('36.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be retrievable by combined criteria where not all docs contain all attributes&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('37.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be retrievable by a multi key post&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_17&quot;&gt;RelaxDB::Document defaults&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('39.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_34&quot;&gt;RelaxDB::Document defaults&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('37.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be set on initialisation&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('40.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('37.9');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be saved&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('41.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('38.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be ignored once overwritten&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('42.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('38.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a simple value&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('43.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('39.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a proc&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_18&quot;&gt;RelaxDB::Document validator&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('44.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_35&quot;&gt;RelaxDB::Document validator&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('39.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent an object from being saved if it evaluates to false&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('45.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('40.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent an object from being saved if it throws an exception&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('46.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('40.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should pass the property value to the validator&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('47.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should add the validation error message if supplied, on failure&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('48.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('41.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should pass the property value and object to the validator&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('41.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should perform all validations&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('42.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent saving unless all validations pass&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('42.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should add a default error message if none is specified&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('43.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a proc&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('43.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a method&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('43.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be skipped by passing the property symbol to save&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_19&quot;&gt;RelaxDB::HasManyProxy&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_36&quot;&gt;RelaxDB::Document validation message&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('44.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be set on failure&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('44.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a proc accepting the prop only&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('45.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may be a proc accepting the prop and object&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_20&quot;&gt;RelaxDB::HasManyProxy has_many&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('49.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_37&quot;&gt;RelaxDB::Document predefined validator&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('45.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be invoked when a symbol clash exists&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('46.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should prevent an object from being saved if validation fails&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_38&quot;&gt;RelaxDB::HasManyProxy&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_39&quot;&gt;RelaxDB::HasManyProxy has_many&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('46.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be considered enumerable&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('50.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('47.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should actually be enumerable&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('51.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('47.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should preserve the collection across the load / save boundary&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('48.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should work with MultiWordClassNames&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_21&quot;&gt;RelaxDB::HasManyProxy has_many#&amp;lt;&amp;lt;&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('52.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_40&quot;&gt;RelaxDB::HasManyProxy has_many#&amp;lt;&amp;lt;&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('48.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should link the added item to the parent&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('53.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('49.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return self&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('54.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('49.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not created duplicates when invoked with same object more than once&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('55.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('50.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return false when the child fails validation&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_22&quot;&gt;RelaxDB::HasManyProxy has_many#=&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('56.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should fail&lt;/span&gt;&lt;/dd&gt;
+  &lt;dt id=&quot;example_group_41&quot;&gt;RelaxDB::HasManyProxy has_many#=&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('50.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not attempt to save the child objects when the relationship is established&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('50.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should preserve given relationships across save/load boundary&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('51.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should invoke the derived properties writer&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_23&quot;&gt;RelaxDB::HasManyProxy has_many#delete&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('57.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_42&quot;&gt;RelaxDB::HasManyProxy has_many#delete&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('51.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify the belongs_to relationship&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_24&quot;&gt;RelaxDB::HasManyProxy has_many#clear&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('58.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_43&quot;&gt;RelaxDB::HasManyProxy has_many#clear&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('52.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should result in an empty collection&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('59.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('52.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify all child relationships&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_25&quot;&gt;RelaxDB::HasManyProxy has_many owner&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('60.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_44&quot;&gt;RelaxDB::HasManyProxy has_many owner&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('53.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be able to form multiple relationships with the same class of child&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_26&quot;&gt;RelaxDB::HasManyProxy has_many owner#destroy&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('61.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_45&quot;&gt;RelaxDB::HasManyProxy has_many owner#destroy&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('53.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify its child relationships&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_27&quot;&gt;RelaxDB::HasOneProxy&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_46&quot;&gt;RelaxDB::HasOneProxy&lt;/dt&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_28&quot;&gt;RelaxDB::HasOneProxy has_one&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('62.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_47&quot;&gt;RelaxDB::HasOneProxy has_one&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('54.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return nil when accessed before assignment&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('63.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('54.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be establishable via a constructor attribute&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('64.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('55.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be establishable via assignment&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('65.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('55.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the same object on repeated invocations&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('66.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('56.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be preserved across load / save boundary&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('67.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('56.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be able reference itself via its child&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('56.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should work with MultiWordClassNames&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_29&quot;&gt;RelaxDB::HasOneProxy has_one#=&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('68.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_48&quot;&gt;RelaxDB::HasOneProxy has_one#=&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('57.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create a reference from the child to the parent&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('69.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('57.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should save the assigned object&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('70.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('58.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not save the parent&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('71.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('58.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set the target to nil when nil is assigned&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('72.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('59.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify any existing relationship in the database&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('73.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('59.7');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify any existing relationship on a known in-memory object&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('74.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('60.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not nullify any existing relationship on unknown in-memory objects&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('75.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('60.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not throw an error when the rhs fails validation&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_30&quot;&gt;RelaxDB::Query&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_49&quot;&gt;RelaxDB::PaginateParams&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('61.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be invalid if hasn't been initialized with both a startkey and endkey&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('61.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be valid if initialized with both a startkey and endkey&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_50&quot;&gt;RelaxDB Pagination&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_51&quot;&gt;RelaxDB Pagination functional tests&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('62.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should navigate through a series&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('62.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should navigate through b series with descending false&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('62.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should navigate through b series with descending true&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('63.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not display pagination options for c series&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_52&quot;&gt;RelaxDB Pagination next_query&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('63.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should emit a url encoded and json encoded string with query name page_params&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('64.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be treated as next_param by the paginator&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_31&quot;&gt;RelaxDB::Query#view_name&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('76.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_53&quot;&gt;RelaxDB Pagination prev_query&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('64.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be treated as prev_query by the paginator&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('65.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should emit a url encoded and json encoded string with query name page_params&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_54&quot;&gt;RelaxDB Pagination multiple keys per document, simple (non array) keys&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('65.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should work when descending is false&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('66.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should work when descending is true&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('66.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not get stuck when the number of keys exceeds the limit&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_55&quot;&gt;RelaxDB Pagination.paginate_by&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('67.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should throw an error unless both startkey and endkey are specified&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('67.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an empty array when no documents exist&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('68.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an array that responds negatively to next_query and prev_query when no documents exist&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_56&quot;&gt;RelaxDB Pagination.paginate_view functional tests&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('68.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should pass&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_57&quot;&gt;RelaxDB::Query&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_58&quot;&gt;RelaxDB::Query#view_name&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('68.9');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should match a single key attribute&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('77.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('69.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should match key attributes&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_32&quot;&gt;RelaxDB::Query#view_path&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('78.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should list design document and view name&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('79.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_59&quot;&gt;RelaxDB::Query#view_path&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('69.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should list design document and view name and default reduce to false&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('70.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should contain URL and JSON encoded key when the key has been set&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('80.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should honour startkey, endkey and count&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('81.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should specify the key as the empty string if key was set to nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('70.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should honour startkey, endkey and limit&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('71.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should specify a null key if key was set to nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('71.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should specify a null startkey if startkey was set to nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('72.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should specify a null endkey if endkey was set to nil&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('72.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not JSON encode the startkey_docid&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('73.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not JSON encode the endkey_docid&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_33&quot;&gt;RelaxDB::ReferencesManyProxy&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_60&quot;&gt;RelaxDB::Query#keys&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('73.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return a JSON encoded hash&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_34&quot;&gt;RelaxDB::ReferencesManyProxy references_many&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('82.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;is now deprecated and will be removed in the near future&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('83.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_61&quot;&gt;RelaxDB::ReferencesManyProxy&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_62&quot;&gt;RelaxDB::ReferencesManyProxy references_many&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('74.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should preserve the relationships across the save / load boundary&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('74.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should issue only a single request to resolve the relationship&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('75.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not resolve the relationship when an object is instantiated&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('75.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should make the ids available as a property&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_35&quot;&gt;RelaxDB::ReferencesManyProxy references_many#=&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('84.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_63&quot;&gt;RelaxDB::ReferencesManyProxy references_many#=&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('75.9');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not be invoked&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_36&quot;&gt;RelaxDB::ReferencesManyProxy references_many#&amp;lt;&amp;lt;&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('85.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_64&quot;&gt;RelaxDB::ReferencesManyProxy references_many#&amp;lt;&amp;lt;&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('76.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should set the relationship on both sides&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('86.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('76.8');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not create duplicates when the same object is added more than once&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('87.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('77.3');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not create duplicates when reciprocal objects are added from opposite sides&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('77.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will resolve the reciprocal relationship&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_37&quot;&gt;RelaxDB::ReferencesManyProxy references_many#delete&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('88.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_65&quot;&gt;RelaxDB::ReferencesManyProxy references_many#delete&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('78.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should nullify relationship on both sides&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_38&quot;&gt;RelaxDB::ReferencesManyProxy references_many owner#destroy&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('89.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not remove its membership from its peers in memory&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('90.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_66&quot;&gt;RelaxDB::ReferencesManyProxy references_many owner#destroy&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('78.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should remove its membership from its peers in memory&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('79.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should remove its membership from its peers in CouchDB&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_39&quot;&gt;RelaxDB&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('91.0');&lt;/script&gt;
-    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should offer an example where behaviour is different with caching enabled and caching disabled&lt;/span&gt;&lt;/dd&gt;
+  &lt;dt id=&quot;example_group_67&quot;&gt;RelaxDB&lt;/dt&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_40&quot;&gt;RelaxDB.create_object&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('92.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_68&quot;&gt;RelaxDB.create_object&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('79.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an instance of a known object if passed a hash with a class key&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('93.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('80.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an instance of a dynamically created object if no class key is provided&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_41&quot;&gt;RelaxDB.bulk_save&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('94.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_69&quot;&gt;RelaxDB.bulk_save&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('80.5');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be invokable multiple times&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('95.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('81.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the objects it was passed&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('81.4');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should succeed when passed no args&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('81.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return false on failure&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('82.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not attempt to save if a pre-save stage fails&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('82.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should invoke the after-save stage after a successful save&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_70&quot;&gt;RelaxDB.bulk_save!&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('83.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should raise an exception if a obj fails validation&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('83.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;will not raise an exception if a document update conflict occurs on save&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_71&quot;&gt;RelaxDB.replicate_db&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('84.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should replicate the named database&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_42&quot;&gt;RelaxDB::ViewObject&lt;/dt&gt;
+  &lt;dt id=&quot;example_group_72&quot;&gt;RelaxDB.load&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('84.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should load a single document&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('85.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should load an arbitrary number of documents&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('85.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return nil when given a id for a non existant doc&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('86.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an array with correctly placed nils when given a list containing non existant doc ids&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_43&quot;&gt;RelaxDB::ViewObject.new&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('96.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_73&quot;&gt;RelaxDB.load!&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('86.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should load a single document&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('87.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should load multiple documents&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('87.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should throw an exception if given a single id for a non-existant doc&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('87.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should throw an exception if any of a list of doc ids is for a non-existant doc&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_74&quot;&gt;RelaxDB.view&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('88.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should request a view and return an array&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('88.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;may accept query params&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('89.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should be queryable with a multi key post&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('89.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return nil for a reduce view with no results&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('90.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return a single value for a reduce view with a single result&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('90.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an array for a reduce view with multiple results&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_75&quot;&gt;RelaxDB.merge&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('91.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should merge rows sharing a common merge key into a single ViewObject&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_76&quot;&gt;RelaxDB create_views disabled&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('91.6');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should not create any views&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_77&quot;&gt;RelaxDB create_views enabled&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('92.1');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create all views&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_78&quot;&gt;RelaxDB&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_79&quot;&gt;RelaxDB GET&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('92.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should raise a HTTP_404 for a non existant doc&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('93.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should raise a RuntimeError for non specific errors&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_80&quot;&gt;view_by&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_81&quot;&gt;view_by view_by&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('93.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create corresponding views&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('93.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create a by_ att list method&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('94.4');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should create a paginate_by_ att list method&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('94.9');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should apply query defaults to by_&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('95.3');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should allow a single arg to be passed to by_&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('95.8');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should apply query defaults to paginate_by_&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('96.2');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should allow query defaults to be overridden for paginate_by_&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('96.7');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should allow query defaults to be overridden for by_&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_82&quot;&gt;RelaxDB::ViewObject&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_83&quot;&gt;RelaxDB::ViewObject.new&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('97.2');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should provide readers for the object passed in the hash&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('97.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('97.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should try to convert objects ending in _at to a time&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
 &lt;div class=&quot;example_group&quot;&gt;
   &lt;dl&gt;
-  &lt;dt id=&quot;example_group_44&quot;&gt;RelaxDB::ViewObject.create&lt;/dt&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('98.0');&lt;/script&gt;
+  &lt;dt id=&quot;example_group_84&quot;&gt;RelaxDB::ViewObject.create&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('98.1');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return an array of view objects when passed an array&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('99.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('98.6');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return a view object when passed a hash&lt;/span&gt;&lt;/dd&gt;
-    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('100.0');&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('99.0');&lt;/script&gt;
     &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return a simple value when passed a primitive&lt;/span&gt;&lt;/dd&gt;
   &lt;/dl&gt;
 &lt;/div&gt;
-&lt;script type=&quot;text/javascript&quot;&gt;document.getElementById('duration').innerHTML = &quot;Finished in &lt;strong&gt;11.855995 seconds&lt;/strong&gt;&quot;;&lt;/script&gt;
-&lt;script type=&quot;text/javascript&quot;&gt;document.getElementById('totals').innerHTML = &quot;100 examples, 0 failures&quot;;&lt;/script&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_85&quot;&gt;RelaxDB::View&lt;/dt&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;div class=&quot;example_group&quot;&gt;
+  &lt;dl&gt;
+  &lt;dt id=&quot;example_group_86&quot;&gt;RelaxDB::View exists&lt;/dt&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('99.5');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return nil if a view doesnt exist&lt;/span&gt;&lt;/dd&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;moveProgressBar('100.0');&lt;/script&gt;
+    &lt;dd class=&quot;spec passed&quot;&gt;&lt;span class=&quot;passed_spec_name&quot;&gt;should return the view if it exits&lt;/span&gt;&lt;/dd&gt;
+  &lt;/dl&gt;
+&lt;/div&gt;
+&lt;script type=&quot;text/javascript&quot;&gt;document.getElementById('duration').innerHTML = &quot;Finished in &lt;strong&gt;32.605052 seconds&lt;/strong&gt;&quot;;&lt;/script&gt;
+&lt;script type=&quot;text/javascript&quot;&gt;document.getElementById('totals').innerHTML = &quot;216 examples, 1 failure&quot;;&lt;/script&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/body&gt;</diff>
      <filename>docs/spec_results.html</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@ module RelaxDB
     attr_accessor :validation_skip_list
     
     class_inheritable_accessor :properties, :reader =&gt; true
-    self.properties = [:_id, :_rev]
+    self.properties = []
 
     class_inheritable_accessor :derived_prop_writers
     self.derived_prop_writers = {}
@@ -58,7 +58,7 @@ module RelaxDB
         add_derived_prop(prop, opts[:derived])
       end
     end    
-    
+  
     property :_id 
     property :_rev        
     </diff>
      <filename>lib/relaxdb/document.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 Gem::Specification.new do |s|
   s.name = &quot;relaxdb&quot;
-  s.version = &quot;0.2.8&quot;
-  s.date = &quot;2009-02-02&quot;
+  s.version = &quot;0.3.0&quot;
+  s.date = &quot;2009-03-31&quot;
   s.summary = &quot;RelaxDB provides a simple interface to CouchDB&quot;
   s.email = &quot;paul.p.carey@gmail.com&quot;
   s.homepage = &quot;http://github.com/paulcarey/relaxdb/&quot;
@@ -9,6 +9,7 @@ Gem::Specification.new do |s|
   s.authors = [&quot;Paul Carey&quot;]
   s.files = [&quot;LICENSE&quot;,
    &quot;README.textile&quot;,
+   &quot;readme.rb&quot;,
    &quot;Rakefile&quot;,
    &quot;docs/spec_results.html&quot;,
    &quot;lib/relaxdb&quot;,</diff>
      <filename>relaxdb.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -185,6 +185,7 @@ describe RelaxDB::Document do
 
     it &quot;should prevent the object from being resaved&quot; do
       p = Atom.new.save.destroy!
+    # Exepcted failure - see http://issues.apache.org/jira/browse/COUCHDB-292      
       lambda { p.save! }.should raise_error
     end
     </diff>
      <filename>spec/document_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -81,9 +81,9 @@ describe RelaxDB do
       lambda { RelaxDB.bulk_save!(c.new) }.should raise_error(RelaxDB::ValidationFailure)
     end
     
-    it &quot;should raise an exception if a document update conflict occurs on save&quot; do
+    it &quot;will not raise an exception if a document update conflict occurs on save&quot; do
       Atom.new(:_id =&gt; &quot;a1&quot;).save!
-      lambda { RelaxDB.bulk_save! Atom.new(:_id =&gt; &quot;a1&quot;) }.should raise_error(RelaxDB::UpdateConflict)
+      RelaxDB.bulk_save! Atom.new(:_id =&gt; &quot;a1&quot;)
     end
     
   end</diff>
      <filename>spec/relaxdb_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>readmev3.rb</filename>
    </removed>
    <removed>
      <filename>scratch/readme.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>67a8acdf5da23b2411aa02a09def89c13d092c86</id>
    </parent>
  </parents>
  <author>
    <name>Paul Carey</name>
    <email>paul.p.carey@gmail.com</email>
  </author>
  <url>http://github.com/paulcarey/relaxdb/commit/341557906b73aea1e2015296b13fe8d0b156a348</url>
  <id>341557906b73aea1e2015296b13fe8d0b156a348</id>
  <committed-date>2009-03-31T10:28:02-07:00</committed-date>
  <authored-date>2009-03-31T10:28:02-07:00</authored-date>
  <message>Updates for 0.3 - readme, spec_results. Deleted now redundant files.</message>
  <tree>d50006b087d18455aaa962c6ffbeccd4d9cf8df3</tree>
  <committer>
    <name>Paul Carey</name>
    <email>paul.p.carey@gmail.com</email>
  </committer>
</commit>
