AadlPropertyView.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.ui.propertyview;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.resource.EObjectAtOffsetHelper;
import org.eclipse.xtext.resource.SaveOptions;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.serializer.ISerializer;
import org.eclipse.xtext.ui.editor.IURIEditorOpener;
import org.eclipse.xtext.ui.editor.XtextEditor;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.model.IXtextModelListener;
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure0;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.osate.aadl2.Aadl2Factory;
import org.osate.aadl2.AadlPackage;
import org.osate.aadl2.BasicProperty;
import org.osate.aadl2.BasicPropertyAssociation;
import org.osate.aadl2.BehavioralFeature;
import org.osate.aadl2.Classifier;
import org.osate.aadl2.ContainedNamedElement;
import org.osate.aadl2.ContainmentPathElement;
import org.osate.aadl2.Element;
import org.osate.aadl2.Feature;
import org.osate.aadl2.ListValue;
import org.osate.aadl2.ModalPath;
import org.osate.aadl2.ModalPropertyValue;
import org.osate.aadl2.ModeFeature;
import org.osate.aadl2.ModelUnit;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.PackageSection;
import org.osate.aadl2.Property;
import org.osate.aadl2.PropertyAssociation;
import org.osate.aadl2.PropertyConstant;
import org.osate.aadl2.PropertyExpression;
import org.osate.aadl2.PropertySet;
import org.osate.aadl2.PropertyType;
import org.osate.aadl2.Prototype;
import org.osate.aadl2.RangeValue;
import org.osate.aadl2.RecordValue;
import org.osate.aadl2.RefinableElement;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.instance.PropertyAssociationInstance;
import org.osate.aadl2.modelsupport.EObjectURIWrapper;
import org.osate.aadl2.modelsupport.util.AadlUtil;
import org.osate.xtext.aadl2.serializer.InstanceEnabledSerializerBinding;
import org.osate.xtext.aadl2.ui.MyAadl2Activator;

/**
 * View that displays the AADL property value associations within a given AADL
 * model element.
 */
@SuppressWarnings("all")
public class AadlPropertyView extends ViewPart {
  private static final String HIDE_UNDEFINED_TOOL_TIP = "Hide undefined properties";

  private static final String SHOW_UNDEFINED_TOOL_TIP = "Show undefined properties";

  private static final String COLLAPSE_ALL_TOOL_TIP = "Collapse All";

  private static final String SHOW_ONLY_IMPORTED_PROPERTIES = "Show imported properties only";

  private static final String SHOW_ALL_AVAILABLE_PROPERTIES = "Show all available properties";

  private static final String HIDE_DEFAULT_TOOL_TIP = "Hide default property values";

  private static final String SHOW_DEFAULT_TOOL_TIP = "Show default property values";

  private static final String NO_PROPERTIES_TO_SHOW = "No properties to show: Please select a single AADL element that can have properties.";

  private static final String POPULATING_VIEW = "Populating AADL Property Values view.";

  /**
   * Page book for switching between the tree viewer and the "no properties"
   * message.
   */
  private PageBook pageBook = null;

  /**
   * Tree for displaying properties. Underlying model is a
   * {@link List} of {@link PropertySet} objects.
   */
  TreeViewer treeViewer = null;

  private Composite treeViewerComposite = null;

  /**
   * The label for the no results message.
   */
  private Label noPropertiesLabel = null;

  private Label populatingViewLabel = null;

  /**
   * Action for toggling the display of nonexistent properties
   */
  Action showUndefinedAction = null;

  Action showDefaultAction = null;

  private Action removeElementAction = null;

  private Action openDefinitionAction = null;

  private Action openPropertyAssociationAction = null;

  private Action makeLocalAction = null;

  private Action makeLocalContainedAction = null;

  private Action createLocalAssociationAction = null;

  boolean nextEditIsLocalCreation = false;

  private Action createLocalContainedAssociationAction = null;

  boolean nextEditIsLocalContainedCreation = false;

  private Action showOnlyImportedPropertiesAction;

  /**
   * The editing domain for the viewer's input
   */
  private EditingDomain editingDomain = null;

  IXtextDocument xtextDocument = null;

  Resource resourceFromSelection;

  /**
   * Only show properties from this group (or all properties if empty)
   */
  private ArrayList<FilterCriterion> currentPropertyGroup = new ArrayList<FilterCriterion>();

  @Inject
  @InstanceEnabledSerializerBinding
  ISerializer serializer;

  @Inject
  private IScopeProvider scopeProvider;

  @Inject
  private IURIEditorOpener editorOpener;

  private URI previousSelectionURI = null;

  private CachePropertyLookupJob cachePropertyLookupJob = null;

  private final Object jobLock = new Object();

  final Map<URI, Map<URI, URI>> cachedPropertyAssociations = Collections.<URI, Map<URI, URI>>synchronizedMap(CollectionLiterals.<URI, Map<URI, URI>>newLinkedHashMap());

  private ArrayList<FilterCriterion> importedPropertyGroups = new ArrayList<FilterCriterion>();

  private Set<URI> filteredPropertySets;

  private final ISelectionListener selectionListener = ((ISelectionListener) (IWorkbenchPart part, ISelection selection) -> {
    this.updateSelection(part, selection);
  });

  private final IPartListener partListener = new IPartListener() {
    @Override
    public void partOpened(final IWorkbenchPart part) {
    }

    @Override
    public void partDeactivated(final IWorkbenchPart part) {
      if ((part instanceof XtextEditor)) {
        final ISelectionProvider selectionProvider = ((XtextEditor)part).getInternalSourceViewer().getSelectionProvider();
        if ((selectionProvider instanceof IPostSelectionProvider)) {
          ((IPostSelectionProvider)selectionProvider).removePostSelectionChangedListener(AadlPropertyView.this.selectionChangedListener);
        }
      }
    }

    @Override
    public void partClosed(final IWorkbenchPart part) {
      if (((part instanceof XtextEditor) && (AadlPropertyView.this.xtextDocument == ((XtextEditor) part).getDocument()))) {
        AadlPropertyView.this.xtextDocument = null;
      }
    }

    @Override
    public void partBroughtToTop(final IWorkbenchPart part) {
    }

    @Override
    public void partActivated(final IWorkbenchPart part) {
      if ((part instanceof XtextEditor)) {
        final ISelectionProvider selectionProvider = ((XtextEditor)part).getInternalSourceViewer().getSelectionProvider();
        if ((selectionProvider instanceof IPostSelectionProvider)) {
          ((IPostSelectionProvider)selectionProvider).addPostSelectionChangedListener(AadlPropertyView.this.selectionChangedListener);
        }
      }
    }
  };

  private final ISelectionChangedListener selectionChangedListener = ((ISelectionChangedListener) (SelectionChangedEvent it) -> {
    final IEditorPart editor = this.getSite().getWorkbenchWindow().getActivePage().getActiveEditor();
    if ((editor instanceof XtextEditor)) {
      this.updateSelection(editor, it.getSelection());
    }
  });

  private boolean modelListenerEnabled = true;

  private final IXtextModelListener xtextModelListener = ((IXtextModelListener) (XtextResource it) -> {
    if (this.modelListenerEnabled) {
      this.runCachePropertyLookupJob(this.getInput(), null);
    }
  });

