/**
 */
package org.etsi.mts.tdl.impl;

import java.lang.reflect.InvocationTargetException;

import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.library.classifier.ClassifierAllInstancesOperation;
import org.eclipse.ocl.pivot.library.collection.CollectionAsOrderedSetOperation;
import org.eclipse.ocl.pivot.library.collection.OrderedCollectionFirstOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclAsTypeOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclIsKindOfOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclTypeOperation;
import org.eclipse.ocl.pivot.messages.PivotMessages;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.InvalidValueException;
import org.eclipse.ocl.pivot.values.OrderedSetValue;
import org.eclipse.ocl.pivot.values.SetValue;
import org.eclipse.ocl.pivot.values.SetValue.Accumulator;
import org.etsi.mts.tdl.AnnotationType;
import org.etsi.mts.tdl.ComponentType;
import org.etsi.mts.tdl.Extension;
import org.etsi.mts.tdl.GateType;
import org.etsi.mts.tdl.PackageableElement;
import org.etsi.mts.tdl.SimpleDataType;
import org.etsi.mts.tdl.StructuredDataType;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.tdlTables;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Packageable Element</b></em>'.
 * <!-- end-user-doc -->
 *
 * @generated
 */
public abstract class PackageableElementImpl extends NamedElementImpl implements PackageableElement
{
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PackageableElementImpl()
	{
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass()
	{
		return tdlPackage.Literals.PACKAGEABLE_ELEMENT;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Boolean conformsTo(final String n)
	{
		/**
		 *
		 * if self.getElementNamed(n).oclIsUndefined()
		 * then false
		 * else self.conformsTo(self.getElementNamed(n))
		 * endif
		 */
		/*@Caught*/ Object CAUGHT_getElementNamed;
		try {
			final /*@Thrown*/ PackageableElement getElementNamed = this.getElementNamed(n);
			CAUGHT_getElementNamed = getElementNamed;
		}
		catch (Exception e) {
			CAUGHT_getElementNamed = ValueUtil.createInvalidValue(e);
		}
		final /*@NonInvalid*/ boolean oclIsUndefined = CAUGHT_getElementNamed instanceof InvalidValueException;
		/*@Thrown*/ boolean local_0;
		if (oclIsUndefined) {
			local_0 = false;
		}
		else {
			final /*@Thrown*/ PackageableElement getElementNamed_0 = this.getElementNamed(n);
			final /*@Thrown*/ boolean conformsTo = this.conformsTo(getElementNamed_0);
			local_0 = conformsTo;
		}
		return local_0;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public PackageableElement getElementNamed(final String n)
	{
		/**
		 *
		 * self.oclType()
		 * .allInstances()
		 * ->select(e | e.name = n)
		 * ->asOrderedSet()
		 * ->first()
		 */
		final /*@NonInvalid*/ Executor executor = PivotUtil.getExecutor(this);
		final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class oclType = (org.eclipse.ocl.pivot.Class)OclAnyOclTypeOperation.INSTANCE.evaluate(executor, this);
		final /*@NonInvalid*/ SetValue allInstances = ClassifierAllInstancesOperation.INSTANCE.evaluate(executor, tdlTables.SET_CLSSid_PackageableElement, oclType);
		/*@Thrown*/ Accumulator accumulator = ValueUtil.createSetAccumulatorValue(tdlTables.SET_CLSSid_PackageableElement);
		Iterator<Object> ITERATOR_e_1 = allInstances.iterator();
		/*@NonInvalid*/ SetValue select;
		while (true) {
			if (!ITERATOR_e_1.hasNext()) {
				select = accumulator;
				break;
			}
			/*@NonInvalid*/ PackageableElement e_1 = (PackageableElement)ITERATOR_e_1.next();
			/**
			 * e.name = n
			 */
			final /*@NonInvalid*/ String name = e_1.getName();
			final /*@NonInvalid*/ boolean eq = (name != null) ? name.equals(n) : (n == null);
			//
			if (eq) {
				accumulator.add(e_1);
			}
		}
		final /*@NonInvalid*/ OrderedSetValue asOrderedSet = CollectionAsOrderedSetOperation.INSTANCE.evaluate(select);
		final /*@Thrown*/ PackageableElement first = (PackageableElement)OrderedCollectionFirstOperation.INSTANCE.evaluate(asOrderedSet);
		return first;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Boolean conformsTo(final PackageableElement n)
	{
		/**
		 *
		 * if self = n
		 * then true
		 * else
		 *   if
		 *     self.oclIsKindOf(AnnotationType) and
		 *     not self.oclAsType(AnnotationType)
		 *     .extension.oclIsUndefined()
		 *   then self.oclAsType(AnnotationType).extension.isExtending(n)
		 *   else
		 *     if
		 *       self.oclIsKindOf(ComponentType) and
		 *       not self.oclAsType(ComponentType)
		 *       .extension.oclIsUndefined()
		 *     then self.oclAsType(ComponentType).extension.isExtending(n)
		 *     else
		 *       if
		 *         self.oclIsKindOf(GateType) and
		 *         not self.oclAsType(GateType)
		 *         .extension.oclIsUndefined()
		 *       then self.oclAsType(GateType).extension.isExtending(n)
		 *       else
		 *         if self.oclIsKindOf(StructuredDataType)
		 *         then
		 *           self.oclAsType(StructuredDataType)
		 *           .extension->exists(ex | ex.isExtending(n))
		 *         else
		 *           if
		 *             self.oclIsKindOf(SimpleDataType) and
		 *             not self.oclAsType(SimpleDataType)
		 *             .extension.oclIsUndefined()
		 *           then
		 *             self.oclAsType(SimpleDataType)
		 *             .extension.isExtending(n)
		 *           else false
		 *           endif
		 *         endif
		 *       endif
		 *     endif
		 *   endif
		 * endif
		 */
		final /*@NonInvalid*/ Executor executor = PivotUtil.getExecutor(this);
		final /*@NonInvalid*/ IdResolver idResolver = executor.getIdResolver();
		final /*@NonInvalid*/ boolean eq = this.equals(n);
		/*@Thrown*/ Boolean local_5;
		if (eq) {
			local_5 = ValueUtil.TRUE_VALUE;
		}
		else {
			final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_AnnotationType_0 = idResolver.getClass(tdlTables.CLSSid_AnnotationType, null);
			final /*@NonInvalid*/ boolean oclIsKindOf = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_AnnotationType_0).booleanValue();
			final /*@Thrown*/ Boolean and;
			if (!oclIsKindOf) {
				and = ValueUtil.FALSE_VALUE;
			}
			else {
				/*@Caught*/ Object CAUGHT_extension;
				try {
					final /*@Thrown*/ AnnotationType oclAsType = (AnnotationType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_AnnotationType_0);
					final /*@Thrown*/ Extension extension = oclAsType.getExtension();
					CAUGHT_extension = extension;
				}
				catch (Exception e) {
					CAUGHT_extension = ValueUtil.createInvalidValue(e);
				}
				final /*@NonInvalid*/ boolean oclIsUndefined = (CAUGHT_extension == null) || (CAUGHT_extension instanceof InvalidValueException);
				final /*@NonInvalid*/ Boolean not;
				if (!oclIsUndefined) {
					not = ValueUtil.TRUE_VALUE;
				}
				else {
					if (oclIsUndefined) {
						not = ValueUtil.FALSE_VALUE;
					}
					else {
						not = null;
					}
				}
				if (not == ValueUtil.FALSE_VALUE) {
					and = ValueUtil.FALSE_VALUE;
				}
				else {
					if (not == null) {
						and = null;
					}
					else {
						and = ValueUtil.TRUE_VALUE;
					}
				}
			}
			if (and == null) {
				throw new InvalidValueException("Null if condition");
			}
			/*@Thrown*/ Boolean local_4;
			if (and) {
				final /*@Thrown*/ AnnotationType oclAsType_0 = (AnnotationType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_AnnotationType_0);
				final /*@Thrown*/ Extension extension_0 = oclAsType_0.getExtension();
				if (extension_0 == null) {
					throw new InvalidValueException("Null source for \'tdl::Extension::isExtending(tdl::PackageableElement[?]) : Boolean[?]\'");
				}
				final /*@Thrown*/ boolean isExtending = extension_0.isExtending(n);
				local_4 = isExtending;
			}
			else {
				final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_ComponentType_0 = idResolver.getClass(tdlTables.CLSSid_ComponentType, null);
				final /*@NonInvalid*/ boolean oclIsKindOf_0 = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_ComponentType_0).booleanValue();
				final /*@Thrown*/ Boolean and_0;
				if (!oclIsKindOf_0) {
					and_0 = ValueUtil.FALSE_VALUE;
				}
				else {
					/*@Caught*/ Object CAUGHT_extension_1;
					try {
						final /*@Thrown*/ ComponentType oclAsType_1 = (ComponentType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_ComponentType_0);
						final /*@Thrown*/ Extension extension_1 = oclAsType_1.getExtension();
						CAUGHT_extension_1 = extension_1;
					}
					catch (Exception e) {
						CAUGHT_extension_1 = ValueUtil.createInvalidValue(e);
					}
					final /*@NonInvalid*/ boolean oclIsUndefined_0 = (CAUGHT_extension_1 == null) || (CAUGHT_extension_1 instanceof InvalidValueException);
					final /*@NonInvalid*/ Boolean not_0;
					if (!oclIsUndefined_0) {
						not_0 = ValueUtil.TRUE_VALUE;
					}
					else {
						if (oclIsUndefined_0) {
							not_0 = ValueUtil.FALSE_VALUE;
						}
						else {
							not_0 = null;
						}
					}
					if (not_0 == ValueUtil.FALSE_VALUE) {
						and_0 = ValueUtil.FALSE_VALUE;
					}
					else {
						if (not_0 == null) {
							and_0 = null;
						}
						else {
							and_0 = ValueUtil.TRUE_VALUE;
						}
					}
				}
				if (and_0 == null) {
					throw new InvalidValueException("Null if condition");
				}
				/*@Thrown*/ Boolean local_3;
				if (and_0) {
					final /*@Thrown*/ ComponentType oclAsType_2 = (ComponentType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_ComponentType_0);
					final /*@Thrown*/ Extension extension_2 = oclAsType_2.getExtension();
					if (extension_2 == null) {
						throw new InvalidValueException("Null source for \'tdl::Extension::isExtending(tdl::PackageableElement[?]) : Boolean[?]\'");
					}
					final /*@Thrown*/ boolean isExtending_0 = extension_2.isExtending(n);
					local_3 = isExtending_0;
				}
				else {
					final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_GateType_0 = idResolver.getClass(tdlTables.CLSSid_GateType, null);
					final /*@NonInvalid*/ boolean oclIsKindOf_1 = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_GateType_0).booleanValue();
					final /*@Thrown*/ Boolean and_1;
					if (!oclIsKindOf_1) {
						and_1 = ValueUtil.FALSE_VALUE;
					}
					else {
						/*@Caught*/ Object CAUGHT_extension_3;
						try {
							final /*@Thrown*/ GateType oclAsType_3 = (GateType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_GateType_0);
							final /*@Thrown*/ Extension extension_3 = oclAsType_3.getExtension();
							CAUGHT_extension_3 = extension_3;
						}
						catch (Exception e) {
							CAUGHT_extension_3 = ValueUtil.createInvalidValue(e);
						}
						final /*@NonInvalid*/ boolean oclIsUndefined_1 = (CAUGHT_extension_3 == null) || (CAUGHT_extension_3 instanceof InvalidValueException);
						final /*@NonInvalid*/ Boolean not_1;
						if (!oclIsUndefined_1) {
							not_1 = ValueUtil.TRUE_VALUE;
						}
						else {
							if (oclIsUndefined_1) {
								not_1 = ValueUtil.FALSE_VALUE;
							}
							else {
								not_1 = null;
							}
						}
						if (not_1 == ValueUtil.FALSE_VALUE) {
							and_1 = ValueUtil.FALSE_VALUE;
						}
						else {
							if (not_1 == null) {
								and_1 = null;
							}
							else {
								and_1 = ValueUtil.TRUE_VALUE;
							}
						}
					}
					if (and_1 == null) {
						throw new InvalidValueException("Null if condition");
					}
					/*@Thrown*/ Boolean local_2;
					if (and_1) {
						final /*@Thrown*/ GateType oclAsType_4 = (GateType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_GateType_0);
						final /*@Thrown*/ Extension extension_4 = oclAsType_4.getExtension();
						if (extension_4 == null) {
							throw new InvalidValueException("Null source for \'tdl::Extension::isExtending(tdl::PackageableElement[?]) : Boolean[?]\'");
						}
						final /*@Thrown*/ boolean isExtending_1 = extension_4.isExtending(n);
						local_2 = isExtending_1;
					}
					else {
						final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_StructuredDataType_0 = idResolver.getClass(tdlTables.CLSSid_StructuredDataType, null);
						final /*@NonInvalid*/ boolean oclIsKindOf_2 = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_StructuredDataType_0).booleanValue();
						/*@Thrown*/ Boolean local_1;
						if (oclIsKindOf_2) {
							final /*@Thrown*/ StructuredDataType oclAsType_5 = (StructuredDataType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_StructuredDataType_0);
							final /*@Thrown*/ List<Extension> extension_5 = oclAsType_5.getExtension();
							final /*@Thrown*/ OrderedSetValue BOXED_extension_5 = idResolver.createOrderedSetOfAll(tdlTables.ORD_CLSSid_Extension, extension_5);
							/*@Thrown*/ Object accumulator = ValueUtil.FALSE_VALUE;
							Iterator<Object> ITERATOR_ex = BOXED_extension_5.iterator();
							/*@Thrown*/ Boolean exists;
							while (true) {
								if (!ITERATOR_ex.hasNext()) {
									if (accumulator == ValueUtil.FALSE_VALUE) {
										exists = ValueUtil.FALSE_VALUE;
									}
									else {
										throw (InvalidValueException)accumulator;
									}
									break;
								}
								/*@NonInvalid*/ Extension ex = (Extension)ITERATOR_ex.next();
								/**
								 * ex.isExtending(n)
								 */
								/*@Caught*/ Object CAUGHT_isExtending_2;
								try {
									if (ex == null) {
										throw new InvalidValueException("Null source for \'tdl::Extension::isExtending(tdl::PackageableElement[?]) : Boolean[?]\'");
									}
									final /*@Thrown*/ boolean isExtending_2 = ex.isExtending(n);
									CAUGHT_isExtending_2 = isExtending_2;
								}
								catch (Exception e) {
									CAUGHT_isExtending_2 = ValueUtil.createInvalidValue(e);
								}
								//
								if (CAUGHT_isExtending_2 == ValueUtil.TRUE_VALUE) {					// Normal successful body evaluation result
									exists = ValueUtil.TRUE_VALUE;
									break;														// Stop immediately
								}
								else if (CAUGHT_isExtending_2 == ValueUtil.FALSE_VALUE) {				// Normal unsuccessful body evaluation result
									;															// Carry on
								}
								else if (CAUGHT_isExtending_2 instanceof InvalidValueException) {		// Abnormal exception evaluation result
									accumulator = CAUGHT_isExtending_2;									// Cache an exception failure
								}
								else {															// Impossible badly typed result
									accumulator = new InvalidValueException(PivotMessages.NonBooleanBody, "exists");
								}
							}
							local_1 = exists;
						}
						else {
							final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_SimpleDataType_0 = idResolver.getClass(tdlTables.CLSSid_SimpleDataType, null);
							final /*@NonInvalid*/ boolean oclIsKindOf_3 = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_SimpleDataType_0).booleanValue();
							final /*@Thrown*/ Boolean and_2;
							if (!oclIsKindOf_3) {
								and_2 = ValueUtil.FALSE_VALUE;
							}
							else {
								/*@Caught*/ Object CAUGHT_extension_6;
								try {
									final /*@Thrown*/ SimpleDataType oclAsType_6 = (SimpleDataType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_SimpleDataType_0);
									final /*@Thrown*/ Extension extension_6 = oclAsType_6.getExtension();
									CAUGHT_extension_6 = extension_6;
								}
								catch (Exception e) {
									CAUGHT_extension_6 = ValueUtil.createInvalidValue(e);
								}
								final /*@NonInvalid*/ boolean oclIsUndefined_2 = (CAUGHT_extension_6 == null) || (CAUGHT_extension_6 instanceof InvalidValueException);
								final /*@NonInvalid*/ Boolean not_2;
								if (!oclIsUndefined_2) {
									not_2 = ValueUtil.TRUE_VALUE;
								}
								else {
									if (oclIsUndefined_2) {
										not_2 = ValueUtil.FALSE_VALUE;
									}
									else {
										not_2 = null;
									}
								}
								if (not_2 == ValueUtil.FALSE_VALUE) {
									and_2 = ValueUtil.FALSE_VALUE;
								}
								else {
									if (not_2 == null) {
										and_2 = null;
									}
									else {
										and_2 = ValueUtil.TRUE_VALUE;
									}
								}
							}
							if (and_2 == null) {
								throw new InvalidValueException("Null if condition");
							}
							/*@Thrown*/ boolean local_0;
							if (and_2) {
								final /*@Thrown*/ SimpleDataType oclAsType_7 = (SimpleDataType)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, this, TYP_tdl_c_c_SimpleDataType_0);
								final /*@Thrown*/ Extension extension_7 = oclAsType_7.getExtension();
								if (extension_7 == null) {
									throw new InvalidValueException("Null source for \'tdl::Extension::isExtending(tdl::PackageableElement[?]) : Boolean[?]\'");
								}
								final /*@Thrown*/ boolean isExtending_3 = extension_7.isExtending(n);
								local_0 = isExtending_3;
							}
							else {
								local_0 = false;
							}
							local_1 = local_0;
						}
						local_2 = local_1;
					}
					local_3 = local_2;
				}
				local_4 = local_3;
			}
			local_5 = local_4;
		}
		return local_5;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException
	{
		switch (operationID) {
			case tdlPackage.PACKAGEABLE_ELEMENT___CONFORMS_TO__STRING:
				return conformsTo((String)arguments.get(0));
			case tdlPackage.PACKAGEABLE_ELEMENT___GET_ELEMENT_NAMED__STRING:
				return getElementNamed((String)arguments.get(0));
			case tdlPackage.PACKAGEABLE_ELEMENT___CONFORMS_TO__PACKAGEABLEELEMENT:
				return conformsTo((PackageableElement)arguments.get(0));
		}
		return super.eInvoke(operationID, arguments);
	}

} //PackageableElementImpl
