       for key in keys
         @_defineAccessor key, wrapSingleAccessor(@_defineAccessor(key), wrapper)
 
-  _defineWrapAccessor: @_defineWrapAccessor
+
+# `Batman.Object` is the base class for all other Batman objects. It is not abstract.
+class BatmanObject extends Object
+  Batman.initializeObject(this)
+  Batman.initializeObject(@prototype)
+
+  # Make every subclass and their instances observable.
+  Batman.mixin @prototype, ObjectFunctions, Batman.EventEmitter, Batman.Observable
+  Batman.mixin @,          ObjectFunctions, Batman.EventEmitter, Batman.Observable
+
+  @classMixin: -> Batman.mixin @, arguments...
+  @mixin: -> @classMixin.apply @prototype, arguments
+  mixin: @classMixin
 
   @classAccessor: @_defineAccessor
   @accessor: -> @prototype._defineAccessor(arguments...)

#= require ./observable/observable
#= require ./hash/simple_hash

# `Batman.Object` is the base class for all other Batman objects. It is not abstract.
class BatmanObject extends Object
  Batman.initializeObject(this)
  Batman.initializeObject(@prototype)

  # Apply mixins to this class.
  @classMixin: -> Batman.mixin @, arguments...

  # Apply mixins to instances of this class.
  @mixin: -> @classMixin.apply @prototype, arguments
  mixin: @classMixin

  counter = 0
  _batmanID: ->
    @_batmanID = -> c
    c = counter++

  hashKey: ->
    return if typeof @isEqual is 'function'
    @hashKey = -> key
    key = "<Batman.Object #{@_batmanID()}>"

  toJSON: ->
    obj = {}
    for own key, value of @ when key not in ["_batman", "hashKey", "_batmanID"]
      obj[key] = if value?.toJSON then value.toJSON() else value
    obj

  getAccessorObject = (base, accessor) ->
    if typeof accessor is 'function'
      accessor = {get: accessor}
    for deprecated in ['cachable', 'cacheable']
      if deprecated of accessor
        Batman.developer.warn "Property accessor option \"#{deprecated}\" is deprecated. Use \"cache\" instead."
        accessor.cache = accessor[deprecated] unless 'cache' of accessor
    accessor

  promiseWrapper = (fetcher) ->
    (defaultAccessor) ->
      get: (key) ->
        return existingValue if (existingValue = defaultAccessor.get.apply(this, arguments))?
        asyncDeliver = false
        newValue = undefined
        @_batman["promise#{key}Fetched"] ?= do =>
          deliver = (err, result) =>
            @set(key, result) if asyncDeliver
            newValue = result
          returnValue = fetcher.call(this, deliver, key)
          newValue = returnValue unless newValue?
          true
        asyncDeliver = true
        newValue
      cache: true

  wrapSingleAccessor = (core, wrapper) ->
    wrapper = wrapper?(core) or wrapper
    for k, v of core
      wrapper[k] = v unless k of wrapper
    wrapper

  @_defineAccessor: (keys..., accessor) ->
    if not accessor?
      return Batman.Property.defaultAccessorForBase(this)
    else if keys.length is 0 and Batman.typeOf(accessor) not in ['Object', 'Function']

  @wrapAccessor: -> @prototype._defineWrapAccessor(arguments...)
  wrapAccessor: @_defineWrapAccessor

  @observeAll: -> @::observe.apply @prototype, arguments

  @singleton: (singletonMethodName="sharedInstance") ->