  @Override
  public void createPartControl(final Composite parent) {
    abstract class __AadlPropertyView_2 extends PatternFilter {
      public abstract boolean anyChildrenMatch(final TreeViewer thisTree, final Object element);

      public abstract boolean isMatch(final String elementName, final String parentName);
    }

    PageBook _pageBook = new PageBook(parent, SWT.NULL);
    this.pageBook = _pageBook;
    Label _label = new Label(this.pageBook, SWT.LEFT);
    final Procedure1<Label> _function = (Label it) -> {
      it.setText(AadlPropertyView.NO_PROPERTIES_TO_SHOW);
      it.setAlignment(SWT.CENTER);
      it.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
    };
    Label _doubleArrow = ObjectExtensions.<Label>operator_doubleArrow(_label, _function);
    this.noPropertiesLabel = _doubleArrow;
    Label _label_1 = new Label(this.pageBook, SWT.LEFT);
    final Procedure1<Label> _function_1 = (Label it) -> {
      it.setText(AadlPropertyView.POPULATING_VIEW);
      it.setAlignment(SWT.CENTER);
      it.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
    };
    Label _doubleArrow_1 = ObjectExtensions.<Label>operator_doubleArrow(_label_1, _function_1);
    this.populatingViewLabel = _doubleArrow_1;
    Composite _composite = new Composite(this.pageBook, SWT.NULL);
    final Procedure1<Composite> _function_2 = (Composite it) -> {
      final __AadlPropertyView_2 patternFilter = new __AadlPropertyView_2() {
        @Override
        protected boolean isLeafMatch(final Viewer viewer, final Object element) {
          TreeViewer thisTree = ((TreeViewer) viewer);
          CellLabelProvider _labelProvider = thisTree.getLabelProvider(0);
          final ColumnLabelProvider labelProvider = ((ColumnLabelProvider) _labelProvider);
          IContentProvider _contentProvider = thisTree.getContentProvider();
          final ITreeContentProvider contentProvider = ((ITreeContentProvider) _contentProvider);
          Object current = element;
          Object parent = contentProvider.getParent(element);
          while ((contentProvider.getParent(parent) instanceof TreeEntry)) {
            {
              current = parent;
              parent = contentProvider.getParent(parent);
            }
          }
          String _elvis = null;
          String _text = labelProvider.getText(parent);
          if (_text != null) {
            _elvis = _text;
          } else {
            _elvis = "";
          }
          final String propertysetName = _elvis;
          String propertyName = labelProvider.getText(current);
          return (this.wordMatches(propertyName) && ((AadlPropertyView.this.currentPropertyGroup.size() == 0) || this.isMatch(propertyName, propertysetName)));
        }

        @Override
        protected boolean isParentMatch(final Viewer viewer, final Object element) {
          return this.anyChildrenMatch(((TreeViewer) viewer), element);
        }

        public boolean anyChildrenMatch(final TreeViewer thisTree, final Object element) {
          IContentProvider _contentProvider = thisTree.getContentProvider();
          final ITreeContentProvider contentProvider = ((ITreeContentProvider) _contentProvider);
          final Object[] children = contentProvider.getChildren(element);
          boolean match = false;
          if (((children != null) && (children.length > 0))) {
            for (int i = 0; ((i < children.length) && (!match)); i++) {
              match = this.anyChildrenMatch(thisTree, children[i]);
            }
          } else {
            match = this.isLeafMatch(thisTree, element);
          }
          return match;
        }

        public boolean isMatch(final String elementName, final String parentName) {
          for (final FilterCriterion e : AadlPropertyView.this.currentPropertyGroup) {
            if (((e.getParent() == null) && Objects.equal(elementName, ((String) e.getElement())))) {
              return true;
            } else {
              if ((Objects.equal(parentName, ((String) e.getParent())) && Objects.equal(elementName, ((String) e.getElement())))) {
                return true;
              }
            }
          }
          return false;
        }
      };
      patternFilter.setPattern("org.eclipse.ui.keys.optimization.false");
      final TreeColumnLayout treeColumnLayout = new TreeColumnLayout();
      final FilteredTree filteredTree = new FilteredTree(it, (SWT.BORDER | SWT.FULL_SELECTION), patternFilter, true) {
        @Override
        public TreeViewer doCreateTreeViewer(final Composite parent, final int style) {
          final TreeViewer c = super.doCreateTreeViewer(parent, style);
          c.getControl().setLayoutData(null);
          parent.setLayout(treeColumnLayout);
          return c;
        }
      };
      GridLayout _gridLayout = new GridLayout();
      it.setLayout(_gridLayout);
      final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
      filteredTree.setLayoutData(gd);
      this.treeViewer = filteredTree.getViewer();
      final Procedure1<TreeViewer> _function_3 = (TreeViewer treeViewer) -> {
        TreeViewerColumn _treeViewerColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
        final Procedure1<TreeViewerColumn> _function_4 = (TreeViewerColumn it_1) -> {
          TreeColumn _column = it_1.getColumn();
          _column.setText("Property");
          TreeColumn _column_1 = it_1.getColumn();
          ColumnWeightData _columnWeightData = new ColumnWeightData(1, true);
          treeColumnLayout.setColumnData(_column_1, _columnWeightData);
          PropertyColumnLabelProvider _propertyColumnLabelProvider = new PropertyColumnLabelProvider(this);
          it_1.setLabelProvider(_propertyColumnLabelProvider);
        };
        ObjectExtensions.<TreeViewerColumn>operator_doubleArrow(_treeViewerColumn, _function_4);
        TreeViewerColumn _treeViewerColumn_1 = new TreeViewerColumn(treeViewer, SWT.LEFT);
        final Procedure1<TreeViewerColumn> _function_5 = (TreeViewerColumn it_1) -> {
          TreeColumn _column = it_1.getColumn();
          _column.setText("Value");
          TreeColumn _column_1 = it_1.getColumn();
          ColumnWeightData _columnWeightData = new ColumnWeightData(2, true);
          treeColumnLayout.setColumnData(_column_1, _columnWeightData);
          ValueColumnLabelProvider _valueColumnLabelProvider = new ValueColumnLabelProvider(this);
          it_1.setLabelProvider(_valueColumnLabelProvider);
          ValueColumnEditingSupport _valueColumnEditingSupport = new ValueColumnEditingSupport(treeViewer, this);
          it_1.setEditingSupport(_valueColumnEditingSupport);
        };
        ObjectExtensions.<TreeViewerColumn>operator_doubleArrow(_treeViewerColumn_1, _function_5);
        TreeViewerColumn _treeViewerColumn_2 = new TreeViewerColumn(treeViewer, SWT.LEFT);
        final Procedure1<TreeViewerColumn> _function_6 = (TreeViewerColumn it_1) -> {
          TreeColumn _column = it_1.getColumn();
          _column.setText("Status");
          Tree _parent = it_1.getColumn().getParent();
          final GC gc = new GC(_parent);
          TreeColumn _column_1 = it_1.getColumn();
          final Function1<PropertyStatus, Integer> _function_7 = (PropertyStatus it_2) -> {
            return Integer.valueOf(gc.stringExtent(it_2.toString()).x);
          };
          Integer _max = IterableExtensions.<Integer>max(ListExtensions.<PropertyStatus, Integer>map(((List<PropertyStatus>)Conversions.doWrapArray(PropertyStatus.values())), _function_7));
          int _plus = ((_max).intValue() + 5);
          ColumnPixelData _columnPixelData = new ColumnPixelData(_plus, true, true);
          treeColumnLayout.setColumnData(_column_1, _columnPixelData);
          gc.dispose();
          StatusColumnLabelProvider _statusColumnLabelProvider = new StatusColumnLabelProvider(this);
          it_1.setLabelProvider(_statusColumnLabelProvider);
        };
        ObjectExtensions.<TreeViewerColumn>operator_doubleArrow(_treeViewerColumn_2, _function_6);
        Tree _tree = treeViewer.getTree();
        _tree.setLinesVisible(true);
        Tree _tree_1 = treeViewer.getTree();
        _tree_1.setHeaderVisible(true);
        treeViewer.setUseHashlookup(true);
        PropertyViewContentProvider _propertyViewContentProvider = new PropertyViewContentProvider(this);
        treeViewer.setContentProvider(_propertyViewContentProvider);
        final ViewerFilter _function_7 = new ViewerFilter() {
          @Override
          public boolean select(final Viewer viewer, final Object parentElement, final Object element) {
            Boolean _xifexpression = null;
            if ((AadlPropertyView.this.filteredPropertySets == null)) {
              _xifexpression = Boolean.valueOf(true);
            } else {
              Boolean _xifexpression_1 = null;
              if ((element instanceof TreeEntry)) {
                Boolean _switchResult = null;
                Object _treeElement = ((TreeEntry)element).getTreeElement();
                final Object treeElement = _treeElement;
                boolean _matched = false;
                if (treeElement instanceof URI) {
                  _matched=true;
                  final Function1<ResourceSet, Boolean> _function = (ResourceSet it_1) -> {
                    boolean _switchResult_1 = false;
                    EObject _eObject = it_1.getEObject(((URI)treeElement), true);
                    final EObject eObject = _eObject;
                    boolean _matched_1 = false;
                    if (eObject instanceof PropertySet) {
                      _matched_1=true;
                      _switchResult_1 = AadlPropertyView.this.filteredPropertySets.contains(((PropertySet)eObject).eResource().getURI());
                    }
                    if (!_matched_1) {
                      _switchResult_1 = true;
                    }
                    return Boolean.valueOf(_switchResult_1);
                  };
                  _switchResult = AadlPropertyView.this.<Boolean>safeRead(_function);
                }
                if (!_matched) {
                  _switchResult = Boolean.valueOf(true);
                }
                _xifexpression_1 = _switchResult;
              } else {
                _xifexpression_1 = Boolean.valueOf(true);
              }
              _xifexpression = _xifexpression_1;
            }
            return (_xifexpression).booleanValue();
          }
        };
        treeViewer.addFilter(_function_7);
      };
      ObjectExtensions.<TreeViewer>operator_doubleArrow(
        this.treeViewer, _function_3);
    };
    Composite _doubleArrow_2 = ObjectExtensions.<Composite>operator_doubleArrow(_composite, _function_2);
    this.treeViewerComposite = _doubleArrow_2;
    this.pageBook.showPage(this.noPropertiesLabel);
    this.getSite().getPage().addSelectionListener(this.selectionListener);
    this.getSite().getPage().addPartListener(this.partListener);
    final IEditorPart editor = this.getSite().getPage().getActiveEditor();
    if ((editor instanceof XtextEditor)) {
      final ISelectionProvider editorSelectionProvider = ((XtextEditor)editor).getInternalSourceViewer().getSelectionProvider();
      if ((editorSelectionProvider instanceof IPostSelectionProvider)) {
        ((IPostSelectionProvider)editorSelectionProvider).addPostSelectionChangedListener(this.selectionChangedListener);
      }
    }
    this.createActions();
    this.createContextMenu();
  }

  @Override
  public void dispose() {
    synchronized (this.jobLock) {
      if ((this.cachePropertyLookupJob != null)) {
        this.cachePropertyLookupJob.cancel();
        this.cachePropertyLookupJob = null;
      }
    }
    this.getSite().getPage().removeSelectionListener(this.selectionListener);
    this.getSite().getPage().removePartListener(this.partListener);
    final IEditorPart editor = this.getSite().getPage().getActiveEditor();
    if ((editor instanceof XtextEditor)) {
      final ISelectionProvider editorSelectionProvider = ((XtextEditor)editor).getInternalSourceViewer().getSelectionProvider();
      if ((editorSelectionProvider instanceof IPostSelectionProvider)) {
        ((IPostSelectionProvider)editorSelectionProvider).removePostSelectionChangedListener(this.selectionChangedListener);
      }
    }
    if (this.xtextDocument!=null) {
      this.xtextDocument.removeModelListener(this.xtextModelListener);
    }
    super.dispose();
  }

  @Override
  public void setFocus() {
    this.treeViewer.getTree().setFocus();
  }

