Binding = (object, type, state)->
	extendState(@, state)
	@optionsDefault = if @saveOptions then @options else defaultOptions
	@type = type							# ObjectProp | Array | Func | Proxy | Event | Pholder | DOMAttr | 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
	@subsMeta = genObj()					# Map subscribers' ID to their metadata (i.e. options, transform, condition, one-time-binding, etc.)
	@pubsMap = genObj()						# Map publishers (bindings that update this binding) by their ID
	@attachedEvents = []					# Array listing all of the events currently listened on @object
	@setValue = setValueNoop if @type is 'Proxy'

	# ==== Properties declared later or inherited from binding interface =================================================================================
	# @options = options
	# @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
	# @origFn = Function					# The original proxied function passed to Proxy bindings
	# @customEventMethod = {}				# Names of the event emitter/trigger methods (if applicable)
	# @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))
	# @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)
	# @selfUpdater = Function 				# A Func-type Binding which invokes @setValue(@fetchDirectValue()) upon change. Created in @convertToLive() for Array bindings & in interface.updateOn()
	# @isAsync = Boolean					# Indicates if this is an async binding (currently only used for Event bindings)
	### ========================================================================== ###

	# simplyimport:if BUNDLE_TARGET = 'browser'
	if @isMultiChoice # True if @object is a radio/checkbox collection
		@choices = genObj()
		
		@object.forEach (choiceEl)=>
			choiceBinding = @choices[choiceEl.value] = SimplyBind('checked').of(choiceEl)._
			choiceBinding.addSub(@)
			choiceBinding.subsMeta[@ID].transformFn = ()-> choiceBinding
			choiceBinding.groupBinding = @
			return
	# simplyimport:end
	

	unless @type is 'Event' or (@type is 'Func' and @isSub) # the second condition will prevent function subscribers from being invoked on this binding creation
		if @type is 'Pholder'
			# simplyimport:if BUNDLE_TARGET = 'browser'
			parentProperty = if @descriptor and not targetIncludes(@descriptor, 'multi') then "#{@descriptor}:#{@property}" else @property
			# simplyimport:end
			
			# simplyimport:if BUNDLE_TARGET = 'node'
			parentProperty = @property
			# simplyimport:end
			
			parentBinding = @parentBinding = SimplyBind(parentProperty).of(object)._
			parentBinding.scanForPholders()
			@value = parentBinding.pholderValues[@pholder]
		
			# simplyimport:if BUNDLE_TARGET = 'browser'
			@textNodes = parentBinding.textNodes[@pholder] if parentBinding.textNodes
			# simplyimport:end
		

		else
			@value = subjectValue = @fetchDirectValue()
		
			if @type is 'ObjectProp' and not checkIf.isDefined(subjectValue) and not getDescriptor(@object, @property)
				@object[@property] = subjectValue # Define the prop on the object if it non-existent

			convertToLive(@, @object)


	@attachEvents()
	return boundInstances[@ID] = @





import './prototype'
