/**
   * Provides custom completion for specifying the type of a property, taking into account the path
   * if the name is qualified
   *
   * @see
   *     org.eclipse.papyrus.uml.textedit.property.xtext.ui.contentassist.AbstractUmlPropertyProposalProvider#completeTypeRule_Type(org.eclipse.emf.ecore.EObject,
   *     org.eclipse.xtext.Assignment,
   *     org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext,
   *     org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor)
   */
  @Override
  public void completeTypeRule_Type(
      EObject model,
      Assignment assignment,
      ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {

    Namespace namespace =
        ((Property) ContextElementUtil.getContextElement(model.eResource())).getNamespace();
    if (model instanceof TypeRule) {
      TypeRule typeRule = (TypeRule) model;
      QualifiedName path = typeRule.getPath();
      while (path.getRemaining() != null) {
        path = path.getRemaining();
      }
      namespace = path.getPath();
    } else if (!(model instanceof PortRule)) {
      return;
    }
    for (NamedElement n : namespace.getOwnedMembers()) {
      if (n instanceof Classifier) {
        if (n.getName().toLowerCase().contains(context.getPrefix().toLowerCase())) {
          String completionString = n.getName();
          String displayString = n.getName();
          CustomCompletionProposal completionProposal =
              CompletionProposalUtils.createCompletionProposalWithReplacementOfPrefix(
                  n, completionString, displayString, context);
          acceptor.accept(completionProposal);
        }
      }
    }
  }
  /**
   * Returns the name of the type with its qualified name
   *
   * @param type a type
   * @return the name of the type with its qualified name
   */
  public static String getTypeLabel(Type type, Namespace model) {
    String label = ""; // $NON-NLS-1$

    List<Package> importedPackages = new ArrayList<Package>(model.getImportedPackages());

    List<Package> visitedPackages = new ArrayList<Package>();
    Package currentPackage = type.getNearestPackage();

    boolean rootFound = false;

    while (currentPackage != null && !rootFound) {
      visitedPackages.add(currentPackage);
      if (importedPackages.contains(currentPackage) || currentPackage == model) {
        rootFound = true;
      }
      Element owner = currentPackage.getOwner();
      while (owner != null && !(owner instanceof Package)) owner = owner.getOwner();

      currentPackage = owner != null ? (Package) owner : null;
    }

    for (int i = visitedPackages.size() - 1; i >= 0; i--) {
      label += visitedPackages.get(i).getName() + "::"; // $NON-NLS-1$
    }

    return label + type.getName();
  }
  /**
   * Utility methods which returns the list of classifiers that are directly or indirectly owned by
   * the namespaces imported by a context namespace
   *
   * @param context The context namespace
   * @return the list of classifiers that are directly or indirectly owned by the namespaces
   *     imported by the context namespace
   */
  private List<Classifier> getRecursivelyImportedClassifiers(Namespace context) {
    List<Classifier> recursivelyImportedClassifiers = new ArrayList<Classifier>();

    List<Package> importedPackages = context.getImportedPackages();
    for (Package p : importedPackages) {
      recursivelyImportedClassifiers.addAll(getRecursivelyOwnedClassifiers(p));
    }

    return recursivelyImportedClassifiers;
  }
 /** @generated */
 public boolean canCreateConstraintContext_8500(Constraint source, Namespace target) {
   if (source != null) {
     if (source.getContext() != null) {
       return false;
     }
   }
   if (target != null && (target.getOwnedRules().contains(target))) {
     return false;
   }
   return canExistConstraintContext_8500(source, target);
 }
 /**
  *
  * <!-- begin-user-doc -->
  * <!-- end-user-doc -->
  *
  * @generated
  */
 public Namespace getPath() {
   if (path != null && path.eIsProxy()) {
     InternalEObject oldPath = (InternalEObject) path;
     path = (Namespace) eResolveProxy(oldPath);
     if (path != oldPath) {
       if (eNotificationRequired())
         eNotify(
             new ENotificationImpl(
                 this, Notification.RESOLVE, UmlPortPackage.QUALIFIED_NAME__PATH, oldPath, path));
     }
   }
   return path;
 }
 /** @generated */
 protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info)
     throws ExecutionException {
   Constraint newElement = UMLFactory.eINSTANCE.createConstraint();
   EObject target = getElementToEdit();
   ModelAddData data = PolicyChecker.getCurrent().getChildAddData(diagram, target, newElement);
   if (data.isPermitted()) {
     if (data.isPathDefined()) {
       if (!data.execute(target, newElement))
         return CommandResult.newErrorCommandResult(
             "Failed to follow the policy-specified for the insertion of the new element");
     } else {
       Namespace qualifiedTarget = (Namespace) target;
       qualifiedTarget.getOwnedRules().add(newElement);
     }
   } else {
     return CommandResult.newErrorCommandResult(
         "The active policy restricts the addition of this element");
   }
   ElementInitializers.getInstance().init_Constraint_3008(newElement);
   doConfigure(newElement, monitor, info);
   ((CreateElementRequest) getRequest()).setNewElement(newElement);
   return CommandResult.newOKCommandResult(newElement);
 }
  /**
   * Provides custom completion for the root element in a qualified name
   *
   * @see
   *     org.eclipse.papyrus.uml.textedit.property.xtext.ui.contentassist.AbstractUmlPropertyProposalProvider#completeTypeRule_Path(org.eclipse.emf.ecore.EObject,
   *     org.eclipse.xtext.Assignment,
   *     org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext,
   *     org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor)
   */
  @Override
  public void completeTypeRule_Path(
      EObject model,
      Assignment assignment,
      ContentAssistContext context,
      ICompletionProposalAcceptor acceptor) {
    Namespace root =
        (Namespace)
            EcoreUtil.getRootContainer(ContextElementUtil.getContextElement(model.eResource()));

    if (root == null) {
      return;
    }

    // first accept the root Model
    String completionString = root.getName() + "::";
    String displayString = root.getName() + "::";
    // String displayString = c.getName() ;
    CustomCompletionProposal completionProposal =
        CompletionProposalUtils.createCompletionProposalWithReplacementOfPrefix(
            root, completionString, displayString, context);
    acceptor.accept(completionProposal);

    // then accepts all packages imported by Model
    List<Package> importedPackages = root.getImportedPackages();
    for (Package p : importedPackages) {
      if (p.getName().toLowerCase().contains(context.getPrefix().toLowerCase())) {
        completionString = p.getName() + "::";
        displayString = p.getName() + "::";
        // String displayString = c.getName() ;
        completionProposal =
            CompletionProposalUtils.createCompletionProposalWithReplacementOfPrefix(
                root, completionString, displayString, context);
        acceptor.accept(completionProposal);
      }
    }
  }
  /**
   * Utility methods wich returns the list of classifiers that are directly or indirectly owned by a
   * context namespace
   *
   * @param context The context namespace
   * @return the list of classifiers that are directly or indirectly owned by the context namespace
   */
  private List<Classifier> getRecursivelyOwnedClassifiers(Namespace context) {
    List<Classifier> recursivelyOwnedClassifiers = new ArrayList<Classifier>();

    List<Element> allOwnedElements = context.getOwnedElements();
    for (Element e : allOwnedElements) {
      if (e instanceof Classifier) {
        recursivelyOwnedClassifiers.add((Classifier) e);
      }
      if (e instanceof Namespace) {
        recursivelyOwnedClassifiers.addAll(getRecursivelyOwnedClassifiers((Namespace) e));
      }
    }

    return recursivelyOwnedClassifiers;
  }