  boolean canEdit(final Object element) {
    Boolean _xifexpression = null;
    if (((this.xtextDocument == null) && (!(this.resourceFromSelection instanceof XtextResource)))) {
      _xifexpression = Boolean.valueOf(false);
    } else {
      final Function1<ResourceSet, Boolean> _function = (ResourceSet it) -> {
        boolean _switchResult = false;
        Object _treeElement = ((TreeEntry) element).getTreeElement();
        final Object treeElement = _treeElement;
        boolean _matched = false;
        if (treeElement instanceof URI) {
          _matched=true;
          boolean _switchResult_1 = false;
          EObject _eObject = it.getEObject(((URI)treeElement), true);
          final EObject treeElementEObject = _eObject;
          boolean _matched_1 = false;
          if (treeElementEObject instanceof Property) {
            _matched_1=true;
            boolean _xblockexpression = false;
            {
              Object _parent = ((TreeEntry) element).getParent();
              final URI associationURI = this.cachedPropertyAssociations.get(
                ((TreeEntry) _parent).getTreeElement()).get(treeElement);
              _xblockexpression = (this.getPropertyStatusNeverUndefined(associationURI).isEditable() && 
                (!((PropertyAssociation) it.getEObject(associationURI, true)).isModal()));
            }
            _switchResult_1 = _xblockexpression;
          }
          if (!_matched_1) {
            if (treeElementEObject instanceof BasicPropertyAssociation) {
              _matched_1=true;
              boolean _xblockexpression = false;
              {
                final PropertyAssociation containingAssociation = EcoreUtil2.<PropertyAssociation>getContainerOfType(treeElementEObject, PropertyAssociation.class);
                _xblockexpression = (this.getPropertyStatusNeverUndefined(it, containingAssociation).isEditable() && 
                  (!containingAssociation.isModal()));
              }
              _switchResult_1 = _xblockexpression;
            }
          }
          if (!_matched_1) {
            _switchResult_1 = false;
          }
          _switchResult = _switchResult_1;
        }
        if (!_matched) {
          if (treeElement instanceof RangeElement) {
            _matched=true;
            boolean _xblockexpression = false;
            {
              EObject _eObject = it.getEObject(((RangeElement)treeElement).getExpressionURI(), true);
              final PropertyAssociation containingAssociation = EcoreUtil2.<PropertyAssociation>getContainerOfType(((PropertyExpression) _eObject), PropertyAssociation.class);
              _xblockexpression = (this.getPropertyStatusNeverUndefined(it, containingAssociation).isEditable() && 
                (!containingAssociation.isModal()));
            }
            _switchResult = _xblockexpression;
          }
        }
        if (!_matched) {
          if (treeElement instanceof ListElement) {
            _matched=true;
            boolean _xblockexpression = false;
            {
              EObject _eObject = it.getEObject(((ListElement)treeElement).getExpressionURI(), true);
              final PropertyAssociation containingAssociation = EcoreUtil2.<PropertyAssociation>getContainerOfType(((PropertyExpression) _eObject), PropertyAssociation.class);
              _xblockexpression = (this.getPropertyStatusNeverUndefined(it, containingAssociation).isEditable() && 
                (!containingAssociation.isModal()));
            }
            _switchResult = _xblockexpression;
          }
        }
        if (!_matched) {
          _switchResult = false;
        }
        return Boolean.valueOf(_switchResult);
      };
      _xifexpression = this.<Boolean>safeRead(_function);
    }
    return (_xifexpression).booleanValue();
  }

  URI getInput() {
    Object _input = this.treeViewer.getInput();
    return ((URI) _input);
  }

