/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.core.common.model.binding.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingPackage;
import org.eclipse.osbp.ecview.core.common.model.binding.YBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingSet;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingUpdateStrategy;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.core.impl.YStringToStringMapImpl;

// TODO: Auto-generated Javadoc
/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>YBinding Set</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getId <em>Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getProperties <em>Properties</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getBindings <em>Bindings</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.common.model.binding.impl.YBindingSetImpl#getTransientBindings <em>Transient Bindings</em>}</li>
 * </ul>
 *
 * @generated
 */
public class YBindingSetImpl extends MinimalEObjectImpl.Container implements
		YBindingSet {
	/**
	 * The cached value of the '{@link #getTags() <em>Tags</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<String> tags;
	/**
	 * The default value of the '{@link #getId() <em>Id</em>}' attribute. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected static final String ID_EDEFAULT = null;
	/**
	 * The cached value of the '{@link #getId() <em>Id</em>}' attribute. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected String id = ID_EDEFAULT;
	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = null;
	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;
	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected EMap<String, String> properties;
	/**
	 * The cached value of the '{@link #getBindings() <em>Bindings</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getBindings()
	 * @generated
	 * @ordered
	 */
	protected EList<YBinding> bindings;

	/**
	 * The cached value of the '{@link #getTransientBindings() <em>Transient Bindings</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTransientBindings()
	 * @generated
	 * @ordered
	 */
	protected EList<YBinding> transientBindings;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @generated
	 */
	protected YBindingSetImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the e class
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return BindingPackage.Literals.YBINDING_SET;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getId() <em>Id</em>}' attribute
	 * @generated
	 */
	public String getId() {
		return id;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newId
	 *            the new cached value of the '{@link #getId() <em>Id</em>}'
	 *            attribute
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BindingPackage.YBINDING_SET__ID, oldId, id));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getName() <em>Name</em>}'
	 *         attribute
	 * @generated
	 */
	public String getName() {
		return name;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newName
	 *            the new cached value of the '{@link #getName() <em>Name</em>}'
	 *            attribute
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BindingPackage.YBINDING_SET__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTags() <em>Tags</em>}'
	 *         attribute list
	 * @generated
	 */
	public EList<String> getTags() {
		if (tags == null) {
			tags = new EDataTypeUniqueEList<String>(String.class, this, BindingPackage.YBINDING_SET__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getProperties()
	 *         <em>Properties</em>}' map
	 * @generated
	 */
	public EMap<String, String> getProperties() {
		if (properties == null) {
			properties = new EcoreEMap<String,String>(CoreModelPackage.Literals.YSTRING_TO_STRING_MAP, YStringToStringMapImpl.class, this, BindingPackage.YBINDING_SET__PROPERTIES);
		}
		return properties;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getBindings() <em>Bindings</em>}
	 *         ' containment reference list
	 * @generated
	 */
	public EList<YBinding> getBindings() {
		if (bindings == null) {
			bindings = new EObjectContainmentEList.Resolving<YBinding>(YBinding.class, this, BindingPackage.YBINDING_SET__BINDINGS);
		}
		return bindings;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTransientBindings()
	 *         <em>Transient Bindings</em>}' reference list
	 * @generated
	 */
	public EList<YBinding> getTransientBindings() {
		if (transientBindings == null) {
			transientBindings = new EObjectResolvingEList<YBinding>(YBinding.class, this, BindingPackage.YBINDING_SET__TRANSIENT_BINDINGS);
		}
		return transientBindings;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y value binding
	 * @generated
	 */
	public YValueBinding addBindingGen(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y value binding
	 * @generated NOT
	 */
	public YValueBinding addBinding(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue) {
		return addBinding(targetValue, modelValue,
				YBindingUpdateStrategy.UPDATE, YBindingUpdateStrategy.UPDATE);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y list binding
	 * @generated
	 */
	public YListBinding addBindingGen(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y list binding
	 * @generated NOT
	 */
	public YListBinding addBinding(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue) {
		return addBinding(targetValue, modelValue,
				YBindingUpdateStrategy.UPDATE, YBindingUpdateStrategy.UPDATE);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y value binding
	 * @generated NOT
	 */
	public YValueBinding addBinding(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {

		// create a new binding
		YValueBinding binding = BindingFactory.eINSTANCE.createYValueBinding();
		binding.setTargetEndpoint(targetValue);
		binding.setModelEndpoint(modelValue);
		binding.setModelToTargetStrategy(modelToTargetStrategy);
		binding.setTargetToModelStrategy(targetToModelStrategy);

		// add the binding to the internal list of bindings
		getBindings().add(binding);

		return binding;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y list binding
	 * @generated NOT
	 */
	public YListBinding addBinding(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {

		// create a new binding
		YListBinding binding = BindingFactory.eINSTANCE.createYListBinding();
		binding.setTargetEndpoint(targetValue);
		binding.setModelEndpoint(modelValue);
		binding.setModelToTargetStrategy(modelToTargetStrategy);
		binding.setTargetToModelStrategy(targetToModelStrategy);

		// add the binding to the internal list of bindings
		getBindings().add(binding);

		return binding;

	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y value binding
	 * @generated
	 */
	public YValueBinding addBindingGen(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y list binding
	 * @generated
	 */
	public YListBinding addBindingGen(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the view gen
	 * @generated
	 */
	public YView getViewGen() {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns the view that binding set is attached to.
	 *
	 * @return the view
	 * @generated NOT
	 */
	public YView getView() {
		return (YView) eContainer();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param binding
	 *            the binding
	 * @generated
	 */
	public void addBindingGen(YBinding binding) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param binding
	 *            the binding
	 * @generated NOT
	 */
	public void addBinding(YBinding binding) {
		getBindings().add(binding);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param binding
	 *            the binding
	 * @generated
	 */
	public void removeBindingGen(YBinding binding) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param binding
	 *            the binding
	 * @generated NOT
	 */
	public void removeBinding(YBinding binding) {
		getBindings().remove(binding);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case BindingPackage.YBINDING_SET__PROPERTIES:
				return ((InternalEList<?>)getProperties()).basicRemove(otherEnd, msgs);
			case BindingPackage.YBINDING_SET__BINDINGS:
				return ((InternalEList<?>)getBindings()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param resolve
	 *            the resolve
	 * @param coreType
	 *            the core type
	 * @return the object
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case BindingPackage.YBINDING_SET__TAGS:
				return getTags();
			case BindingPackage.YBINDING_SET__ID:
				return getId();
			case BindingPackage.YBINDING_SET__NAME:
				return getName();
			case BindingPackage.YBINDING_SET__PROPERTIES:
				if (coreType) return getProperties();
				else return getProperties().map();
			case BindingPackage.YBINDING_SET__BINDINGS:
				return getBindings();
			case BindingPackage.YBINDING_SET__TRANSIENT_BINDINGS:
				return getTransientBindings();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case BindingPackage.YBINDING_SET__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends String>)newValue);
				return;
			case BindingPackage.YBINDING_SET__ID:
				setId((String)newValue);
				return;
			case BindingPackage.YBINDING_SET__NAME:
				setName((String)newValue);
				return;
			case BindingPackage.YBINDING_SET__PROPERTIES:
				((EStructuralFeature.Setting)getProperties()).set(newValue);
				return;
			case BindingPackage.YBINDING_SET__BINDINGS:
				getBindings().clear();
				getBindings().addAll((Collection<? extends YBinding>)newValue);
				return;
			case BindingPackage.YBINDING_SET__TRANSIENT_BINDINGS:
				getTransientBindings().clear();
				getTransientBindings().addAll((Collection<? extends YBinding>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case BindingPackage.YBINDING_SET__TAGS:
				getTags().clear();
				return;
			case BindingPackage.YBINDING_SET__ID:
				setId(ID_EDEFAULT);
				return;
			case BindingPackage.YBINDING_SET__NAME:
				setName(NAME_EDEFAULT);
				return;
			case BindingPackage.YBINDING_SET__PROPERTIES:
				getProperties().clear();
				return;
			case BindingPackage.YBINDING_SET__BINDINGS:
				getBindings().clear();
				return;
			case BindingPackage.YBINDING_SET__TRANSIENT_BINDINGS:
				getTransientBindings().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @return true, if successful
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case BindingPackage.YBINDING_SET__TAGS:
				return tags != null && !tags.isEmpty();
			case BindingPackage.YBINDING_SET__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
			case BindingPackage.YBINDING_SET__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case BindingPackage.YBINDING_SET__PROPERTIES:
				return properties != null && !properties.isEmpty();
			case BindingPackage.YBINDING_SET__BINDINGS:
				return bindings != null && !bindings.isEmpty();
			case BindingPackage.YBINDING_SET__TRANSIENT_BINDINGS:
				return transientBindings != null && !transientBindings.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the string
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (tags: ");
		result.append(tags);
		result.append(", id: ");
		result.append(id);
		result.append(", name: ");
		result.append(name);
		result.append(')');
		return result.toString();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param binding
	 *            the binding
	 * @generated NOT
	 */
	public void addTransientBinding(YBinding binding) {
		getTransientBindings().add(binding);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y list binding
	 * @generated NOT
	 */
	public YListBinding addTransientBinding(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue) {
		return addTransientBinding(targetValue, modelValue,
				YBindingUpdateStrategy.UPDATE, YBindingUpdateStrategy.UPDATE);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y list binding
	 * @generated NOT
	 */
	public YListBinding addTransientBinding(YListBindingEndpoint targetValue,
			YListBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {
	
		// create a new binding
		YListBinding binding = BindingFactory.eINSTANCE.createYListBinding();
		binding.setTargetEndpoint(targetValue);
		binding.setModelEndpoint(modelValue);
		binding.setModelToTargetStrategy(modelToTargetStrategy);
		binding.setTargetToModelStrategy(targetToModelStrategy);
	
		// add the binding to the internal list of bindings
		getTransientBindings().add(binding);
	
		return binding;
	
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @return the y value binding
	 * @generated NOT
	 */
	public YValueBinding addTransientBinding(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue) {
		return addTransientBinding(targetValue, modelValue,
				YBindingUpdateStrategy.UPDATE, YBindingUpdateStrategy.UPDATE);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param targetValue
	 *            the target value
	 * @param modelValue
	 *            the model value
	 * @param targetToModelStrategy
	 *            the target to model strategy
	 * @param modelToTargetStrategy
	 *            the model to target strategy
	 * @return the y value binding
	 * @generated NOT
	 */
	public YValueBinding addTransientBinding(YValueBindingEndpoint targetValue,
			YValueBindingEndpoint modelValue,
			YBindingUpdateStrategy targetToModelStrategy,
			YBindingUpdateStrategy modelToTargetStrategy) {
	
		// create a new binding
		YValueBinding binding = BindingFactory.eINSTANCE.createYValueBinding();
		binding.setTargetEndpoint(targetValue);
		binding.setModelEndpoint(modelValue);
		binding.setModelToTargetStrategy(modelToTargetStrategy);
		binding.setTargetToModelStrategy(targetToModelStrategy);
	
		// add the binding to the internal list of bindings
		getTransientBindings().add(binding);
	
		return binding;
	}

} // YBindingSetImpl
