/**
  * Remove a monitor for a metadata object.
  *
  * @param object The metadata object who wanted to monitor a link but don't now.
  */
 public void removeMonitors(Metadata object) {
   if (object.getMetaMetadata() instanceof MetaMetadata) {
     MetaMetadata mmd = (MetaMetadata) object.getMetaMetadata();
     Map<String, LinkWith> linkWiths = mmd.getLinkWiths();
     if (linkWiths != null) {
       for (String name : linkWiths.keySet()) {
         LinkWith lw = linkWiths.get(name);
         Map<Metadata, LinkWith> collection = monitorRecords.get(lw.getName());
         // collection can't be null
         synchronized (collection) {
           collection.remove(object);
         }
       }
     }
   }
 }
  public boolean reselect(Metadata metadata) {
    if (reselectFields == null || reselectFields.isEmpty()) return false;

    for (String fieldName : reselectFields.keySet()) {
      FieldDescriptor fd =
          metadata.getMetadataClassDescriptor().getFieldDescriptorByFieldName(fieldName);
      String actualValue = fd.getValueString(metadata);
      String expectedValue = reselectFields.get(fieldName).getValue();
      if (!actualValue.equals(expectedValue)) return false;
    }
    return true;
  }
  /**
   * When a new metadata object is parsed, try to link it with some monitoring metadata objects that
   * are waiting here.
   *
   * @param repository
   * @param parsedMetadata
   * @return If the linking happens.
   */
  public boolean tryLink(MetaMetadataRepository repository, Metadata parsedMetadata) {
    if (parsedMetadata == null) {
      return false;
    }
    MetaMetadataCompositeField composite = parsedMetadata.getMetaMetadata();
    if (composite == null) {
      return false;
    }

    MetaMetadata mmd;
    String mmdName;

    if (composite instanceof MetaMetadata) {
      mmd = (MetaMetadata) composite;
      mmdName = mmd.getName();
    } else {
      mmdName = composite.getTypeName();
      mmd = repository.getMMByName(mmdName);
    }

    if (mmd == null) {
      // maybe it's defined inline -- we need a solution for this kind of inline definition thing!
      // currently you can't do metadata linking on inline-defined meta_metadata classes
      return false;
    }

    while (!monitorRecords.containsKey(mmdName)) {
      if (mmdName == null || "metadata".equals(mmdName)) return false;
      mmdName = mmd.getSuperMmdTypeName();
      mmd = repository.getMMByName(mmdName);
    }

    Map<Metadata, LinkWith> records = monitorRecords.get(mmdName);
    for (Metadata object : records.keySet()) {
      LinkWith lw = records.get(object);
      if (lw.tryLink(parsedMetadata, object)) {
        SemanticActionHandler handler = object.pendingSemanticActionHandler;
        handler.takeSemanticActions();
        return true;
      }
    }

    return false;
  }