/**
   * Constructs a handle for a model workspace item of the specified type, with the given parent
   * item and name.
   *
   * @param type - one of the constants defined in ModelWorkspaceItem
   * @exception IllegalArgumentException if the type is not one of the valid model workspace item
   *     type constants
   */
  protected ModelWorkspaceItemImpl(
      final int type, final ModelWorkspaceItem parent, final String name)
      throws IllegalArgumentException {
    if (type < MINIMUM_VALID_TYPE || type > MAXIMUM_VALID_TYPE) {
      throw new IllegalArgumentException(
          ModelerCore.Util.getString("element.invalidType")); // $NON-NLS-1$
    }

    // ArgCheck.isNotNull(name); // Should be done in subclasses, not here
    // ArgCheck.isNotZeroLength(name); // Should be done in subclasses, not here
    fType = type;
    fParent = (ModelWorkspaceItemImpl) parent;
    fName = name;
    if (fParent != null) {
      try {
        ModelWorkspaceItemInfo info = (ModelWorkspaceItemInfo) fParent.getItemInfo();
        info.addChild(this);
      } catch (ModelWorkspaceException e) {
        ModelerCore.Util.log(
            IStatus.ERROR,
            e,
            ModelerCore.Util.getString(
                "ModelWorkspaceItemImpl.Error_trying_to_create_a_modelWorksapceItem_{0}_under_the_parent_{1}_1",
                name, fParent.getItemName())); // $NON-NLS-1$
      }
    }
  }
 /** Debugging purposes */
 protected void toStringAncestors(StringBuffer buffer) {
   ModelWorkspaceItemImpl parent = (ModelWorkspaceItemImpl) this.getParent();
   if (parent != null && parent.getParent() != null) {
     buffer.append(" [in "); // $NON-NLS-1$
     parent.toStringInfo(0, buffer, NO_INFO);
     parent.toStringAncestors(buffer);
     buffer.append("]"); // $NON-NLS-1$
   }
 }
 /**
  * Removes all cached info from the Model Workspace, including all children, but does not close
  * this element.
  */
 protected void removeInfo() {
   Object info = ModelWorkspaceManager.getModelWorkspaceManager().peekAtInfo(this);
   if (info != null) {
     ModelWorkspaceItem[] children = ((ModelWorkspaceItemInfo) info).getChildren();
     for (int i = 0, size = children.length; i < size; ++i) {
       ModelWorkspaceItemImpl child = (ModelWorkspaceItemImpl) children[i];
       child.removeInfo();
     }
     ModelWorkspaceManager.getModelWorkspaceManager().removeInfo(this);
   }
 }
 /**
  * Returns the hash code for this model workspace item. By default, the hash code for an element
  * is a combination of its name and parent's hash code. Elements with other requirements must
  * override this method.
  */
 @Override
 public int hashCode() {
   if (fParent == null) {
     return super.hashCode();
   }
   return HashCodeUtil.hashCode(fParent.hashCode(), fName.hashCode());
 }
 /** @see Openable */
 public void close() throws ModelWorkspaceException {
   this.closing = true;
   boolean wasVerbose = ModelWorkspaceManager.VERBOSE;
   try {
     Object info = ModelWorkspaceManager.getModelWorkspaceManager().peekAtInfo(this);
     if (info != null) {
       if (ModelWorkspaceManager.VERBOSE) {
         System.out.println(
             "CLOSING Element ("
                 + Thread.currentThread()
                 + "): "
                 + this.toStringWithAncestors()); // $NON-NLS-1$//$NON-NLS-2$
         wasVerbose = true;
         ModelWorkspaceManager.VERBOSE = false;
       }
       ModelWorkspaceItem[] children = ((ModelWorkspaceItemInfo) info).getChildren();
       for (int i = 0, size = children.length; i < size; ++i) {
         ModelWorkspaceItemImpl child = (ModelWorkspaceItemImpl) children[i];
         child.close();
       }
       closing(info);
       ModelWorkspaceManager.getModelWorkspaceManager().removeInfo(this);
       if (wasVerbose) {
         System.out.println(
             "-> Package cache size = "
                 + ModelWorkspaceManager.getModelWorkspaceManager()
                     .cache
                     .pkgSize()); //$NON-NLS-1$
       }
     }
   } catch (ModelWorkspaceException e) {
     throw e;
   } catch (Throwable t) {
     ModelerCore.Util.log(t);
   } finally {
     ModelWorkspaceManager.VERBOSE = wasVerbose;
     this.closing = false;
   }
 }
  /**
   * Returns true if this handle represents the same model workspace item as the given handle. By
   * default, two handles represent the same element if they are identical or if they represent the
   * same type of element, have equal names, parents, and occurrence counts.
   *
   * <p>If a subclass has other requirements for equality, this method must be overridden.
   *
   * @see Object#equals
   */
  @Override
  public boolean equals(Object o) {

    if (this == o) return true;

    // Model parent is null
    if (fParent == null) return super.equals(o);

    if (o instanceof ModelWorkspaceItemImpl) {
      ModelWorkspaceItemImpl other = (ModelWorkspaceItemImpl) o;
      if (fType != other.fType) return false;

      return fName.equals(other.fName)
          && fParent.equals(other.fParent)
          && occurrenceCount == other.occurrenceCount;
    }
    return false;
  }