     c.newrng = newrng
     c.raw_options = options
     c.equals = (other) ->
-      name = undefined
-      zipCDom = undefined
-      zipNDom = undefined
-      pCDom = undefined
-      pNDom = undefined
-      pOpt = undefined
+      # can can short circuit here if we're not testing against another contract
       return false  if not other instanceof Contract or other.ctype isnt @ctype
+
       zipCDom = Utils.zip(@calldom, other.calldom)
       zipNDom = Utils.zip(@newdom, other.newdom)
-      pCDom = (zipCDom.length isnt 0) and zipCDom.every((zd) ->
-        zd[0].equals zd[1]
-      )
-      pNDom = (zipNDom.length isnt 0) and zipNDom.every((zd) ->
-        zd[0].equals zd[1]
-      )
+
+      pCDom = (zipCDom.length isnt 0) and zipCDom.every (zd) -> zd[0].equals zd[1]
+      pNDom = (zipNDom.length isnt 0) and zipNDom.every (zd) -> zd[0].equals zd[1]
+
+      # this will "fail" equality testing if the options object has
+      # pre/post functions that are the "same" but not the same reference
       pOpt = checkOptions(@raw_options, other.raw_options)
+
       pOpt and pCDom and pNDom and (@callrng.equals(other.callrng)) and (@newrng.equals(other.newrng))
-
     c
+
   ctor = (dom, rng, options) ->
-    opt = Utils.merge(options,
+    opt = Utils.merge options,
       newOnly: true
-    )
+
     fun dom, rng, opt
+
   ctorSafe = (dom, rng, options) ->
-    opt = Utils.merge(options,
+    opt = Utils.merge options,
       newSafe: true
-    )
+
     fun dom, rng, opt
-  object = (objContract, options, name) ->
-    setSelfContracts = (c, toset) ->
-      i = undefined
-      name = undefined
-      childrenNames = [ "k", "k1", "k2", "flats", "ho", "calldom", "callrng", "newdom", "newrng" ]
-      if typeof c.oc isnt "undefined"
-        for name of c.oc
-          if c.oc[name] is self
-            c.oc[name] = toset
-          else setSelfContracts c.oc[name], toset  if c.oc[name].ctype isnt "object"
-      else
-        childrenNames.forEach (cName) ->
-          if typeof c[cName] isnt "undefined"
-            if Array.isArray(c[cName])
-              i = 0
-              while i < c[cName].length
-                if c[cName][i] is self
-                  c[cName][i] = toset
-                else setSelfContracts c[cName][i], toset  if c[cName][i].ctype isnt "object"
-                i++
-            else
-              if c[cName] is self
-                c[cName] = toset
-              else setSelfContracts c[cName], toset  if c[cName] isnt "object"
-    options = options or {}
+
+
+  object = (objContract, options = {}, name) ->
     objName = (obj) ->
