PropertiesScopeProvider.java

/**
 * Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
 * All Rights Reserved.
 * 
 * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
 * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
 * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 * 
 * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
 * 
 * This program includes and/or can make use of certain third party source code, object code, documentation and other
 * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
 * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
 * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
 * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
 * aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
 * censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
 */
package org.osate.xtext.aadl2.properties.scoping;

import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.FilteringScope;
import org.eclipse.xtext.scoping.impl.SimpleScope;
import org.eclipse.xtext.util.SimpleAttributeResolver;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osate.aadl2.Aadl2Package;
import org.osate.aadl2.BasicProperty;
import org.osate.aadl2.BasicPropertyAssociation;
import org.osate.aadl2.BehavioredImplementation;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.ComponentClassifier;
import org.osate.aadl2.ComponentImplementation;
import org.osate.aadl2.ComponentPrototype;
import org.osate.aadl2.ComponentType;
import org.osate.aadl2.ComponentTypeRename;
import org.osate.aadl2.ContainmentPathElement;
import org.osate.aadl2.Element;
import org.osate.aadl2.EnumerationLiteral;
import org.osate.aadl2.EnumerationType;
import org.osate.aadl2.Feature;
import org.osate.aadl2.FeatureGroup;
import org.osate.aadl2.FeatureGroupPrototype;
import org.osate.aadl2.FeatureGroupType;
import org.osate.aadl2.FeatureGroupTypeRename;
import org.osate.aadl2.FeatureType;
import org.osate.aadl2.InternalFeature;
import org.osate.aadl2.Mode;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.NumberType;
import org.osate.aadl2.PackageRename;
import org.osate.aadl2.PackageSection;
import org.osate.aadl2.Property;
import org.osate.aadl2.PropertyAssociation;
import org.osate.aadl2.PropertyConstant;
import org.osate.aadl2.PropertySet;
import org.osate.aadl2.PropertyType;
import org.osate.aadl2.RangeType;
import org.osate.aadl2.RecordType;
import org.osate.aadl2.ReferenceValue;
import org.osate.aadl2.RefinableElement;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.SubcomponentType;
import org.osate.aadl2.SubprogramCall;
import org.osate.aadl2.UnitsType;
import org.osate.aadl2.modelsupport.ResolvePrototypeUtil;
import org.osate.aadl2.modelsupport.util.AadlUtil;
import org.osate.aadl2.parsesupport.AObject;

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
 * on how and when to use it
 */
