private void emitReferencedValue(AttributeList attrs) throws SAXException {
    if (expectingTarget) {
      String previousElement = "";
      if (!elementStack.empty()) {
        previousElement = (String) elementStack.peek();
      }

      int prevSrxId = XmiMapping.getSrxId(previousElement);
      // enabledOutput = toProcess(prevSrxId);
      if (!enabledOutput) {
        return;
      }

      if (attrs != null) {
        for (int i = 0; i < attrs.getLength(); i++) {
          String attr = attrs.getName(i);
          if (attr.equals(kTarget)) {
            String key = attrs.getValue(i);
            String name = (String) idTable.get(key);
            if (name != null) {
              emit(name + eol);
            }
            expectingTarget = false;
          }
        } // end for
      } // end if
    } // end if
  } // end emitReferencedValue()
  public void endElement(String name) throws SAXException {
    if (isDebug) emit("end element" + eol); // NOT LOCALIZABLE

    if (!elementStack.empty()) {
      String removed = (String) elementStack.pop();

      if (name.equals(kTaggedValue)) {
        taggedValueMode = false;
      }

      // is the element removed a concept (as table, column, etc.)?
      int removedSrxId = XmiMapping.getSrxId(removed);
      if (removedSrxId != XmiMapping.UNKNOWN) {
        // does this concept have an identifier?
        String xmiName = XmiMapping.getXmiName(removedSrxId);
        if (!xmiName.equals("")) {
          if (!occurrenceNameStack.empty()) {
            occurrenceNameStack.pop(); // yes, so pop its name
          }
        }
      } // end if
    } // end if
  } // end endElement()
  private void emitNewTag(String tag) throws SAXException {
    String previousElement = null;

    // retrieve the actual previous element
    int index = elementStack.size();
    while (previousElement == null) {
      if (!elementStack.empty()) {
        index--;
        previousElement = (String) elementStack.elementAt(index);
      } else {
        previousElement = ""; // exit, to avoid endless loop
      }

      if (previousElement.equals(kTag)
          || previousElement.equals(kTaggedValue)
          || previousElement.equals(ktaggedValue)) {
        previousElement = null; // continue to search
      }
    }

    // ignore if not known in Srx format
    int prevSrxId = XmiMapping.getSrxId(previousElement);
    if (!enabledOutput) {
      return;
    }

    if (prevSrxId != XmiMapping.UNKNOWN) {
      int attrId = XmiMapping.getAttrId(prevSrxId, tag);
      if (attrId != XmiMapping.UNKNOWN) {
        String mappedAttr = XmiMapping.getMappedAttr(prevSrxId, attrId);
        emit(mappedAttr + " ");
        tagFound = true;
      }
    }

    expectingTarget = true;
  }
  private void emitNewOccurrence(int srxId, AttributeList attrs) throws SAXException {

    enabledOutput = toProcess(srxId);
    if (!enabledOutput) {
      return;
    }

    currentSrxId = srxId;
    String mappedName = XmiMapping.getMappingName(srxId);
    emit(eol + kOccurrenceType + " " + mappedName + eol);

    // if it's a component, write its composite
    String composite = XmiMapping.getComposite(srxId);
    if (composite != null) {
      if (!occurrenceNameStack.empty()) {
        String compositeName = (String) occurrenceNameStack.peek();
        if (compositeName != null) {
          emit(composite + " " + compositeName + eol);
        }
      } // end if
    } // end if

    // Keep its XMI.id
    if (attrs != null) {
      for (int i = 0; i < attrs.getLength(); i++) {
        String attr = attrs.getName(i);
        if (attr.equals(kXmiId)) {
          currentXmiId = attrs.getValue(i);
        } // end if
      } // end for
    } // end if

    // Keep its current XMI name & SRX name
    currentXmiName = XmiMapping.getXmiName(srxId);
    currentSrxName = XmiMapping.getSrxName(srxId);
  }
  public void startElement(String tag, AttributeList attrs) throws SAXException {
    if (isDebug) emit("start element" + eol); // NOT LOCALIZABLE

    // keep previous element before adding a new one
    String previousElement = "";
    if (!elementStack.empty()) {
      previousElement = (String) elementStack.peek();
    }

    elementStack.push(tag);

    if (tag.equals(kTaggedValue)) {
      taggedValueMode = true;
      return;
    }

    // ignore <tag> and <value> if outside a <TaggedValue> block
    if (taggedValueMode) {
      if (tag.equals(kTag)) {
        expectingTag = true;
      } else if (tag.equals(kValue)) {
        expectingTagValue = true;
      }
    }

    int srxId = XmiMapping.getSrxId(tag);
    boolean isOccurrenceType = (srxId != XmiMapping.UNKNOWN);

    if (isOccurrenceType) {
      emitNewOccurrence(srxId, attrs);
    } else {

      if (!enabledOutput) {
        return;
      }

      // if tag = 'NAME' and currentXmiName expected is also 'NAME'
      if (tag.equals(currentXmiName)) {
        // ignore if not known in Srx format
        int prevSrxId = XmiMapping.getSrxId(previousElement);
        if (prevSrxId != XmiMapping.UNKNOWN) {
          expectingNameValue = true;
        }
      } else if (tag.equals(kXmiReference)) {
        emitReferencedValue(attrs);
      } else {
        // ignore if not known in Srx format
        int prevSrxId = XmiMapping.getSrxId(previousElement);
        if (currentSrxId != XmiMapping.UNKNOWN) {
          int attrId = XmiMapping.getAttrId(currentSrxId, tag);
          if (attrId != XmiMapping.UNKNOWN) {
            String mappedAttr = XmiMapping.getMappedAttr(currentSrxId, attrId);

            if (mappedAttr.equals(MULTIPLICITY)) {
              // Special case for multiplicity
              expectingMultiplicity = true;
            } else if (mappedAttr.equals(ORIGINTABLE)) {
              // Special case for origin table
              expectingOriginTable = true;
              expectingTarget = true;
            } else if (mappedAttr.equals(TARGETTABLE)) {
              // Special case for target table
              expectingTargetTable = true;
              expectingTarget = true;
            } else {
              emit(mappedAttr + " ");
              expectingTarget = true;
            } // end if
          } // end if
        } // end if
      } // end if
    } // end if
  } // end startElement()