-      if name is `undefined`
-        props = Object.keys(obj).map((propName) ->
+      if name is undefined
+        props = Object.keys(obj).map (propName) ->
           if obj[propName].cname
             propName + " : " + obj[propName].cname
           else
             propName + " : " + obj[propName].value.cname
-        , this)
+        , this
+
         "{" + props.join(", ") + "}"
       else
         name
 
     c = new Contract(objName(objContract), "object", (obj, pos, neg, parentKs) ->
-      missingProps = undefined
-      op = undefined
-      i = undefined
-      prop = undefined
-      contractDesc = undefined
-      objDesc = undefined
-      value = undefined
-      handler = idHandler(obj)
+      handler = idHandler obj
       that = this
       parents = parentKs.slice(0)
-      invariant = undefined
       parents.push this
-      blame pos, neg, this, obj, parentKs  unless obj instanceof Object
-      blame pos, neg, "[extensible object]", "[non-extensible object]", parents  if options.extensible is true and not Object.isExtensible(obj)
-      blame pos, neg, "[non-extensible]", "[extensible object]", parents  if options.extensible is false and Object.isExtensible(obj)
-      blame pos, neg, "[sealed object]", "[non-sealed object]", parents  if options.sealed is true and not Object.isSealed(obj)
-      blame pos, neg, "[non-sealed object]", "[sealed object]", parents  if options.sealed is false and Object.isSealed(obj)
-      blame pos, neg, "[frozen object]", "[non-frozen object]", parents  if options.frozen is true and not Object.isFrozen(obj)
-      blame pos, neg, "[non-frozen object]", "[frozen object]", parents  if options.frozen is false and Object.isFrozen(obj)
+
+      if not obj instanceof Object
+        blame pos, neg, this, obj, parentKs 
+
+      if options.extensible is true and not Object.isExtensible(obj)
+        blame pos, neg, "[extensible object]", "[non-extensible object]", parents  
+
+      if options.extensible is false and Object.isExtensible(obj)
+        blame pos, neg, "[non-extensible]", "[extensible object]", parents  
+
+      if options.sealed is true and not Object.isSealed(obj)
+        blame pos, neg, "[sealed object]", "[non-sealed object]", parents  
+
+      if options.sealed is false and Object.isSealed(obj)
+        blame pos, neg, "[non-sealed object]", "[sealed object]", parents  
+
+      if options.frozen is true and not Object.isFrozen(obj)
+        blame pos, neg, "[frozen object]", "[non-frozen object]", parents  
+
+      if options.frozen is false and Object.isFrozen(obj)
+        blame pos, neg, "[non-frozen object]", "[frozen object]", parents  
+
+      # do some cleaning of the object contract...
+      # in particular wrap all object contract in a prop descriptor like object
+      # for symmetry with user defined contract property
+      # descriptors: object({ a: Num }) ==> object({ a: {value: Num} })
       for prop of @oc
+        # todo: commenting out for now to allow us to have an object contract prototype chain
+        # only reason not too allow this is if the user puts something silly on the chain. 
+        # if(!this.oc.hasOwnProperty(prop)) {
+        #     continue; 
+        # }
         contractDesc = @oc[prop]
         objDesc = Utils.getPropertyDescriptor(obj, prop)
+
+        # pull out the contract (might be direct or in a descriptor like {value: Str, writable: true})
         if contractDesc instanceof Contract
           value = contractDesc
         else
+          # case when defined as a contract property descriptor
           if contractDesc["value"]
             value = contractDesc["value"]
+          # something other than a descriptor
           else
             blameM pos, neg, "contract property descriptor missing value property", parents
+
         if objDesc
-          blame pos, neg, "[writable property: " + prop + "]", "[read-only property: " + prop + "]", parents  if contractDesc.writable is true and not objDesc.writable
-          blame pos, neg, "[read-only property: " + prop + "]", "[writable property: " + prop + "]", parents  if contractDesc.writable is false and objDesc.writable
-          blame pos, neg, "[configurable property: " + prop + "]", "[non-configurable property: " + prop + "]", parents  if contractDesc.configurable is true and not objDesc.configurable
-          blame pos, neg, "[non-configurable property: " + prop + "]", "[configurable property: " + prop + "]", parents  if contractDesc.configurable is false and objDesc.configurable
-          blame pos, neg, "[enumerable property: " + prop + "]", "[non-enumerable property: " + prop + "]", parents  if contractDesc.enumerable is true and not objDesc.enumerable
-          blame pos, neg, "[non-enumerable property: " + prop + "]", "[enumerable property: " + prop + "]", parents  if contractDesc.enumerable is false and objDesc.enumerable
+          # check the contract descriptors agains what is actually on the object
+          # and blame where apropriate
+          if contractDesc.writable is true and not objDesc.writable
+            blame pos, neg, "[writable property: #{prop}]", "[read-only property: #{prop}]", parents
+
+          if contractDesc.writable is false and objDesc.writable
+            blame pos, neg, "[read-only property: #{prop}]", "[writable property: #{prop}]", parents  
+
+          if contractDesc.configurable is true and not objDesc.configurable
+            blame pos, neg, "[configurable property: #{prop}]", "[non-configurable property: #{prop}]", parents  
+
+          if contractDesc.configurable is false and objDesc.configurable
+            blame pos, neg, "[non-configurable property: #{prop}]", "[configurable property: #{prop}]", parents  
+
+          if contractDesc.enumerable is true and not objDesc.enumerable
+            blame pos, neg, "[enumerable property: #{prop}]", "[non-enumerable property: #{prop}]", parents  
+
+          if contractDesc.enumerable is false and objDesc.enumerable
+            blame pos, neg, "[non-enumerable property: #{prop}]", "[enumerable property: #{prop}]", parents  
+
+          # contract descriptors default to the descriptor on the value unless
+          # explicitly specified by the contrac 
           @oc[prop] =
             value: value
             writable: contractDesc.writable or objDesc.writable
             configurable: contractDesc.configurable or objDesc.configurable
             enumerable: contractDesc.enumerable or objDesc.enumerable
         else
+          # property does not exist but we have a contract for it
           if value.ctype is "opt"
+            # the opt contract allows a property to be optional
+            # so just put in the contract with all the prop descriptors set to true
             @oc[prop] =
               value: value
               writable: true
               configurable: true
               enumerable: true
           else
-            blame pos, neg, this, "[missing property: " + prop + "]", parents
+            blame pos, neg, this, "[missing property: #{prop}]", parents
+
+      # check object invariant
       if options.invariant
         invariant = options.invariant.bind(obj)
-        blame neg, pos, "invariant: " + options.invariant.toString(), obj, parents  unless invariant()
+        blame neg, pos, "invariant: #{options.invariant.toString()}", obj, parents  unless invariant()
+
       handler.defineProperty = (name, desc) ->
-        blame neg, pos, "[non-extensible object]", "[attempted to change property descriptor of: " + name + "]", parents  if (options.extensible is false) or options.sealed or options.frozen
-        blame neg, pos, "[non-configurable property: " + name + "]", "[attempted to change the property descriptor of property: " + name + "]", parents  unless that.oc[name].configurable
+        # note: we coulad have also allowed a TypeError to be thrown by the system
+        # if in strict mode or silengtly fail otherwise but we're using the blame system
+        # for hopfully better error messaging
+        if (options.extensible is false) or options.sealed or options.frozen
+          # have to reverse blame since the client is the one calling defineProperty
+          blame neg, pos, "[non-extensible object]", 
+            "[attempted to change property descriptor of: #{name}]", parents  
+
+        if not that.oc[name].configurable
+          blame neg, pos, "[non-configurable property: #{name}]", 
+            "[attempted to change the property descriptor of property: #{name}]", parents  
+
         Object.defineProperty obj, name, desc
 
       handler["delete"] = (name) ->
         res = undefined
         invariant = undefined
-        blame neg, pos, (if options.sealed then "sealed" else "frozen") + " object", "[call to delete]", parents  if options.sealed or options.frozen
+        # have to reverse blame since the client is the one calling delete
+        if options.sealed or options.frozen
+          blame neg, pos, "#{if options.sealed then 'sealed' else 'frozen'} object", 
+            "[call to delete]", parents  
+
         res = delete obj[name]
 
         if options.invariant
           invariant = options.invariant.bind(obj)
-          blame neg, pos, "invariant: " + options.invariant.toString(), obj, parents  unless invariant()
+          blame neg, pos, "invariant: #{options.invariant.toString()}", obj, parents  unless invariant()
 
       handler["get"] = (receiver, name) ->
         if that.oc.hasOwnProperty(name)

    defineProperty: (name, desc) ->
      Object.defineProperty obj, name, desc

    delete: (name) ->
      delete obj[name]

    fix: ->

          obj[name]

      handler.set = (receiver, name, val) ->
        if (options.extensible is false) and Object.getOwnPropertyDescriptor(obj, name) is undefined
          blame neg, pos, "non-extensible object", "[attempted to set a new property: #{name}]", parents  

        if options.frozen
          blame neg, pos, "frozen object", "[attempted to set: #{name}]", parents  

        if that.oc.hasOwnProperty(name)
          if not that.oc[name].writable
            blame neg, pos, "read-only property", "[attempted to set read-only property: #{name}]", parents  
          # have to reverse blame since the client is the one calling set
          obj[name] = that.oc[name]["value"].check(val, neg, pos, parents)
        else if (options.arrayRangeContract and (options.arrayRange isnt undefined)) and (parseInt(name, 10) >= options.arrayRange)
          obj[name] = options.arrayRangeContract.check(val, neg, pos, parents)
        else
          obj[name] = val
        if options.invariant
          invariant = options.invariant.bind(obj)
          blame neg, pos, "invariant: #{options.invariant.toString()}", obj, parents  unless invariant()
        true

      # making this a function proxy if object is also a
      # function to preserve typeof checks
      if typeof obj is "function"
        op = Proxy.createFunction(handler, (args) ->
          obj.apply this, arguments
        , (args) ->
          boundArgs = [].concat.apply([ null ], arguments)
          bf = obj.bind.apply(obj, boundArgs)
          new bf()