@SuppressWarnings("all")
public class PropertiesScopeProvider extends AbstractDeclarativeScopeProvider {
  public IScope scope_Classifier(final Element context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      IScope scope = this.delegateGetScope(context, reference);
      final ArrayList<IEObjectDescription> renameScopeElements = CollectionLiterals.<IEObjectDescription>newArrayList();
      final PackageSection packageSection = EcoreUtil2.<PackageSection>getContainerOfType(context, PackageSection.class);
      if ((packageSection != null)) {
        final Function1<ComponentTypeRename, Boolean> _function = (ComponentTypeRename it) -> {
          return Boolean.valueOf(reference.getEReferenceType().isSuperTypeOf(it.getRenamedComponentType().eClass()));
        };
        final Consumer<ComponentTypeRename> _function_1 = (ComponentTypeRename it) -> {
          String _elvis = null;
          String _name = it.getName();
          if (_name != null) {
            _elvis = _name;
          } else {
            String _name_1 = it.getRenamedComponentType().getName();
            _elvis = _name_1;
          }
          QualifiedName _create = QualifiedName.create(_elvis);
          ComponentType _renamedComponentType = it.getRenamedComponentType();
          EObjectDescription _eObjectDescription = new EObjectDescription(_create, _renamedComponentType, null);
          renameScopeElements.add(_eObjectDescription);
        };
        IterableExtensions.<ComponentTypeRename>filter(packageSection.getOwnedComponentTypeRenames(), _function).forEach(_function_1);
        boolean _isSuperTypeOf = reference.getEReferenceType().isSuperTypeOf(Aadl2Package.eINSTANCE.getFeatureGroupType());
        if (_isSuperTypeOf) {
          final Consumer<FeatureGroupTypeRename> _function_2 = (FeatureGroupTypeRename it) -> {
            String _elvis = null;
            String _name = it.getName();
            if (_name != null) {
              _elvis = _name;
            } else {
              String _name_1 = it.getRenamedFeatureGroupType().getName();
              _elvis = _name_1;
            }
            QualifiedName _create = QualifiedName.create(_elvis);
            FeatureGroupType _renamedFeatureGroupType = it.getRenamedFeatureGroupType();
            EObjectDescription _eObjectDescription = new EObjectDescription(_create, _renamedFeatureGroupType, null);
            renameScopeElements.add(_eObjectDescription);
          };
          packageSection.getOwnedFeatureGroupTypeRenames().forEach(_function_2);
        }
        final Consumer<PackageRename> _function_3 = (PackageRename packageRename) -> {
          final Function1<Classifier, Boolean> _function_4 = (Classifier it) -> {
            return Boolean.valueOf(reference.getEReferenceType().isSuperTypeOf(it.eClass()));
          };
          final Consumer<Classifier> _function_5 = (Classifier classifier) -> {
            List<String> _xifexpression = null;
            boolean _isRenameAll = packageRename.isRenameAll();
            if (_isRenameAll) {
              String _name = classifier.getName();
              _xifexpression = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList(_name));
            } else {
              String _name_1 = packageRename.getName();
              String _name_2 = classifier.getName();
              _xifexpression = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList(_name_1, _name_2));
            }
            QualifiedName _create = QualifiedName.create(_xifexpression);
            EObjectDescription _eObjectDescription = new EObjectDescription(_create, classifier, null);
            renameScopeElements.add(_eObjectDescription);
          };
          IterableExtensions.<Classifier>filter(packageRename.getRenamedPackage().getPublicSection().getOwnedClassifiers(), _function_4).forEach(_function_5);
        };
        packageSection.getOwnedPackageRenames().forEach(_function_3);
        SimpleScope _simpleScope = new SimpleScope(scope, renameScopeElements, true);
        scope = _simpleScope;
      }
      _xblockexpression = scope;
    }
    return _xblockexpression;
  }

  /**
   * Reference is from ModalPropertyValue and OptionalModalPropertyValue in Properties.xtext
   * and SubprogramCallSequence, InternalFeature, ProcessorFeature, and DefaultAnnexSubclause in Aadl2.xtext
   */
  public IScope scope_ModalElement_inMode(final Element context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      IScope scope = IScope.NULLSCOPE;
      final PropertyAssociation containingPropertyAssociation = EcoreUtil2.<PropertyAssociation>getContainerOfType(context, PropertyAssociation.class);
      if ((containingPropertyAssociation != null)) {
        boolean _isEmpty = containingPropertyAssociation.getAppliesTos().isEmpty();
        boolean _not = (!_isEmpty);
        if (_not) {
          IScope _elvis = null;
          final Function1<ContainmentPathElement, Boolean> _function = (ContainmentPathElement it) -> {
            NamedElement _namedElement = it.getNamedElement();
            return Boolean.valueOf((_namedElement instanceof Subcomponent));
          };
          NamedElement _namedElement = IterableExtensions.<ContainmentPathElement>findLast(containingPropertyAssociation.getAppliesTos().get(0).getContainmentPathElements(), _function).getNamedElement();
          ComponentClassifier _classifier = null;
          if (((Subcomponent) _namedElement)!=null) {
            _classifier=((Subcomponent) _namedElement).getClassifier();
          }
          EList<Mode> _allModes = null;
          if (_classifier!=null) {
            _allModes=_classifier.getAllModes();
          }
          SimpleScope _scopeFor = null;
          if (_allModes!=null) {
            _scopeFor=PropertiesScopeProvider.scopeFor(_allModes);
          }
          if (_scopeFor != null) {
            _elvis = _scopeFor;
          } else {
            _elvis = scope;
          }
          scope = _elvis;
        } else {
          Element _owner = containingPropertyAssociation.getOwner();
          if ((_owner instanceof Subcomponent)) {
            IScope _elvis_1 = null;
            Element _owner_1 = containingPropertyAssociation.getOwner();
            ComponentClassifier _allClassifier = ((Subcomponent) _owner_1).getAllClassifier();
            EList<Mode> _allModes_1 = null;
            if (_allClassifier!=null) {
              _allModes_1=_allClassifier.getAllModes();
            }
            SimpleScope _scopeFor_1 = null;
            if (_allModes_1!=null) {
              _scopeFor_1=PropertiesScopeProvider.scopeFor(_allModes_1);
            }
            if (_scopeFor_1 != null) {
              _elvis_1 = _scopeFor_1;
            } else {
              _elvis_1 = scope;
            }
            scope = _elvis_1;
          }
        }
      }
      boolean _equals = Objects.equal(scope, IScope.NULLSCOPE);
      if (_equals) {
        scope = PropertiesScopeProvider.scopeFor(EcoreUtil2.<ComponentClassifier>getContainerOfType(context, ComponentClassifier.class).getAllModes());
      }
      _xblockexpression = scope;
    }
    return _xblockexpression;
  }

  public IScope scope_NamedValue_namedValue(final Element context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      IScope scope = this.delegateGetScope(context, reference);
      final PropertySet ps = EcoreUtil2.<PropertySet>getContainerOfType(context, PropertySet.class);
      if ((ps != null)) {
        final Predicate<IEObjectDescription> _function = (IEObjectDescription desc) -> {
          return ((desc.getName().getSegmentCount() > 1) || (!Objects.equal(desc.getEObjectOrProxy().eContainer(), ps)));
        };
        FilteringScope _filteringScope = new FilteringScope(scope, _function);
        scope = _filteringScope;
      }
      PropertyType propertyType = null;
      BasicPropertyAssociation _containerOfType = EcoreUtil2.<BasicPropertyAssociation>getContainerOfType(context, BasicPropertyAssociation.class);
      BasicProperty _property = null;
      if (_containerOfType!=null) {
        _property=_containerOfType.getProperty();
      }
      PropertyType _propertyType = null;
      if (_property!=null) {
        _propertyType=_property.getPropertyType();
      }
      propertyType = _propertyType;
      if ((propertyType == null)) {
        PropertyConstant _containerOfType_1 = EcoreUtil2.<PropertyConstant>getContainerOfType(context, PropertyConstant.class);
        PropertyType _propertyType_1 = null;
        if (_containerOfType_1!=null) {
          _propertyType_1=_containerOfType_1.getPropertyType();
        }
        propertyType = _propertyType_1;
      }
      if ((propertyType == null)) {
        Property _containerOfType_2 = EcoreUtil2.<Property>getContainerOfType(context, Property.class);
        PropertyType _propertyType_2 = null;
        if (_containerOfType_2!=null) {
          _propertyType_2=_containerOfType_2.getPropertyType();
        }
        propertyType = _propertyType_2;
      }
      if ((propertyType == null)) {
        PropertyAssociation _containerOfType_3 = EcoreUtil2.<PropertyAssociation>getContainerOfType(context, PropertyAssociation.class);
        Property _property_1 = null;
        if (_containerOfType_3!=null) {
          _property_1=_containerOfType_3.getProperty();
        }
        PropertyType _propertyType_3 = null;
        if (_property_1!=null) {
          _propertyType_3=_property_1.getPropertyType();
        }
        propertyType = _propertyType_3;
      }
      propertyType = AadlUtil.getBasePropertyType(propertyType);
      if ((propertyType instanceof EnumerationType)) {
        scope = PropertiesScopeProvider.scopeFor(((EnumerationType)propertyType).getOwnedLiterals(), scope);
      }
      _xblockexpression = scope;
    }
    return _xblockexpression;
  }

  public IScope scope_BasicPropertyAssociation_property(final Element context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      Element _switchResult = null;
      boolean _matched = false;
      if (context instanceof BasicPropertyAssociation) {
        _matched=true;
        _switchResult = ((BasicPropertyAssociation)context).getOwner();
      }
      if (!_matched) {
        _switchResult = context;
      }
      Element parent = _switchResult;
      while (((parent != null) && (!((((parent instanceof BasicPropertyAssociation) || (parent instanceof PropertyAssociation)) || (parent instanceof Property)) || (parent instanceof PropertyConstant))))) {
        parent = parent.getOwner();
      }
      PropertyType propertyType = null;
      boolean _matched_1 = false;
      if (parent instanceof BasicPropertyAssociation) {
        _matched_1=true;
        BasicProperty _property = ((BasicPropertyAssociation)parent).getProperty();
        PropertyType _propertyType = null;
        if (_property!=null) {
          _propertyType=_property.getPropertyType();
        }
        propertyType = _propertyType;
      }
      if (!_matched_1) {
        if (parent instanceof PropertyAssociation) {
          _matched_1=true;
          Property _property = ((PropertyAssociation)parent).getProperty();
          PropertyType _propertyType = null;
          if (_property!=null) {
            _propertyType=_property.getPropertyType();
          }
          propertyType = _propertyType;
        }
      }
      if (!_matched_1) {
        if (parent instanceof Property) {
          _matched_1=true;
          propertyType = ((Property)parent).getPropertyType();
        }
      }
      if (!_matched_1) {
        if (parent instanceof PropertyConstant) {
          _matched_1=true;
          propertyType = ((PropertyConstant)parent).getPropertyType();
        }
      }
      propertyType = AadlUtil.getBasePropertyType(propertyType);
      IScope _xifexpression = null;
      if ((propertyType instanceof RecordType)) {
        _xifexpression = PropertiesScopeProvider.scopeFor(((RecordType)propertyType).getOwnedFields());
      } else {
        _xifexpression = IScope.NULLSCOPE;
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }

  public IScope scope_ContainmentPathElement_namedElement(final Element context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      Classifier _switchResult = null;
      boolean _matched = false;
      if (context instanceof ReferenceValue) {
        _matched=true;
        PropertyAssociation _containerOfType = EcoreUtil2.<PropertyAssociation>getContainerOfType(context, PropertyAssociation.class);
        Classifier _namespaceForPropertyAssociation = null;
        if (_containerOfType!=null) {
          _namespaceForPropertyAssociation=PropertiesScopeProvider.namespaceForPropertyAssociation(_containerOfType);
        }
        _switchResult = _namespaceForPropertyAssociation;
      }
      if (!_matched) {
        if (context instanceof PropertyAssociation) {
          _matched=true;
          _switchResult = PropertiesScopeProvider.namespaceForPropertyAssociation(((PropertyAssociation)context));
        }
      }
      if (!_matched) {
        if (context instanceof ContainmentPathElement) {
          _matched=true;
          Classifier _xifexpression = null;
          if (((((ContainmentPathElement)context).getNamedElement() == null) || ((ContainmentPathElement)context).getNamedElement().eIsProxy())) {
            Classifier _xifexpression_1 = null;
            Element _owner = ((ContainmentPathElement)context).getOwner();
            if ((_owner instanceof ReferenceValue)) {
              PropertyAssociation _containerOfType = EcoreUtil2.<PropertyAssociation>getContainerOfType(context, PropertyAssociation.class);
              Classifier _namespaceForPropertyAssociation = null;
              if (_containerOfType!=null) {
                _namespaceForPropertyAssociation=PropertiesScopeProvider.namespaceForPropertyAssociation(_containerOfType);
              }
              _xifexpression_1 = _namespaceForPropertyAssociation;
            } else {
              Classifier _xifexpression_2 = null;
              Element _owner_1 = ((ContainmentPathElement)context).getOwner().getOwner();
              if ((_owner_1 instanceof PropertyAssociation)) {
                Element _owner_2 = ((ContainmentPathElement)context).getOwner().getOwner();
                _xifexpression_2 = PropertiesScopeProvider.namespaceForPropertyAssociation(((PropertyAssociation) _owner_2));
              } else {
                Classifier _xifexpression_3 = null;
                Element _owner_3 = ((ContainmentPathElement)context).getOwner();
                if ((_owner_3 instanceof ContainmentPathElement)) {
                  Element _owner_4 = ((ContainmentPathElement)context).getOwner();
                  _xifexpression_3 = PropertiesScopeProvider.getClassifierForPreviousContainmentPathElement(((ContainmentPathElement) _owner_4));
                }
                _xifexpression_2 = _xifexpression_3;
              }
              _xifexpression_1 = _xifexpression_2;
            }
            _xifexpression = _xifexpression_1;
          } else {
            _xifexpression = PropertiesScopeProvider.getClassifierForPreviousContainmentPathElement(((ContainmentPathElement)context));
          }
          _switchResult = _xifexpression;
        }
      }
      final Classifier namespace = _switchResult;
      IScope _elvis = null;
      ArrayList<NamedElement> _allMembers = null;
      if (namespace!=null) {
        _allMembers=PropertiesScopeProvider.allMembers(namespace);
      }
      Iterable<NamedElement> _filterRefined = null;
      if (_allMembers!=null) {
        _filterRefined=PropertiesScopeProvider.<NamedElement>filterRefined(_allMembers);
      }
      SimpleScope _scopeFor = null;
      if (_filterRefined!=null) {
        _scopeFor=PropertiesScopeProvider.scopeFor(_filterRefined);
      }
      if (_scopeFor != null) {
        _elvis = _scopeFor;
      } else {
        _elvis = IScope.NULLSCOPE;
      }
      _xblockexpression = _elvis;
    }
    return _xblockexpression;
  }

  public IScope scope_NumberValue_unit(final NumberType context, final EReference reference) {
    IScope _elvis = null;
    UnitsType _unitsType = context.getUnitsType();
    EList<EnumerationLiteral> _ownedLiterals = null;
    if (_unitsType!=null) {
      _ownedLiterals=_unitsType.getOwnedLiterals();
    }
    SimpleScope _scopeFor = null;
    if (_ownedLiterals!=null) {
      _scopeFor=PropertiesScopeProvider.scopeFor(_ownedLiterals);
    }
    if (_scopeFor != null) {
      _elvis = _scopeFor;
    } else {
      _elvis = IScope.NULLSCOPE;
    }
    return _elvis;
  }

  public IScope scope_NumberValue_unit(final PropertyConstant context, final EReference reference) {
    return PropertiesScopeProvider.createUnitLiteralsScopeFromPropertyType(context.getPropertyType());
  }

  public IScope scope_NumberValue_unit(final Property context, final EReference reference) {
    return PropertiesScopeProvider.createUnitLiteralsScopeFromPropertyType(context.getPropertyType());
  }

  public IScope scope_NumberValue_unit(final PropertyAssociation context, final EReference reference) {
    return PropertiesScopeProvider.createUnitLiteralsScopeFromPropertyType(context.getProperty().getPropertyType());
  }

  public IScope scope_NumberValue_unit(final BasicPropertyAssociation context, final EReference reference) {
    return PropertiesScopeProvider.createUnitLiteralsScopeFromPropertyType(context.getProperty().getPropertyType());
  }

  protected static SimpleScope scopeFor(final Iterable<? extends EObject> elements) {
    return PropertiesScopeProvider.scopeFor(elements, IScope.NULLSCOPE);
  }

  protected static SimpleScope scopeFor(final Iterable<? extends EObject> elements, final IScope outer) {
    Iterable<IEObjectDescription> _scopedElementsFor = Scopes.<EObject>scopedElementsFor(elements, QualifiedName.<EObject>wrapper(SimpleAttributeResolver.NAME_RESOLVER));
    return new SimpleScope(outer, _scopedElementsFor, true);
  }

  protected static <T extends EObject> SimpleScope scopeFor(final Iterable<? extends T> elements, final Function1<? super T, ? extends QualifiedName> nameComputation, final IScope outer) {
    Iterable<IEObjectDescription> _scopedElementsFor = Scopes.<T>scopedElementsFor(elements, new Function<T, QualifiedName>() {
        public QualifiedName apply(T arg0) {
          return nameComputation.apply(arg0);
        }
    });
    return new SimpleScope(outer, _scopedElementsFor, true);
  }

  protected static <T extends AObject> Iterable<T> filterRefined(final Iterable<T> unfiltered) {
    final Function1<T, Boolean> _function = (T member) -> {
      boolean _xifexpression = false;
      if ((member instanceof RefinableElement)) {
        final Function1<RefinableElement, Boolean> _function_1 = (RefinableElement it) -> {
          RefinableElement _refinedElement = it.getRefinedElement();
          return Boolean.valueOf(Objects.equal(_refinedElement, member));
        };
        boolean _exists = IterableExtensions.<RefinableElement>exists(Iterables.<RefinableElement>filter(unfiltered, RefinableElement.class), _function_1);
        _xifexpression = (!_exists);
      } else {
        _xifexpression = true;
      }
      return Boolean.valueOf(_xifexpression);
    };
    return IterableExtensions.<T>filter(unfiltered, _function);
  }

  protected static ArrayList<SubprogramCall> allSubprogramCalls(final BehavioredImplementation implementation) {
    ArrayList<SubprogramCall> _xblockexpression = null;
    {
      final ArrayList<SubprogramCall> allSubprogramCalls = CollectionLiterals.<SubprogramCall>newArrayList();
      for (ComponentImplementation currentImplementation = implementation; (currentImplementation != null); currentImplementation = currentImplementation.getExtended()) {
        if ((currentImplementation instanceof BehavioredImplementation)) {
          allSubprogramCalls.addAll(((BehavioredImplementation)currentImplementation).subprogramCalls());
        }
      }
      _xblockexpression = allSubprogramCalls;
    }
    return _xblockexpression;
  }

  protected static FeatureType allFeatureType(final FeatureGroup featureGroup) {
    FeatureType _xblockexpression = null;
    {
      FeatureGroup refinedFeatureGroup = featureGroup;
      while (((refinedFeatureGroup.getFeatureType() == null) && (refinedFeatureGroup.getRefined() instanceof FeatureGroup))) {
        Feature _refined = refinedFeatureGroup.getRefined();
        refinedFeatureGroup = ((FeatureGroup) _refined);
      }
      _xblockexpression = refinedFeatureGroup.getFeatureType();
    }
    return _xblockexpression;
  }

  protected static SubcomponentType allSubcomponentType(final Subcomponent subcomponent) {
    SubcomponentType _xblockexpression = null;
    {
      Subcomponent refinedSubcomponent = subcomponent;
      while (((refinedSubcomponent.getSubcomponentType() == null) && (refinedSubcomponent.getRefined() != null))) {
        refinedSubcomponent = refinedSubcomponent.getRefined();
      }
      _xblockexpression = refinedSubcomponent.getSubcomponentType();
    }
    return _xblockexpression;
  }

  protected static ArrayList<InternalFeature> allInternalFeatures(final ComponentImplementation implementation) {
    ArrayList<InternalFeature> _xblockexpression = null;
    {
      final ArrayList<InternalFeature> allInternalFeatures = CollectionLiterals.<InternalFeature>newArrayList();
      for (ComponentImplementation currentImplementation = implementation; (currentImplementation != null); currentImplementation = currentImplementation.getExtended()) {
        allInternalFeatures.addAll(currentImplementation.getOwnedInternalFeatures());
      }
      _xblockexpression = allInternalFeatures;
    }
    return _xblockexpression;
  }

  public static ArrayList<NamedElement> allMembers(final Classifier classifier) {
    ArrayList<NamedElement> _xblockexpression = null;
    {
      final ArrayList<NamedElement> allMembers = CollectionLiterals.<NamedElement>newArrayList();
      allMembers.addAll(classifier.getMembers());
      if ((classifier instanceof BehavioredImplementation)) {
        allMembers.addAll(PropertiesScopeProvider.allSubprogramCalls(((BehavioredImplementation)classifier)));
      }
      _xblockexpression = allMembers;
    }
    return _xblockexpression;
  }

  protected static IScope createUnitLiteralsScopeFromPropertyType(final PropertyType type) {
    IScope _elvis = null;
    UnitsType _switchResult = null;
    PropertyType _basePropertyType = AadlUtil.getBasePropertyType(type);
    final PropertyType baseType = _basePropertyType;
    boolean _matched = false;
    if (baseType instanceof NumberType) {
      _matched=true;
      _switchResult = ((NumberType)baseType).getUnitsType();
    }
    if (!_matched) {
      if (baseType instanceof RangeType) {
        _matched=true;
        _switchResult = ((RangeType)baseType).getNumberType().getUnitsType();
      }
    }
    EList<EnumerationLiteral> _ownedLiterals = null;
    if (_switchResult!=null) {
      _ownedLiterals=_switchResult.getOwnedLiterals();
    }
    SimpleScope _scopeFor = null;
    if (_ownedLiterals!=null) {
      _scopeFor=PropertiesScopeProvider.scopeFor(_ownedLiterals);
    }
    if (_scopeFor != null) {
      _elvis = _scopeFor;
    } else {
      _elvis = IScope.NULLSCOPE;
    }
    return _elvis;
  }

  /**
   * @since 1.1
   */
  protected static Classifier namespaceForPropertyAssociation(final PropertyAssociation propertyAssociation) {
    Classifier _switchResult = null;
    Element _owner = propertyAssociation.getOwner();
    final Element container = _owner;
    boolean _matched = false;
    if (container instanceof FeatureGroup) {
      _matched=true;
      FeatureGroupType _switchResult_1 = null;
      FeatureType _allFeatureType = PropertiesScopeProvider.allFeatureType(((FeatureGroup)container));
      final FeatureType featureType = _allFeatureType;
      boolean _matched_1 = false;
      if (featureType instanceof FeatureGroupType) {
        _matched_1=true;
        _switchResult_1 = ((FeatureGroupType)featureType);
      }
      if (!_matched_1) {
        if (featureType instanceof FeatureGroupPrototype) {
          _matched_1=true;
          _switchResult_1 = ResolvePrototypeUtil.resolveFeatureGroupPrototype(((FeatureGroupPrototype)featureType), EcoreUtil2.<Classifier>getContainerOfType(propertyAssociation, Classifier.class));
        }
      }
      _switchResult = _switchResult_1;
    }
    if (!_matched) {
      if (container instanceof Subcomponent) {
        _matched=true;
        ComponentClassifier _switchResult_1 = null;
        SubcomponentType _allSubcomponentType = PropertiesScopeProvider.allSubcomponentType(((Subcomponent)container));
        final SubcomponentType subcomponentType = _allSubcomponentType;
        boolean _matched_1 = false;
        if (subcomponentType instanceof ComponentClassifier) {
          _matched_1=true;
          _switchResult_1 = ((ComponentClassifier)subcomponentType);
        }
        if (!_matched_1) {
          if (subcomponentType instanceof ComponentPrototype) {
            _matched_1=true;
            _switchResult_1 = ResolvePrototypeUtil.resolveComponentPrototype(((ComponentPrototype)subcomponentType), EcoreUtil2.<Classifier>getContainerOfType(propertyAssociation, Classifier.class));
          }
        }
        _switchResult = _switchResult_1;
      }
    }
    if (!_matched) {
      _switchResult = EcoreUtil2.<Classifier>getContainerOfType(container, Classifier.class);
    }
    return _switchResult;
  }

  /**
   * @since 1.1
   */
  protected static Classifier getClassifierForPreviousContainmentPathElement(final ContainmentPathElement previousCpe) {
    Classifier _switchResult = null;
    NamedElement _namedElement = previousCpe.getNamedElement();
    final NamedElement previousElement = _namedElement;
    boolean _matched = false;
    if (Objects.equal(previousElement, null)) {
      _matched=true;
    }
    if (!_matched) {
      boolean _eIsProxy = previousElement.eIsProxy();
      if (_eIsProxy) {
        _matched=true;
      }
    }
    if (_matched) {
      _switchResult = null;
    }
    if (!_matched) {
      if (previousElement instanceof Subcomponent) {
        _matched=true;
        ComponentClassifier _switchResult_1 = null;
        SubcomponentType _allSubcomponentType = PropertiesScopeProvider.allSubcomponentType(((Subcomponent)previousElement));
        final SubcomponentType subcomponentType = _allSubcomponentType;
        boolean _matched_1 = false;
        if (subcomponentType instanceof ComponentClassifier) {
          _matched_1=true;
          _switchResult_1 = ((ComponentClassifier)subcomponentType);
        }
        if (!_matched_1) {
          if (subcomponentType instanceof ComponentPrototype) {
            _matched_1=true;
            _switchResult_1 = ResolvePrototypeUtil.resolveComponentPrototype(((ComponentPrototype)subcomponentType), previousCpe);
          }
        }
        _switchResult = _switchResult_1;
      }
    }
    if (!_matched) {
      if (previousElement instanceof FeatureGroup) {
        _matched=true;
        FeatureGroupType _switchResult_1 = null;
        FeatureType _allFeatureType = PropertiesScopeProvider.allFeatureType(((FeatureGroup)previousElement));
        final FeatureType featureType = _allFeatureType;
        boolean _matched_1 = false;
        if (featureType instanceof FeatureGroupType) {
          _matched_1=true;
          _switchResult_1 = ((FeatureGroupType)featureType);
        }
        if (!_matched_1) {
          if (featureType instanceof FeatureGroupPrototype) {
            _matched_1=true;
            _switchResult_1 = ResolvePrototypeUtil.resolveFeatureGroupPrototype(((FeatureGroupPrototype)featureType), previousCpe);
          }
        }
        _switchResult = _switchResult_1;
      }
    }
    return _switchResult;
  }
}