/**
  * return the root package from an element
  *
  * @param elem the element
  * @return the root package
  */
 protected org.eclipse.uml2.uml.Package getToPackage(Element elem) {
   org.eclipse.uml2.uml.Package tmp = elem.getNearestPackage();
   while (tmp.getOwner() != null && (tmp.getOwner() instanceof Package)) {
     tmp = (org.eclipse.uml2.uml.Package) tmp.getOwner();
   }
   return tmp;
 }
  /**
   * 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();
  }
  /**
   * Check if controlled sub-packages can be correctly updated : - Check if controlled package is
   * loaded - Change the control strategy if necessary - Report error if the controlled package is
   * read-only
   *
   * @param controlledPackages the controlled sub-packages (may be updated if contains proxies)
   * @return true if can be updated
   */
  private boolean checkControlledPackagesUpdateable(Set<Package> controlledPackages) {
    boolean notLoadedPackages = false;
    StringBuffer notLoadedPackagesList = new StringBuffer();
    boolean readOnlyPackages = false;
    StringBuffer readOnlyPackagesList = new StringBuffer();
    // Check if controlled package is loaded
    for (Iterator<Package> iterator = controlledPackages.iterator(); iterator.hasNext(); ) {
      Package pack = iterator.next();
      EditingDomain domain = EditorUtils.getTransactionalEditingDomain();
      if (pack.eIsProxy()) {
        EObject loadedObject =
            domain.getResourceSet().getEObject(((InternalEObject) pack).eProxyURI(), true);
        if (loadedObject != null) {
          // pack has been reload, replace proxy;
          controlledPackages.remove(pack);
          pack = (Package) loadedObject;
          controlledPackages.add(pack);
        }
      }
      if (pack.eIsProxy()) {
        notLoadedPackages = true;
        URI uri = ((InternalEObject) pack).eProxyURI();
        String uriLastSeg = uri.lastSegment();
        String name =
            uriLastSeg.substring(0, uriLastSeg.length() - uri.fileExtension().length() - 1);
        String qualifName =
            EMFCoreUtil.getQualifiedName(pack.getOwner(), true)
                .concat("::")
                .concat(name); // $NON-NLS-1$
        notLoadedPackagesList.append(String.format(ENTRY_FORMAT, qualifName));
      } else {
        if (domain instanceof AdapterFactoryEditingDomain) {
          // reset read-only cache map
          ((AdapterFactoryEditingDomain) domain).getResourceToReadOnlyMap().clear();
        }
        if (domain.isReadOnly(pack.eResource())) {
          readOnlyPackages = true;
          String name = EMFCoreUtil.getQualifiedName(pack, true);
          readOnlyPackagesList.append(String.format(ENTRY_FORMAT, name));
        }
      }
    }
    // Report error if the controlled package is read-only
    if (readOnlyPackages) {
      String msg = NLS.bind(Messages.error_readonly, readOnlyPackagesList.toString());
      NotificationBuilder notifBuild = NotificationBuilder.createErrorPopup(msg);
      notifBuild.setHTML(true);
      notifBuild.run();
      return false;
    }
    // Change the control strategy if necessary
    if (notLoadedPackages) {
      String msg = NLS.bind(Messages.switch_loading_strategy, notLoadedPackagesList.toString());
      final BooleanResult stategyChanged = new BooleanResult();
      Runnable runStrategySwitch =
          new Runnable() {

            public void run() {
              StrategyChooser.setCurrentStrategy(LOAD_ALL_STRATEGY);
              stategyChanged.setValue(true);
            }
          };
      Runnable cancel =
          new Runnable() {

            public void run() {
              stategyChanged.setValue(false);
            }
          };
      NotificationBuilder notifBuild =
          NotificationBuilder.createYesNo(msg, runStrategySwitch, cancel);
      notifBuild.setHTML(true);
      notifBuild.setAsynchronous(false);
      notifBuild.run();
      if (stategyChanged.getValue()) {
        // refresh set controlledPackages
        return checkControlledPackagesUpdateable(controlledPackages);
      } else {
        return false;
      }
    }
    return true;
  }