  private Action createActions() {
    Action _xblockexpression = null;
    {
      final Procedure1<Action> _function = (Action it) -> {
        it.setImageDescriptor(MyAadl2Activator.getImageDescriptor("icons/propertyview/collapseall.gif"));
        this.getViewSite().getActionBars().getToolBarManager().add(it);
        it.setToolTipText(AadlPropertyView.COLLAPSE_ALL_TOOL_TIP);
      };
      ObjectExtensions.<Action>operator_doubleArrow(
        new Action("Collapse All") {
          @Override
          public void run() {
            AadlPropertyView.this.treeViewer.collapseAll();
          }
        }, _function);
      final Procedure1<Action> _function_1 = (Action it) -> {
        it.setEnabled(false);
        it.setImageDescriptor(MyAadl2Activator.getImageDescriptor("icons/propertyview/filter_ps.png"));
        it.setToolTipText(AadlPropertyView.SHOW_ONLY_IMPORTED_PROPERTIES);
        this.getViewSite().getActionBars().getToolBarManager().add(it);
      };
      Action _doubleArrow = ObjectExtensions.<Action>operator_doubleArrow(new Action("Show Only Imported Property Groups", IAction.AS_CHECK_BOX) {
        @Override
        public void run() {
          String _xifexpression = null;
          boolean _isChecked = AadlPropertyView.this.showOnlyImportedPropertiesAction.isChecked();
          if (_isChecked) {
            _xifexpression = AadlPropertyView.SHOW_ONLY_IMPORTED_PROPERTIES;
          } else {
            _xifexpression = AadlPropertyView.SHOW_ALL_AVAILABLE_PROPERTIES;
          }
          AadlPropertyView.this.showOnlyImportedPropertiesAction.setToolTipText(_xifexpression);
          boolean _isChecked_1 = AadlPropertyView.this.showOnlyImportedPropertiesAction.isChecked();
          if (_isChecked_1) {
            ArrayList<FilterCriterion> _arrayList = new ArrayList<FilterCriterion>(AadlPropertyView.this.importedPropertyGroups);
            AadlPropertyView.this.currentPropertyGroup = _arrayList;
          } else {
            AadlPropertyView.this.currentPropertyGroup.clear();
          }
          AadlPropertyView.this.treeViewer.refresh();
        }
      }, _function_1);
      this.showOnlyImportedPropertiesAction = _doubleArrow;
      final Procedure1<Action> _function_2 = (Action it) -> {
        it.setImageDescriptor(MyAadl2Activator.getImageDescriptor("icons/propertyview/nonexistent_property.gif"));
        this.getViewSite().getActionBars().getToolBarManager().add(it);
        it.setToolTipText(AadlPropertyView.SHOW_UNDEFINED_TOOL_TIP);
      };
      Action _doubleArrow_1 = ObjectExtensions.<Action>operator_doubleArrow(new Action(null, IAction.AS_CHECK_BOX) {
        @Override
        public void run() {
          String _xifexpression = null;
          boolean _isChecked = AadlPropertyView.this.showUndefinedAction.isChecked();
          if (_isChecked) {
            _xifexpression = AadlPropertyView.HIDE_UNDEFINED_TOOL_TIP;
          } else {
            _xifexpression = AadlPropertyView.SHOW_UNDEFINED_TOOL_TIP;
          }
          AadlPropertyView.this.showUndefinedAction.setToolTipText(_xifexpression);
          AadlPropertyView.this.treeViewer.refresh();
        }
      }, _function_2);
      this.showUndefinedAction = _doubleArrow_1;
      final Procedure1<Action> _function_3 = (Action it) -> {
        it.setImageDescriptor(MyAadl2Activator.getImageDescriptor("icons/propertyview/filter_properties.gif"));
        this.getViewSite().getActionBars().getToolBarManager().add(it);
        it.setToolTipText(AadlPropertyView.SHOW_DEFAULT_TOOL_TIP);
      };
      Action _doubleArrow_2 = ObjectExtensions.<Action>operator_doubleArrow(new Action(null, IAction.AS_CHECK_BOX) {
        @Override
        public void run() {
          String _xifexpression = null;
          boolean _isChecked = AadlPropertyView.this.showDefaultAction.isChecked();
          if (_isChecked) {
            _xifexpression = AadlPropertyView.HIDE_DEFAULT_TOOL_TIP;
          } else {
            _xifexpression = AadlPropertyView.SHOW_DEFAULT_TOOL_TIP;
          }
          AadlPropertyView.this.showDefaultAction.setToolTipText(_xifexpression);
          AadlPropertyView.this.treeViewer.refresh();
        }
      }, _function_3);
      this.showDefaultAction = _doubleArrow_2;
      final Procedure1<Action> _function_4 = (Action it) -> {
        this.getViewSite().getActionBars().getMenuManager().add(it);
      };
      ObjectExtensions.<Action>operator_doubleArrow(
        new Action("Property Set Filters...") {
          @Override
          public void run() {
            PropertySetFilterDialog _xifexpression = null;
            if ((AadlPropertyView.this.filteredPropertySets == null)) {
              Shell _shell = AadlPropertyView.this.getViewSite().getShell();
              _xifexpression = new PropertySetFilterDialog(_shell);
            } else {
              Shell _shell_1 = AadlPropertyView.this.getViewSite().getShell();
              _xifexpression = new PropertySetFilterDialog(_shell_1, AadlPropertyView.this.filteredPropertySets);
            }
            final PropertySetFilterDialog dialog = _xifexpression;
            int _open = dialog.open();
            boolean _equals = (_open == Window.OK);
            if (_equals) {
              AadlPropertyView.this.filteredPropertySets = dialog.getSelectedPropertySets();
              AadlPropertyView.this.treeViewer.refresh();
            }
          }
        }, _function_4);
      this.removeElementAction = new Action("Remove") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          Object _treeElement = selectedElement.getTreeElement();
          final Object treeElement = _treeElement;
          boolean _matched = false;
          if (treeElement instanceof URI) {
            _matched=true;
            final IUnitOfWork<Procedure0, XtextResource> _function = (XtextResource it) -> {
              Procedure0 _switchResult_1 = null;
              EObject _eObject = it.getResourceSet().getEObject(((URI)treeElement), true);
              final EObject treeElementObject = _eObject;
              boolean _matched_1 = false;
              if (treeElementObject instanceof Property) {
                _matched_1=true;
                Procedure0 _xblockexpression = null;
                {
                  Object _parent = selectedElement.getParent();
                  final URI associationURI = AadlPropertyView.this.cachedPropertyAssociations.get(
                    ((TreeEntry) _parent).getTreeElement()).get(selectedElement.getTreeElement());
                  EObject _eObject_1 = it.getResourceSet().getEObject(associationURI, true);
                  final PropertyAssociation association = ((PropertyAssociation) _eObject_1);
                  Element _owner = association.getOwner();
                  ((NamedElement) _owner).getOwnedPropertyAssociations().remove(association);
                  final Procedure0 _function_1 = () -> {
                    AadlPropertyView.this.runCachePropertyLookupJob(AadlPropertyView.this.getInput(), null);
                  };
                  _xblockexpression = _function_1;
                }
                _switchResult_1 = _xblockexpression;
              }
              if (!_matched_1) {
                if (treeElementObject instanceof BasicPropertyAssociation) {
                  _matched_1=true;
                  Procedure0 _xblockexpression = null;
                  {
                    Element _owner = ((BasicPropertyAssociation)treeElementObject).getOwner();
                    ((RecordValue) _owner).getOwnedFieldValues().remove(treeElementObject);
                    final Procedure0 _function_1 = () -> {
                      AadlPropertyView.this.treeViewer.refresh(selectedElement.getParent());
                    };
                    _xblockexpression = _function_1;
                  }
                  _switchResult_1 = _xblockexpression;
                }
              }
              return _switchResult_1;
            };
            final Procedure0 postModificationUpdate = AadlPropertyView.this.<Procedure0>modify(_function);
            postModificationUpdate.apply();
          }
          if (!_matched) {
            if (treeElement instanceof RangeElement) {
              _matched=true;
              AadlPropertyView.this.<Object>modify(
                new IUnitOfWork.Void<XtextResource>() {
                  @Override
                  public void process(final XtextResource state) throws Exception {
                    EObject _eObject = state.getResourceSet().getEObject(((RangeElement)treeElement).getExpressionURI(), true);
                    Element _owner = ((PropertyExpression) _eObject).getOwner();
                    ((RangeValue) _owner).setDelta(null);
                  }
                });
              AadlPropertyView.this.treeViewer.refresh(selectedElement.getParent());
            }
          }
          if (!_matched) {
            if (treeElement instanceof ListElement) {
              _matched=true;
              AadlPropertyView.this.<Object>modify(
                new IUnitOfWork.Void<XtextResource>() {
                  @Override
                  public void process(final XtextResource state) throws Exception {
                    EObject _eObject = state.getResourceSet().getEObject(((ListElement)treeElement).getExpressionURI(), true);
                    Element _owner = ((PropertyExpression) _eObject).getOwner();
                    ((ListValue) _owner).getOwnedListElements().remove(
                      ((ListElement)treeElement).getIndex());
                  }
                });
              AadlPropertyView.this.treeViewer.refresh(selectedElement.getParent());
            }
          }
        }
      };
      this.openDefinitionAction = new Action("Open Property Definition") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          Object _treeElement = ((TreeEntry) _firstElement).getTreeElement();
          final URI selectedElementURI = ((URI) _treeElement);
          final Function1<ResourceSet, URI> _function = (ResourceSet it) -> {
            URI _switchResult = null;
            EObject _eObject = it.getEObject(selectedElementURI, true);
            final EObject selectedElement = _eObject;
            boolean _matched = false;
            if (selectedElement instanceof PropertySet) {
              _matched=true;
            }
            if (!_matched) {
              if (selectedElement instanceof Property) {
                _matched=true;
              }
            }
            if (!_matched) {
              if (selectedElement instanceof BasicProperty) {
                _matched=true;
              }
            }
            if (_matched) {
              _switchResult = selectedElementURI;
            }
            if (!_matched) {
              if (selectedElement instanceof BasicPropertyAssociation) {
                _matched=true;
                _switchResult = EcoreUtil.getURI(((BasicPropertyAssociation)selectedElement).getProperty());
              }
            }
            return _switchResult;
          };
          final URI uriToOpen = AadlPropertyView.this.<URI>safeRead(_function);
          AadlPropertyView.this.modelListenerEnabled = false;
          AadlPropertyView.this.editorOpener.open(uriToOpen, true);
          AadlPropertyView.this.modelListenerEnabled = true;
        }
      };
      this.openPropertyAssociationAction = new Action("Open Property Association") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          final Function1<ResourceSet, URI> _function = (ResourceSet it) -> {
            URI _xblockexpression = null;
            {
              Object _parent = selectedElement.getParent();
              final EObject associationTemp = it.getEObject(AadlPropertyView.this.cachedPropertyAssociations.get(((TreeEntry) _parent).getTreeElement()).get(selectedElement.getTreeElement()), true);
              PropertyAssociation _switchResult = null;
              boolean _matched = false;
              if (associationTemp instanceof PropertyAssociationInstance) {
                _matched=true;
                _switchResult = ((PropertyAssociationInstance)associationTemp).getPropertyAssociation();
              }
              if (!_matched) {
                if (associationTemp instanceof PropertyAssociation) {
                  _matched=true;
                  _switchResult = ((PropertyAssociation)associationTemp);
                }
              }
              if (!_matched) {
                _switchResult = null;
              }
              final PropertyAssociation association = _switchResult;
              final EObject inputElement = it.getEObject(AadlPropertyView.this.getInput(), true);
              Element _xifexpression = null;
              if ((inputElement instanceof RefinableElement)) {
                Element _elvis = null;
                final Function1<ContainedNamedElement, ContainmentPathElement> _function_1 = (ContainedNamedElement it_1) -> {
                  return IterableExtensions.<ContainmentPathElement>last(it_1.getContainmentPathElements());
                };
                final Function1<ContainmentPathElement, Boolean> _function_2 = (ContainmentPathElement it_1) -> {
                  return Boolean.valueOf(((it_1.getNamedElement() instanceof RefinableElement) && 
                    AadlUtil.isSameOrRefines(((RefinableElement) it_1.getNamedElement()), ((RefinableElement)inputElement))));
                };
                ContainmentPathElement _head = IterableExtensions.<ContainmentPathElement>head(IterableExtensions.<ContainmentPathElement>filter(ListExtensions.<ContainedNamedElement, ContainmentPathElement>map(association.getAppliesTos(), _function_1), _function_2));
                if (_head != null) {
                  _elvis = _head;
                } else {
                  _elvis = association;
                }
                _xifexpression = _elvis;
              } else {
                _xifexpression = association;
              }
              _xblockexpression = EcoreUtil.getURI(_xifexpression);
            }
            return _xblockexpression;
          };
          final URI uriToOpen = AadlPropertyView.this.<URI>safeRead(_function);
          AadlPropertyView.this.modelListenerEnabled = false;
          AadlPropertyView.this.editorOpener.open(uriToOpen, true);
          AadlPropertyView.this.modelListenerEnabled = true;
        }
      };
      this.makeLocalAction = new Action("Make Local") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          Object _treeElement = selectedElement.getTreeElement();
          final URI propertyURI = ((URI) _treeElement);
          Object _parent = selectedElement.getParent();
          final URI associationURI = AadlPropertyView.this.cachedPropertyAssociations.get(((TreeEntry) _parent).getTreeElement()).get(propertyURI);
          final IUnitOfWork<Procedure0, XtextResource> _function = (XtextResource it) -> {
            Procedure0 _xblockexpression = null;
            {
              final Procedure0 _function_1 = () -> {
              };
              Procedure0 update = _function_1;
              EObject _eObject = it.getResourceSet().getEObject(AadlPropertyView.this.getInput(), true);
              final NamedElement inputElement = ((NamedElement) _eObject);
              AadlPropertyView.this.resolveProperties(inputElement);
              if ((associationURI != null)) {
                EObject _eObject_1 = it.getResourceSet().getEObject(associationURI, true);
                final PropertyAssociation oldPA = ((PropertyAssociation) _eObject_1);
                final PropertyAssociation newPA = EcoreUtil.<PropertyAssociation>copy(oldPA);
                newPA.getAppliesTos().clear();
                int _size = oldPA.getAppliesTos().size();
                boolean _equals = (_size == 1);
                if (_equals) {
                  Element _owner = oldPA.getOwner();
                  ((NamedElement) _owner).getOwnedPropertyAssociations().remove(oldPA);
                  final Procedure0 _function_2 = () -> {
                    AadlPropertyView.this.runCachePropertyLookupJob(AadlPropertyView.this.getInput(), null);
                  };
                  update = _function_2;
                } else {
                  int _size_1 = oldPA.getAppliesTos().size();
                  boolean _greaterThan = (_size_1 > 1);
                  if (_greaterThan) {
                    final Function1<ContainedNamedElement, Boolean> _function_3 = (ContainedNamedElement it_1) -> {
                      NamedElement _namedElement = it_1.getPath().getNamedElement();
                      return Boolean.valueOf((_namedElement == inputElement));
                    };
                    final ContainedNamedElement toRemove = IterableExtensions.<ContainedNamedElement>findFirst(oldPA.getAppliesTos(), _function_3);
                    oldPA.getAppliesTos().remove(toRemove);
                  }
                }
                inputElement.getOwnedPropertyAssociations().add(newPA);
              } else {
                EObject _eObject_2 = it.getResourceSet().getEObject(propertyURI, true);
                final Property property = ((Property) _eObject_2);
                PropertyAssociation _createOwnedPropertyAssociation = inputElement.createOwnedPropertyAssociation();
                final Procedure1<PropertyAssociation> _function_4 = (PropertyAssociation it_1) -> {
                  it_1.setProperty(property);
                  ModalPropertyValue _createOwnedValue = it_1.createOwnedValue();
                  final Procedure1<ModalPropertyValue> _function_5 = (ModalPropertyValue it_2) -> {
                    it_2.setOwnedValue(EcoreUtil.<PropertyExpression>copy(property.getDefaultValue()));
                  };
                  ObjectExtensions.<ModalPropertyValue>operator_doubleArrow(_createOwnedValue, _function_5);
                };
                ObjectExtensions.<PropertyAssociation>operator_doubleArrow(_createOwnedPropertyAssociation, _function_4);
              }
              _xblockexpression = update;
            }
            return _xblockexpression;
          };
          final Procedure0 postModificationUpdate = AadlPropertyView.this.<Procedure0>modify(_function);
          postModificationUpdate.apply();
        }
      };
      this.makeLocalContainedAction = new Action("Make Local Contained") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          Object _treeElement = selectedElement.getTreeElement();
          final URI propertyURI = ((URI) _treeElement);
          Object _parent = selectedElement.getParent();
          final URI associationURI = AadlPropertyView.this.cachedPropertyAssociations.get(((TreeEntry) _parent).getTreeElement()).get(propertyURI);
          final IUnitOfWork<Procedure0, XtextResource> _function = (XtextResource it) -> {
            Procedure0 _xblockexpression = null;
            {
              final Procedure0 _function_1 = () -> {
              };
              Procedure0 update = _function_1;
              EObject _eObject = it.getResourceSet().getEObject(AadlPropertyView.this.getInput(), true);
              final NamedElement inputElement = ((NamedElement) _eObject);
              AadlPropertyView.this.resolveProperties(inputElement);
              if ((associationURI != null)) {
                EObject _eObject_1 = it.getResourceSet().getEObject(associationURI, true);
                final PropertyAssociation oldPA = ((PropertyAssociation) _eObject_1);
                final PropertyAssociation newPA = EcoreUtil.<PropertyAssociation>copy(oldPA);
                newPA.getAppliesTos().clear();
                EList<ContainedNamedElement> _appliesTos = newPA.getAppliesTos();
                ContainedNamedElement _createContainedNamedElement = Aadl2Factory.eINSTANCE.createContainedNamedElement();
                final Procedure1<ContainedNamedElement> _function_2 = (ContainedNamedElement it_1) -> {
                  ContainmentPathElement _createPath = it_1.createPath();
                  final Procedure1<ContainmentPathElement> _function_3 = (ContainmentPathElement it_2) -> {
                    it_2.setNamedElement(inputElement);
                  };
                  ObjectExtensions.<ContainmentPathElement>operator_doubleArrow(_createPath, _function_3);
                };
                ContainedNamedElement _doubleArrow = ObjectExtensions.<ContainedNamedElement>operator_doubleArrow(_createContainedNamedElement, _function_2);
                _appliesTos.add(_doubleArrow);
                if (((oldPA.getAppliesTos().size() == 0) && (oldPA.getOwner() == inputElement))) {
                  inputElement.getOwnedPropertyAssociations().remove(oldPA);
                  final Procedure0 _function_3 = () -> {
                    AadlPropertyView.this.runCachePropertyLookupJob(AadlPropertyView.this.getInput(), null);
                  };
                  update = _function_3;
                } else {
                  int _size = oldPA.getAppliesTos().size();
                  boolean _greaterThan = (_size > 1);
                  if (_greaterThan) {
                    final Function1<ContainedNamedElement, Boolean> _function_4 = (ContainedNamedElement it_1) -> {
                      NamedElement _namedElement = it_1.getPath().getNamedElement();
                      return Boolean.valueOf((_namedElement == inputElement));
                    };
                    final ContainedNamedElement toRemove = IterableExtensions.<ContainedNamedElement>findFirst(oldPA.getAppliesTos(), _function_4);
                    oldPA.getAppliesTos().remove(toRemove);
                  }
                }
                Element _owner = inputElement.getOwner();
                ((NamedElement) _owner).getOwnedPropertyAssociations().add(newPA);
              } else {
                EObject _eObject_2 = it.getResourceSet().getEObject(propertyURI, true);
                final Property property = ((Property) _eObject_2);
                Element _owner_1 = inputElement.getOwner();
                PropertyAssociation _createOwnedPropertyAssociation = ((NamedElement) _owner_1).createOwnedPropertyAssociation();
                final Procedure1<PropertyAssociation> _function_5 = (PropertyAssociation it_1) -> {
                  it_1.setProperty(property);
                  ModalPropertyValue _createOwnedValue = it_1.createOwnedValue();
                  final Procedure1<ModalPropertyValue> _function_6 = (ModalPropertyValue it_2) -> {
                    it_2.setOwnedValue(EcoreUtil.<PropertyExpression>copy(property.getDefaultValue()));
                  };
                  ObjectExtensions.<ModalPropertyValue>operator_doubleArrow(_createOwnedValue, _function_6);
                  EList<ContainedNamedElement> _appliesTos_1 = it_1.getAppliesTos();
                  ContainedNamedElement _createContainedNamedElement_1 = Aadl2Factory.eINSTANCE.createContainedNamedElement();
                  final Procedure1<ContainedNamedElement> _function_7 = (ContainedNamedElement it_2) -> {
                    ContainmentPathElement _createPath = it_2.createPath();
                    final Procedure1<ContainmentPathElement> _function_8 = (ContainmentPathElement it_3) -> {
                      it_3.setNamedElement(inputElement);
                    };
                    ObjectExtensions.<ContainmentPathElement>operator_doubleArrow(_createPath, _function_8);
                  };
                  ContainedNamedElement _doubleArrow_1 = ObjectExtensions.<ContainedNamedElement>operator_doubleArrow(_createContainedNamedElement_1, _function_7);
                  _appliesTos_1.add(_doubleArrow_1);
                };
                ObjectExtensions.<PropertyAssociation>operator_doubleArrow(_createOwnedPropertyAssociation, _function_5);
              }
              _xblockexpression = update;
            }
            return _xblockexpression;
          };
          final Procedure0 postModificationUpdate = AadlPropertyView.this.<Procedure0>modify(_function);
          postModificationUpdate.apply();
        }
      };
      this.createLocalAssociationAction = new Action("Create Local Property Association") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          AadlPropertyView.this.nextEditIsLocalCreation = true;
          AadlPropertyView.this.treeViewer.editElement(selectedElement, 1);
        }
      };
      _xblockexpression = this.createLocalContainedAssociationAction = new Action("Create Local Contained Property Association") {
        @Override
        public void run() {
          ISelection _selection = AadlPropertyView.this.treeViewer.getSelection();
          Object _firstElement = ((IStructuredSelection) _selection).getFirstElement();
          final TreeEntry selectedElement = ((TreeEntry) _firstElement);
          AadlPropertyView.this.nextEditIsLocalContainedCreation = true;
          AadlPropertyView.this.treeViewer.editElement(selectedElement, 1);
        }
      };
    }
    return _xblockexpression;
  }

  /**
   * When editing a raw XtextResouce, this calls the getProperty() method for all property associations owned by a specified named element.
   * This is needed because under certain conditions the property reference is not updated and this can result in a broken proxy.
   * An exception is thrown when resolving the proxy. Resolving the property before making a modification prevents this from happening.
   */
  public void resolveProperties(final NamedElement element) {
    if ((this.xtextDocument == null)) {
      EList<PropertyAssociation> _ownedPropertyAssociations = element.getOwnedPropertyAssociations();
      for (final PropertyAssociation pa : _ownedPropertyAssociations) {
        pa.getProperty();
      }
    }
  }

  <T extends Object> T modify(final IUnitOfWork<T, XtextResource> work) {
    abstract class __AadlPropertyView_16 extends RecordingCommand {
      __AadlPropertyView_16(final TransactionalEditingDomain arg0) {
        super(arg0);
      }

      T result;
    }

    try {
      T _xifexpression = null;
      if ((this.xtextDocument != null)) {
        _xifexpression = this.xtextDocument.<T>modify(work);
      } else {
        T _xifexpression_1 = null;
        if ((this.resourceFromSelection instanceof XtextResource)) {
          T _xblockexpression = null;
          {
            final XtextResource resource = ((XtextResource)this.resourceFromSelection);
            __AadlPropertyView_16 cmd = new __AadlPropertyView_16(((TransactionalEditingDomain) this.editingDomain)) {
              @Override
              protected void doExecute() {
                try {
                  this.result = work.exec(resource);
                } catch (Throwable _e) {
                  throw Exceptions.sneakyThrow(_e);
                }
              }
            };
            this.editingDomain.getCommandStack().execute(cmd);
            final String serializedSrc = resource.getSerializer().serialize(resource.getContents().get(0));
            final boolean modificationSuccessful = ((serializedSrc != null) && (!serializedSrc.trim().isEmpty()));
            if ((!modificationSuccessful)) {
              if (((!this.editingDomain.getCommandStack().canUndo()) || (!Objects.equal(this.editingDomain.getCommandStack().getUndoCommand(), cmd)))) {
                throw new RuntimeException("Property modification failed and unable to undo. Unexpected state.");
              }
              this.editingDomain.getCommandStack().undo();
            }
            ((XtextResource)this.resourceFromSelection).save(SaveOptions.newBuilder().format().getOptions().toOptionsMap());
            _xblockexpression = cmd.result;
          }
          _xifexpression_1 = _xblockexpression;
        } else {
          throw new RuntimeException("Unsupported case. Cannot modify model without an Xtext Document or an Xtext resource");
        }
        _xifexpression = _xifexpression_1;
      }
      return _xifexpression;
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }

  private MenuManager createContextMenu() {
    MenuManager _menuManager = new MenuManager();
    final Procedure1<MenuManager> _function = (MenuManager it) -> {
      it.setRemoveAllWhenShown(true);
      final IMenuListener _function_1 = (IMenuManager it_1) -> {
        it_1.add(this.openDefinitionAction);
        it_1.add(this.openPropertyAssociationAction);
        it_1.add(this.createLocalAssociationAction);
        it_1.add(this.createLocalContainedAssociationAction);
        it_1.add(this.makeLocalAction);
        it_1.add(this.makeLocalContainedAction);
        it_1.add(this.removeElementAction);
        this.openDefinitionAction.setEnabled(false);
        this.openPropertyAssociationAction.setEnabled(false);
        this.createLocalAssociationAction.setEnabled(false);
        this.createLocalContainedAssociationAction.setEnabled(false);
        this.makeLocalAction.setEnabled(false);
        this.makeLocalContainedAction.setEnabled(false);
        this.removeElementAction.setEnabled(false);
        ISelection _selection = this.treeViewer.getSelection();
        final IStructuredSelection selection = ((IStructuredSelection) _selection);
        int _size = selection.size();
        boolean _equals = (_size == 1);
        if (_equals) {
          Object _firstElement = selection.getFirstElement();
          final TreeEntry firstSelectedElement = ((TreeEntry) _firstElement);
          Object _treeElement = firstSelectedElement.getTreeElement();
          if ((_treeElement instanceof URI)) {
            final Function1<ResourceSet, Boolean> _function_2 = (ResourceSet it_2) -> {
              boolean _xblockexpression = false;
              {
                Object _treeElement_1 = firstSelectedElement.getTreeElement();
                final EObject treeElementEObject = it_2.getEObject(((URI) _treeElement_1), true);
                _xblockexpression = ((((treeElementEObject instanceof PropertySet) || (treeElementEObject instanceof Property)) || 
                  (treeElementEObject instanceof BasicPropertyAssociation)) || 
                  (treeElementEObject instanceof BasicProperty));
              }
              return Boolean.valueOf(_xblockexpression);
            };
            this.openDefinitionAction.setEnabled((this.<Boolean>safeRead(_function_2)).booleanValue());
            final Function1<ResourceSet, Boolean> _function_3 = (ResourceSet it_2) -> {
              Object _treeElement_1 = firstSelectedElement.getTreeElement();
              EObject _eObject = it_2.getEObject(((URI) _treeElement_1), true);
              return Boolean.valueOf((_eObject instanceof Property));
            };
            Boolean _safeRead = this.<Boolean>safeRead(_function_3);
            if ((_safeRead).booleanValue()) {
              Object _parent = firstSelectedElement.getParent();
              Object _treeElement_1 = ((TreeEntry) _parent).getTreeElement();
              Object _treeElement_2 = firstSelectedElement.getTreeElement();
              final PropertyStatus propertyStatus = this.getPropertyStatus(
                ((URI) _treeElement_1), 
                ((URI) _treeElement_2));
              this.openPropertyAssociationAction.setEnabled(Collections.<PropertyStatus>unmodifiableList(CollectionLiterals.<PropertyStatus>newArrayList(PropertyStatus.INHERITED, PropertyStatus.LOCAL, PropertyStatus.LOCAL_CONTAINED)).contains(propertyStatus));
              this.createLocalAssociationAction.setEnabled((((Objects.equal(propertyStatus, 
                PropertyStatus.INHERITED) || Objects.equal(propertyStatus, PropertyStatus.DEFAULT)) || 
                Objects.equal(propertyStatus, PropertyStatus.UNDEFINED)) && (this.<Boolean>safeRead(((Function1<ResourceSet, Boolean>) (ResourceSet it_2) -> {
                boolean _xblockexpression = false;
                {
                  final EObject inputElement = it_2.getEObject(this.getInput(), true);
                  _xblockexpression = ((((((((inputElement instanceof AadlPackage) || (inputElement instanceof Classifier)) || 
                    (inputElement instanceof Subcomponent)) || (inputElement instanceof ModalPath)) || 
                    (inputElement instanceof BehavioralFeature)) || (inputElement instanceof Prototype)) || 
                    (inputElement instanceof Feature)) || (inputElement instanceof ModeFeature));
                }
                return Boolean.valueOf(_xblockexpression);
              }))).booleanValue()));
              this.createLocalContainedAssociationAction.setEnabled((((Objects.equal(propertyStatus, 
                PropertyStatus.INHERITED) || Objects.equal(propertyStatus, PropertyStatus.DEFAULT)) || 
                Objects.equal(propertyStatus, PropertyStatus.UNDEFINED)) && (this.<Boolean>safeRead(((Function1<ResourceSet, Boolean>) (ResourceSet it_2) -> {
                boolean _xblockexpression = false;
                {
                  final EObject inputElement = it_2.getEObject(this.getInput(), true);
                  _xblockexpression = ((((((inputElement instanceof Subcomponent) || (inputElement instanceof ModalPath)) || 
                    (inputElement instanceof BehavioralFeature)) || (inputElement instanceof Prototype)) || 
                    (inputElement instanceof Feature)) || (inputElement instanceof ModeFeature));
                }
                return Boolean.valueOf(_xblockexpression);
              }))).booleanValue()));
              this.makeLocalAction.setEnabled(Collections.<PropertyStatus>unmodifiableList(CollectionLiterals.<PropertyStatus>newArrayList(PropertyStatus.INHERITED, PropertyStatus.LOCAL_CONTAINED, PropertyStatus.LOCAL_SHARED, PropertyStatus.DEFAULT)).contains(propertyStatus));
              this.makeLocalContainedAction.setEnabled((Collections.<PropertyStatus>unmodifiableList(CollectionLiterals.<PropertyStatus>newArrayList(PropertyStatus.INHERITED, PropertyStatus.LOCAL, PropertyStatus.LOCAL_SHARED, PropertyStatus.DEFAULT)).contains(propertyStatus) && (this.<Boolean>safeRead(((Function1<ResourceSet, Boolean>) (ResourceSet it_2) -> {
                boolean _xblockexpression = false;
                {
                  final EObject inputElement = it_2.getEObject(this.getInput(), true);
                  _xblockexpression = ((((((inputElement instanceof Subcomponent) || (inputElement instanceof ModalPath)) || 
                    (inputElement instanceof BehavioralFeature)) || (inputElement instanceof Prototype)) || 
                    (inputElement instanceof Feature)) || (inputElement instanceof ModeFeature));
                }
                return Boolean.valueOf(_xblockexpression);
              }))).booleanValue()));
            }
          }
          boolean _and = false;
          boolean _canEdit = this.canEdit(firstSelectedElement);
          if (!_canEdit) {
            _and = false;
          } else {
            Boolean _switchResult = null;
            Object _treeElement_3 = firstSelectedElement.getTreeElement();
            final Object treeElement = _treeElement_3;
            boolean _matched = false;
            if (treeElement instanceof URI) {
              _matched=true;
              final Function1<ResourceSet, Boolean> _function_4 = (ResourceSet it_2) -> {
                boolean _switchResult_1 = false;
                EObject _eObject = it_2.getEObject(((URI)treeElement), true);
                final EObject treeElementEObject = _eObject;
                boolean _matched_1 = false;
                if (treeElementEObject instanceof Property) {
                  _matched_1=true;
                  _switchResult_1 = true;
                }
                if (!_matched_1) {
                  if (treeElementEObject instanceof BasicPropertyAssociation) {
                    _matched_1=true;
                    Element _owner = ((BasicPropertyAssociation)treeElementEObject).getOwner();
                    int _size_1 = ((RecordValue) _owner).getOwnedFieldValues().size();
                    _switchResult_1 = (_size_1 >= 2);
                  }
                }
                if (!_matched_1) {
                  _switchResult_1 = false;
                }
                return Boolean.valueOf(_switchResult_1);
              };
              _switchResult = this.<Boolean>safeRead(_function_4);
            }
            if (!_matched) {
              if (treeElement instanceof RangeElement) {
                _matched=true;
                String _label = ((RangeElement)treeElement).getLabel();
                _switchResult = Boolean.valueOf(Objects.equal(_label, RangeElement.DELTA_LABEL));
              }
            }
            if (!_matched) {
              if (treeElement instanceof ListElement) {
                _matched=true;
                _switchResult = Boolean.valueOf(true);
              }
            }
            if (!_matched) {
              _switchResult = Boolean.valueOf(false);
            }
            _and = (_switchResult).booleanValue();
          }
          this.removeElementAction.setEnabled(_and);
        }
        GroupMarker _groupMarker = new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS);
        it_1.add(_groupMarker);
      };
      it.addMenuListener(_function_1);
      Control _control = this.treeViewer.getControl();
      _control.setMenu(it.createContextMenu(this.treeViewer.getControl()));
      this.getSite().registerContextMenu(it, this.treeViewer);
    };
    return ObjectExtensions.<MenuManager>operator_doubleArrow(_menuManager, _function);
  }

  private void updateSelection(final IWorkbenchPart part, final ISelection selection) {
    if (this.xtextDocument!=null) {
      this.xtextDocument.removeModelListener(this.xtextModelListener);
    }
    EObject _switchResult = null;
    boolean _matched = false;
    boolean _isEmpty = selection.isEmpty();
    if (_isEmpty) {
      _matched=true;
      _switchResult = null;
    }
    if (!_matched) {
      if (selection instanceof ITextSelection) {
        if ((part instanceof XtextEditor)) {
          _matched=true;
          EObject _xblockexpression = null;
          {
            this.xtextDocument = ((XtextEditor) part).getDocument();
            final IUnitOfWork<EObject, XtextResource> _function = (XtextResource it) -> {
              return new EObjectAtOffsetHelper().resolveContainedElementAt(it, ((ITextSelection)selection).getOffset());
            };
            _xblockexpression = this.xtextDocument.<EObject>readOnly(_function);
          }
          _switchResult = _xblockexpression;
        }
      }
    }
    if (!_matched) {
      if (selection instanceof IStructuredSelection) {
        int _size = ((IStructuredSelection)selection).size();
        boolean _equals = (_size == 1);
        if (_equals) {
          _matched=true;
          EObject _switchResult_1 = null;
          Object _firstElement = ((IStructuredSelection)selection).getFirstElement();
          final Object selectedObject = _firstElement;
          boolean _matched_1 = false;
          if (selectedObject instanceof EObject) {
            _matched_1=true;
            EObject _xblockexpression = null;
            {
              this.xtextDocument = null;
              _xblockexpression = ((EObject)selectedObject);
            }
            _switchResult_1 = _xblockexpression;
          }
          if (!_matched_1) {
            if (selectedObject instanceof EObjectNode) {
              _matched_1=true;
              EObject _xblockexpression = null;
              {
                this.xtextDocument = ((EObjectNode)selectedObject).getDocument();
                final IUnitOfWork<EObject, EObject> _function = (EObject it) -> {
                  return it;
                };
                _xblockexpression = ((EObjectNode)selectedObject).<EObject>readOnly(_function);
              }
              _switchResult_1 = _xblockexpression;
            }
          }
          if (!_matched_1) {
            if (selectedObject instanceof EObjectURIWrapper) {
              _matched_1=true;
              EObject _xblockexpression = null;
              {
                this.xtextDocument = null;
                _xblockexpression = new ResourceSetImpl().getEObject(((EObjectURIWrapper)selectedObject).getUri(), true);
              }
              _switchResult_1 = _xblockexpression;
            }
          }
          if (!_matched_1) {
            NamedElement _xblockexpression = null;
            {
              IAadlPropertySource _elvis = null;
              IAadlPropertySource _adapt = Adapters.<IAadlPropertySource>adapt(selectedObject, IAadlPropertySource.class);
              if (_adapt != null) {
                _elvis = _adapt;
              } else {
                IAadlPropertySource _adapt_1 = Adapters.<IAadlPropertySource>adapt(selection, IAadlPropertySource.class);
                _elvis = _adapt_1;
              }
              final IAadlPropertySource propertySource = _elvis;
              NamedElement _xifexpression = null;
              if ((propertySource != null)) {
                NamedElement _xblockexpression_1 = null;
                {
                  this.xtextDocument = propertySource.getDocument();
                  _xblockexpression_1 = propertySource.getNamedElement();
                }
                _xifexpression = _xblockexpression_1;
              }
              _xblockexpression = _xifexpression;
            }
            _switchResult_1 = _xblockexpression;
          }
          _switchResult = _switchResult_1;
        }
      }
    }
    final EObject currentSelection = _switchResult;
    if (this.xtextDocument!=null) {
      this.xtextDocument.addModelListener(this.xtextModelListener);
    }
    Object treeElementToSelect = null;
    URI _xtrycatchfinallyexpression = null;
    try {
      URI _switchResult_1 = null;
      boolean _matched_1 = false;
      if (currentSelection instanceof PropertySet) {
        _matched_1=true;
      }
      if (!_matched_1) {
        if (currentSelection instanceof Property) {
          _matched_1=true;
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof PropertyType) {
          _matched_1=true;
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof PropertyConstant) {
          _matched_1=true;
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof PackageSection) {
          _matched_1=true;
        }
      }
      if (_matched_1) {
        _switchResult_1 = null;
      }
      if (!_matched_1) {
        if (currentSelection instanceof NamedElement) {
          _matched_1=true;
          _switchResult_1 = EcoreUtil.getURI(currentSelection);
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof PropertyAssociation) {
          boolean _isEmpty_1 = ((PropertyAssociation)currentSelection).getAppliesTos().isEmpty();
          if (_isEmpty_1) {
            _matched_1=true;
            URI _xblockexpression = null;
            {
              URI _uRI = EcoreUtil.getURI(((PropertyAssociation)currentSelection).getOwner());
              URI _uRI_1 = EcoreUtil.getURI(EcoreUtil2.<PropertySet>getContainerOfType(((PropertyAssociation)currentSelection).getProperty(), PropertySet.class));
              TreeEntry _treeEntry = new TreeEntry(_uRI, _uRI_1);
              URI _uRI_2 = EcoreUtil.getURI(((PropertyAssociation)currentSelection).getProperty());
              TreeEntry _treeEntry_1 = new TreeEntry(_treeEntry, _uRI_2);
              treeElementToSelect = _treeEntry_1;
              _xblockexpression = EcoreUtil.getURI(((PropertyAssociation)currentSelection).getOwner());
            }
            _switchResult_1 = _xblockexpression;
          }
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof PropertyAssociation) {
          if (((((PropertyAssociation)currentSelection).getAppliesTos().size() == 1) && 
            (IterableExtensions.<ContainedNamedElement>head(((PropertyAssociation)currentSelection).getAppliesTos()).getContainmentPathElements().size() == 1))) {
            _matched_1=true;
            URI _xblockexpression = null;
            {
              URI _uRI = EcoreUtil.getURI(IterableExtensions.<ContainmentPathElement>head(IterableExtensions.<ContainedNamedElement>head(((PropertyAssociation)currentSelection).getAppliesTos()).getContainmentPathElements()).getNamedElement());
              URI _uRI_1 = EcoreUtil.getURI(EcoreUtil2.<PropertySet>getContainerOfType(((PropertyAssociation)currentSelection).getProperty(), PropertySet.class));
              TreeEntry _treeEntry = new TreeEntry(_uRI, _uRI_1);
              URI _uRI_2 = EcoreUtil.getURI(((PropertyAssociation)currentSelection).getProperty());
              TreeEntry _treeEntry_1 = new TreeEntry(_treeEntry, _uRI_2);
              treeElementToSelect = _treeEntry_1;
              _xblockexpression = EcoreUtil.getURI(IterableExtensions.<ContainmentPathElement>head(IterableExtensions.<ContainedNamedElement>head(((PropertyAssociation)currentSelection).getAppliesTos()).getContainmentPathElements()).getNamedElement());
            }
            _switchResult_1 = _xblockexpression;
          }
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof ContainmentPathElement) {
          if (((((ContainmentPathElement)currentSelection).getPath() == null) && 
            (((ContainmentPathElement)currentSelection).getOwner() instanceof ContainedNamedElement))) {
            _matched_1=true;
            URI _xblockexpression = null;
            {
              URI _uRI = EcoreUtil.getURI(((ContainmentPathElement)currentSelection).getNamedElement());
              URI _uRI_1 = EcoreUtil.getURI(EcoreUtil2.<PropertySet>getContainerOfType(EcoreUtil2.<PropertyAssociation>getContainerOfType(currentSelection, PropertyAssociation.class).getProperty(), PropertySet.class));
              TreeEntry _treeEntry = new TreeEntry(_uRI, _uRI_1);
              URI _uRI_2 = EcoreUtil.getURI(EcoreUtil2.<PropertyAssociation>getContainerOfType(currentSelection, PropertyAssociation.class).getProperty());
              TreeEntry _treeEntry_1 = new TreeEntry(_treeEntry, _uRI_2);
              treeElementToSelect = _treeEntry_1;
              _xblockexpression = EcoreUtil.getURI(((ContainmentPathElement)currentSelection).getNamedElement());
            }
            _switchResult_1 = _xblockexpression;
          }
        }
      }
      if (!_matched_1) {
        if (currentSelection instanceof BasicPropertyAssociation) {
          _matched_1=true;
        }
        if (!_matched_1) {
          if (currentSelection instanceof PropertyExpression) {
            _matched_1=true;
          }
        }
        if (_matched_1) {
          URI _xblockexpression = null;
          {
            final ArrayDeque<Object> path = new ArrayDeque<Object>();
            if ((currentSelection instanceof BasicPropertyAssociation)) {
              path.push(EcoreUtil.getURI(currentSelection));
            }
            Element currentElement = ((Element)currentSelection).getOwner();
            Element previousElement = ((Element)currentSelection);
            while (((currentElement != null) && (!(currentElement instanceof PropertyAssociation)))) {
              {
                boolean _matched_2 = false;
                if (currentElement instanceof ModalPropertyValue) {
                  Element _owner = ((ModalPropertyValue)currentElement).getOwner();
                  boolean _isModal = ((PropertyAssociation) _owner).isModal();
                  if (_isModal) {
                    _matched_2=true;
                  }
                }
                if (!_matched_2) {
                  if (currentElement instanceof BasicPropertyAssociation) {
                    _matched_2=true;
                  }
                }
                if (_matched_2) {
                  path.push(EcoreUtil.getURI(currentElement));
                }
                if (!_matched_2) {
                  if (currentElement instanceof ListValue) {
                    _matched_2=true;
                    int _indexOf = ((ListValue)currentElement).getOwnedListElements().indexOf(previousElement);
                    URI _uRI = EcoreUtil.getURI(previousElement);
                    ListElement _listElement = new ListElement(_indexOf, _uRI);
                    path.push(_listElement);
                  }
                }
                if (!_matched_2) {
                  if (currentElement instanceof RangeValue) {
                    _matched_2=true;
                    String _switchResult_3 = null;
                    boolean _matched_3 = false;
                    PropertyExpression _minimum = ((RangeValue)currentElement).getMinimum();
                    if (Objects.equal(previousElement, _minimum)) {
                      _matched_3=true;
                      _switchResult_3 = RangeElement.MINIMUM_LABEL;
                    }
                    if (!_matched_3) {
                      PropertyExpression _maximum = ((RangeValue)currentElement).getMaximum();
                      if (Objects.equal(previousElement, _maximum)) {
                        _matched_3=true;
                        _switchResult_3 = RangeElement.MAXIMUM_LABEL;
                      }
                    }
                    if (!_matched_3) {
                      PropertyExpression _delta = ((RangeValue)currentElement).getDelta();
                      if (Objects.equal(previousElement, _delta)) {
                        _matched_3=true;
                        _switchResult_3 = RangeElement.DELTA_LABEL;
                      }
                    }
                    URI _uRI = EcoreUtil.getURI(previousElement);
                    RangeElement _rangeElement = new RangeElement(_switchResult_3, _uRI);
                    path.push(_rangeElement);
                  }
                }
                previousElement = currentElement;
                currentElement = currentElement.getOwner();
              }
            }
            URI _xifexpression = null;
            if ((currentElement instanceof PropertyAssociation)) {
              URI _xblockexpression_1 = null;
              {
                path.push(EcoreUtil.getURI(((PropertyAssociation)currentElement).getProperty()));
                URI _xifexpression_1 = null;
                boolean _isEmpty_1 = ((PropertyAssociation)currentElement).getAppliesTos().isEmpty();
                if (_isEmpty_1) {
                  _xifexpression_1 = EcoreUtil.getURI(((PropertyAssociation)currentElement).getOwner());
                } else {
                  URI _xifexpression_2 = null;
                  if (((((PropertyAssociation)currentElement).getAppliesTos().size() == 1) && 
                    (IterableExtensions.<ContainedNamedElement>head(((PropertyAssociation)currentElement).getAppliesTos()).getContainmentPathElements().size() == 1))) {
                    _xifexpression_2 = EcoreUtil.getURI(IterableExtensions.<ContainmentPathElement>head(IterableExtensions.<ContainedNamedElement>head(((PropertyAssociation)currentElement).getAppliesTos()).getContainmentPathElements()).getNamedElement());
                  }
                  _xifexpression_1 = _xifexpression_2;
                }
                final URI root = _xifexpression_1;
                URI _uRI = EcoreUtil.getURI(EcoreUtil2.<PropertySet>getContainerOfType(((PropertyAssociation)currentElement).getProperty(), PropertySet.class));
                TreeEntry _treeEntry = new TreeEntry(root, _uRI);
                final Function2<TreeEntry, Object, TreeEntry> _function = (TreeEntry $0, Object $1) -> {
                  return new TreeEntry($0, $1);
                };
                treeElementToSelect = IterableExtensions.<Object, TreeEntry>fold(path, _treeEntry, _function);
                _xblockexpression_1 = root;
              }
              _xifexpression = _xblockexpression_1;
            }
            _xblockexpression = _xifexpression;
          }
          _switchResult_1 = _xblockexpression;
        }
      }
      _xtrycatchfinallyexpression = _switchResult_1;
    } catch (final Throwable _t) {
      if (_t instanceof NullPointerException) {
        _xtrycatchfinallyexpression = null;
      } else {
        throw Exceptions.sneakyThrow(_t);
      }
    }
    final URI currentSelectionURI = _xtrycatchfinallyexpression;
    if ((currentSelectionURI != null)) {
      this.editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(currentSelection);
      this.resourceFromSelection = currentSelection.eResource();
      boolean _equals = Objects.equal(currentSelectionURI, this.previousSelectionURI);
      if (_equals) {
        if ((treeElementToSelect != null)) {
          StructuredSelection _structuredSelection = new StructuredSelection(treeElementToSelect);
          this.treeViewer.setSelection(_structuredSelection, true);
        }
        this.pageBook.showPage(this.treeViewerComposite);
      } else {
        this.previousSelectionURI = currentSelectionURI;
        this.runCachePropertyLookupJob(currentSelectionURI, treeElementToSelect);
      }
    } else {
      synchronized (this.jobLock) {
        if ((this.cachePropertyLookupJob != null)) {
          this.cachePropertyLookupJob.cancel();
          this.cachePropertyLookupJob = null;
        }
      }
      this.pageBook.showPage(this.noPropertiesLabel);
      this.editingDomain = null;
      this.resourceFromSelection = null;
      this.previousSelectionURI = null;
    }
    EObject package_ = this.getPackageSection(currentSelection);
    this.importedPropertyGroups.clear();
    if ((package_ != null)) {
      final EList<ModelUnit> units = ((PackageSection) package_).getImportedUnits();
      for (final ModelUnit unit : units) {
        if ((unit instanceof PropertySet)) {
          EList<Property> _ownedProperties = ((PropertySet)unit).getOwnedProperties();
          for (final Property prop : _ownedProperties) {
            String _name = ((PropertySet)unit).getName();
            String _name_1 = prop.getName();
            FilterCriterion _filterCriterion = new FilterCriterion(_name, _name_1);
            this.importedPropertyGroups.add(_filterCriterion);
          }
        }
      }
      this.showOnlyImportedPropertiesAction.setEnabled(true);
    } else {
      this.showOnlyImportedPropertiesAction.setEnabled(false);
    }
  }

  private EObject getPackageSection(final EObject selection) {
    EObject _xblockexpression = null;
    {
      if ((selection == null)) {
        return null;
      }
      EObject _xifexpression = null;
      if ((selection instanceof PackageSection)) {
        return selection;
      } else {
        EObject _xifexpression_1 = null;
        if ((selection instanceof Element)) {
          EObject _xblockexpression_1 = null;
          {
            Element owner = ((Element)selection).getOwner();
            EObject _xifexpression_2 = null;
            if ((owner != null)) {
              _xifexpression_2 = this.getPackageSection(owner);
            }
            _xblockexpression_1 = _xifexpression_2;
          }
          _xifexpression_1 = _xblockexpression_1;
        }
        _xifexpression = _xifexpression_1;
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }

  <T extends Object> T safeRead(final Function1<? super ResourceSet, ? extends T> operation) {
    final Function1<Resource, T> _function = (Resource resource) -> {
      return operation.apply(resource.getResourceSet());
    };
    return this.<T>safeReadResource(_function);
  }

  <T extends Object> T safeReadResource(final Function1<? super Resource, ? extends T> operation) {
    T _xifexpression = null;
    if ((this.xtextDocument != null)) {
      _xifexpression = this.xtextDocument.<T>readOnly(new IUnitOfWork<T, XtextResource>() {
          public T exec(XtextResource arg0) {
            return operation.apply(arg0);
          }
      });
    } else {
      T _xifexpression_1 = null;
      if ((this.editingDomain instanceof TransactionalEditingDomain)) {
        T _xtrycatchfinallyexpression = null;
        try {
          _xtrycatchfinallyexpression = TransactionUtil.<T>runExclusive(((TransactionalEditingDomain)this.editingDomain), 
            new RunnableWithResult.Impl<T>() {
              @Override
              public void run() {
                this.setResult(operation.apply(AadlPropertyView.this.resourceFromSelection));
                this.setStatus(Status.OK_STATUS);
              }
            });
        } catch (final Throwable _t) {
          if (_t instanceof InterruptedException) {
            _xtrycatchfinallyexpression = operation.apply(null);
          } else {
            throw Exceptions.sneakyThrow(_t);
          }
        }
        _xifexpression_1 = _xtrycatchfinallyexpression;
      } else {
        _xifexpression_1 = operation.apply(this.resourceFromSelection);
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }

  private CachePropertyLookupJob createCachePropertyLookupJob(final URI elementURI, final Object objectToSelect) {
    Display _display = this.getSite().getShell().getDisplay();
    final Runnable _function = () -> {
      this.pageBook.showPage(this.populatingViewLabel);
    };
    final Runnable _function_1 = () -> {
      this.treeViewer.setInput(elementURI);
      if ((objectToSelect != null)) {
        StructuredSelection _structuredSelection = new StructuredSelection(objectToSelect);
        this.treeViewer.setSelection(_structuredSelection, true);
      }
      this.pageBook.showPage(this.treeViewerComposite);
    };
    return new CachePropertyLookupJob(elementURI, this, _display, this.scopeProvider, _function, _function_1);
  }

  PropertyStatus getPropertyStatus(final URI propertySetURI, final URI propertyURI) {
    final Function1<ResourceSet, PropertyStatus> _function = (ResourceSet it) -> {
      PropertyStatus _xblockexpression = null;
      {
        final URI associationURI = this.cachedPropertyAssociations.get(propertySetURI).get(propertyURI);
        PropertyStatus _xifexpression = null;
        if ((associationURI != null)) {
          PropertyStatus _xblockexpression_1 = null;
          {
            EObject _eObject = it.getEObject(associationURI, true);
            final PropertyAssociation association = ((PropertyAssociation) _eObject);
            final EObject inputElement = it.getEObject(this.getInput(), true);
            PropertyStatus _xifexpression_1 = null;
            Element _owner = association.getOwner();
            boolean _equals = Objects.equal(inputElement, _owner);
            if (_equals) {
              _xifexpression_1 = PropertyStatus.LOCAL;
            } else {
              PropertyStatus _xifexpression_2 = null;
              final Function1<ContainedNamedElement, Boolean> _function_1 = (ContainedNamedElement it_1) -> {
                NamedElement _namedElement = IterableExtensions.<ContainmentPathElement>last(it_1.getContainmentPathElements()).getNamedElement();
                return Boolean.valueOf(Objects.equal(inputElement, _namedElement));
              };
              boolean _exists = IterableExtensions.<ContainedNamedElement>exists(association.getAppliesTos(), _function_1);
              if (_exists) {
                PropertyStatus _xifexpression_3 = null;
                int _size = association.getAppliesTos().size();
                boolean _greaterThan = (_size > 1);
                if (_greaterThan) {
                  _xifexpression_3 = PropertyStatus.LOCAL_SHARED;
                } else {
                  _xifexpression_3 = PropertyStatus.LOCAL_CONTAINED;
                }
                _xifexpression_2 = _xifexpression_3;
              } else {
                _xifexpression_2 = PropertyStatus.INHERITED;
              }
              _xifexpression_1 = _xifexpression_2;
            }
            _xblockexpression_1 = _xifexpression_1;
          }
          _xifexpression = _xblockexpression_1;
        } else {
          PropertyStatus _xifexpression_1 = null;
          EObject _eObject = it.getEObject(propertyURI, true);
          PropertyExpression _defaultValue = ((Property) _eObject).getDefaultValue();
          boolean _tripleNotEquals = (_defaultValue != null);
          if (_tripleNotEquals) {
            _xifexpression_1 = PropertyStatus.DEFAULT;
          } else {
            _xifexpression_1 = PropertyStatus.UNDEFINED;
          }
          _xifexpression = _xifexpression_1;
        }
        _xblockexpression = _xifexpression;
      }
      return _xblockexpression;
    };
    return this.<PropertyStatus>safeRead(_function);
  }

  private PropertyStatus getPropertyStatusNeverUndefined(final URI associationURI) {
    PropertyStatus _xifexpression = null;
    if ((associationURI != null)) {
      final Function1<ResourceSet, PropertyStatus> _function = (ResourceSet it) -> {
        PropertyStatus _xblockexpression = null;
        {
          EObject _eObject = it.getEObject(associationURI, true);
          final PropertyAssociation association = ((PropertyAssociation) _eObject);
          final EObject inputElement = it.getEObject(this.getInput(), true);
          PropertyStatus _xifexpression_1 = null;
          Element _owner = association.getOwner();
          boolean _equals = Objects.equal(inputElement, _owner);
          if (_equals) {
            _xifexpression_1 = PropertyStatus.LOCAL;
          } else {
            PropertyStatus _xifexpression_2 = null;
            final Function1<ContainedNamedElement, Boolean> _function_1 = (ContainedNamedElement it_1) -> {
              NamedElement _namedElement = IterableExtensions.<ContainmentPathElement>last(it_1.getContainmentPathElements()).getNamedElement();
              return Boolean.valueOf(Objects.equal(inputElement, _namedElement));
            };
            boolean _exists = IterableExtensions.<ContainedNamedElement>exists(association.getAppliesTos(), _function_1);
            if (_exists) {
              _xifexpression_2 = PropertyStatus.LOCAL_CONTAINED;
            } else {
              _xifexpression_2 = PropertyStatus.INHERITED;
            }
            _xifexpression_1 = _xifexpression_2;
          }
          _xblockexpression = _xifexpression_1;
        }
        return _xblockexpression;
      };
      _xifexpression = this.<PropertyStatus>safeRead(_function);
    } else {
      _xifexpression = PropertyStatus.DEFAULT;
    }
    return _xifexpression;
  }

  PropertyStatus getPropertyStatusNeverUndefined(@Extension final ResourceSet resourceSet, final PropertyAssociation association) {
    PropertyStatus _xifexpression = null;
    if ((association == null)) {
      _xifexpression = PropertyStatus.DEFAULT;
    } else {
      PropertyStatus _xblockexpression = null;
      {
        final EObject inputElement = resourceSet.getEObject(this.getInput(), true);
        PropertyStatus _xifexpression_1 = null;
        Element _owner = association.getOwner();
        boolean _equals = Objects.equal(inputElement, _owner);
        if (_equals) {
          _xifexpression_1 = PropertyStatus.LOCAL;
        } else {
          PropertyStatus _xifexpression_2 = null;
          final Function1<ContainedNamedElement, Boolean> _function = (ContainedNamedElement it) -> {
            NamedElement _namedElement = IterableExtensions.<ContainmentPathElement>last(it.getContainmentPathElements()).getNamedElement();
            return Boolean.valueOf(Objects.equal(inputElement, _namedElement));
          };
          boolean _exists = IterableExtensions.<ContainedNamedElement>exists(association.getAppliesTos(), _function);
          if (_exists) {
            _xifexpression_2 = PropertyStatus.LOCAL_CONTAINED;
          } else {
            _xifexpression_2 = PropertyStatus.INHERITED;
          }
          _xifexpression_1 = _xifexpression_2;
        }
        _xblockexpression = _xifexpression_1;
      }
      _xifexpression = _xblockexpression;
    }
    return _xifexpression;
  }

  void runCachePropertyLookupJob(final URI elementURI, final Object objectToSelect) {
    synchronized (this.jobLock) {
      if (((this.cachePropertyLookupJob != null) && 
        (this.cachePropertyLookupJob.getState() != Job.NONE))) {
        this.cachePropertyLookupJob.cancel();
      }
      this.cachePropertyLookupJob = this.createCachePropertyLookupJob(elementURI, objectToSelect);
      this.cachePropertyLookupJob.schedule();
    }
  }
}