Binding = (object, type, state)->
	extendState(@, state)
	@optionsDefault = if @saveOptions then @options else defaultOptions
	@type = type							# ObjectProp | Array | Func | Proxy | Event | DOMAttr | DOMValue | DOMCheckbox | DOMRadio
	@object = object 						# The subject object of this binding, i.e. function, array, {}, DOM el, etc.
	@ID = genID() 							# Assigned only after passing a valid object to .of()
	@subs = []								# Subscribers array listing all of the objects that will be updated upon value update
	@subOpts = genObj()						# Map subscribers' options by their ID
	@pubsMap = genObj()						# Map publishers (bindings that update this binding) by their ID
	@subsPholders = genObj()				# SubscriberID:sub-placeholder mapping
	@myPholders = genObj() 					# SubscriberID:self-placeholder mapping indicating which subs will receive a value of a specific placeholder from this binding (if applicable)
	@attachedEvents = []					# Array listing all of the events currently listened on @object
	@setValue = noop if @type is 'Array' or @type is 'Proxy'

	# ==== Properties declared later or inherited from binding interface =================================================================================
	# @options = options
	# @transforms = genObj()				# SubscriberID:transformFn mapping
	# @conditions = genObj() 				# SubscriberID:coniditionFn mapping
	# @valueOriginal = undefined			# Value on init
	# @value = undefined 					# Will represent the actual current value of the binding/object
	# @property = property					# The property name or array index or event callback argument
	# @selector = selector					# The property name or array index or event callback argument
	# @customEventMethod = {}				# Names of the event emitter/trigger methods (if applicable)
	# @pholderValues = {}					# Placeholder value mapping
	# @pholderContexts = {}					# Placeholder surroundings (original binding value split by the placeholder regEx)
	# @pholderIndexMap = {}					# Placeholder occurence mapping, i.e. the placeholder name for each placeholder occurence
	# @placeholder = ""						# The last specified placeholder to bind the value to
	# @descriptor = ""						# Describes the type of property, i.e. 'attr:data-name' to indicate a DOMAttr type binding
	# @isLiveProp = Boolean					# Indicates whether or not the Object/Object's propety have been modified to be a live property
	# @isDom = Boolean						# Indicates whether or not the binding's object is a DOM object
	# @pollInterval = ID					# The interval ID of the timer that manually polls the object's value at a set interval
	# @arrayBinding = Binding				# Reference to the parent array binding (if exists) for an index-of-array binding (i.e. SimplyBind(array))
	# @trackedChildren = []					# For Array type bindings - indicates which indicies of the array are tracked for changes (applicable when @options.trackArrayChildren) is true
	# @eventName = ""						# The name of the event this binding is listening to (for Event type bindings)
	# @isEmitter = Boolean 					# Tracker to let us know we shouldn't handle the event update we received as it is the event this binding just emitted
	# @eventHandler = Function 				# The callback that gets triggered upon an event emittance (for Even type bindings)
	# @eventObject = Event 					# The dispatched event object (for Event type bindings)
	# @selfTransform = Function 			# The transform function that new values being set to this binding are being passed through during @setValue (if applicable)
	# @throttleRate = milliseconds			# The rate in which the binding's subscribers will be updated only once in
	# @throttleTimeout = ID					# The timeout ID of the delay timer to update a throttled binding
	# @lastUpdate = epoch timestamp			# Last time the subs have been updated; used for throttle functions
	# @isAsync = Boolean					# Indicates if this is an async binding (currently only used for Event bindings)
	### ========================================================================== ###


	import [browserOnly] -DOMChoice_group.coffee
	
	unless @type is 'Event' or (@type is 'Func' and @parentInterface) # the second condition will prevent function subscribers from being invoked on this binding creation
		@value = @valueOriginal = subjectValue = @fetchDirectValue()
		
		if @type is 'ObjectProp' and not checkIf.isDefined(subjectValue)
			@object[@property] = subjectValue # Define the prop on the object if it non-existent

		
		if @placeholder and not @pholderValues
			@scanForPholders()


		@convertToLive()
	@attachEvents()




	# IF this is a binding to a specific index of an array then we must make this binding update the array on change if the array binding is tracking its children
	if @object instanceof Array and @type isnt 'Array'
		@arrayBinding = arrayBinding = cache.get(@object, true)
		
		if arrayBinding and arrayBinding.trackedChildren and not targetIncludes(arrayBinding.trackedChildren, @property)
			arrayBinding.trackedChildren.push(@property)
			SimplyBind(@property).of(@object).to arrayBinding.updateSelf


	return boundInstances[@ID] = @





import prototype.coffee
