BindingInterfacePrivate =
	selfClone: ()-> new BindingInterface(null, @)
	
	defineMainProps: (binding)->
		@_ = binding
		Object.defineProperties @,
			'value':		get: ()-> binding.value
			'original':		get: ()-> binding.objects or binding.object
			'subscribers':	get: ()-> binding.subs.slice().map (sub)-> sub.object




	createBinding: (subject, newObjectType, bindingInterface, isFunction)->
		@object = subject
		cachedBinding = cache.get(subject, isFunction, @selector, @isMultiChoice)
		
		if cachedBinding # Exit early by returning the subject from cache if is already in there
			return @patchCachedBinding(cachedBinding)

		else
			newBinding = new Binding(subject, newObjectType, bindingInterface)
			cache.set(newBinding, isFunction)
			return newBinding



	patchCachedBinding: (cachedBinding)->
		if cachedBinding.type is 'ObjectProp' and @property not of @object # This property was manually deleted and needs its prop to be re-defined as a live one
			convertToLive(cachedBinding, @object)

		if @saveOptions
			cachedBinding.optionsDefault[option] = value for option,value of @optionsPassed

		for key,value of cachedBinding.optionsDefault
			@options[key] = if checkIf.isDefined(@optionsPassed[key]) then @optionsPassed[key] else value
		
		return cachedBinding



	setProperty: (subject)->
		subject = subject.toString() if checkIf.isNumber(subject)
		@selector = @property = subject

		
		unless @options.simpleSelector
			if targetIncludes(subject, ':')
				split = subject.split(':')
				@descriptor = split.slice(0, -1).join(':')
				@property = split[split.length-1]
			
			
			if targetIncludes(subject, '.') # Placeholder extraction
				split = @property.split('.') # We use '@property' instead of 'subject' because it may have been modified by the previous ':' descriptor check
				@property = split[0]				
				@pholder = split.slice(1).join('.')



			if targetIncludes(@descriptor, 'event')
				if targetIncludes(subject, '#')
					split = @property.split('#')
					@eventName = split[0]
					@property = split[1]
				else
					@eventName = @property
					@property = 0

				throwWarning('badEventArg',1) if isNaN parseInt(@property)

		return @



	setObject: (subject, isFunction)->
		@stage = 1
		# simplyimport:if BUNDLE_TARGET = 'browser'
		import './prototype-private.setObject-parseDOMObject'
		# simplyimport:end
		
		switch
			when isFunction
				newObjectType = 'Func'
			
			when @pholder
				newObjectType = 'Pholder'
			
			when targetIncludes(@descriptor, 'array') and checkIf.isArray(subject[@property])
				newObjectType = 'Array'
			
			when targetIncludes(@descriptor, 'event')
				newObjectType = 'Event'
				import './prototype-private.setObject-defineEventMethods'

			when targetIncludes(@descriptor, 'func')
				newObjectType = 'Proxy'
			
			# simplyimport:if BUNDLE_TARGET = 'browser'
			when isDomRadio 
				newObjectType = 'DOMRadio'

			when isDomCheckbox 
				newObjectType = 'DOMCheckbox'

			when targetIncludes(@descriptor, 'attr')
				newObjectType = 'DOMAttr'
			# simplyimport:end

			else
				newObjectType = 'ObjectProp'
		

		if targetIncludes(@descriptor, 'multi')
			throwError('emptyList') if not subject.length
			@defineMainProps new GroupBinding(@, subject, newObjectType)
		else
			@defineMainProps @createBinding(subject, newObjectType, @, isFunction)


		if targetIncludes(@_.type, 'Event') or targetIncludes(@_.type, 'Proxy')
			@options.updateOnBind = false
		else if targetIncludes(@_.type, 'Func')
			@options.updateOnBind = true


		if @completeCallback
			return @completeCallback(@)
		else
			return @




	addToPublisher: (publisherInterface)->
		publisherInterface.stage = 2
		publisherInterface.subs.push(@)
		alreadyHadSub = publisherInterface._.addSub(@_, publisherInterface.options, publisherInterface.updateOnce)

		if publisherInterface.updateOnce
			delete publisherInterface.updateOnce
		
		else if publisherInterface.options.updateOnBind and not alreadyHadSub
			if @_.isMulti
				publisherInterface._.updateSub(binding, publisherInterface._) for binding in @_.bindings
			else
				publisherInterface._.updateSub(@_, publisherInterface._)

		return





