public void endElement(
     String namespaceURI,
     String sName, // simple name
     String qName // qualified name
     ) throws SAXException {
   String element = qName;
   if (element.compareToIgnoreCase("presence") == 0) {}
   if (element.compareToIgnoreCase("presentity") == 0) {
     presenceTag.setPresentityTag(presentityTag);
   }
   if (element.compareToIgnoreCase("tuple") == 0) {
     presenceTag.addTupleTag(tupleTag);
   }
   if (element.compareToIgnoreCase("status") == 0) {
     tupleTag.setStatusTag(statusTag);
   }
   if (element.compareToIgnoreCase("basic") == 0) {
     statusTag.setBasicTag(basicTag);
   }
   if (element.compareToIgnoreCase("contact") == 0) {
     tupleTag.setContactTag(contactTag);
   }
   if (element.compareToIgnoreCase("note") == 0) {
     tupleTag.setNoteTag(noteTag);
   }
 }
  /**
   * Returns a {@link PCollectionTuple} with each of the given tags mapping to a new output {@link
   * PCollection}.
   *
   * <p>For use by primitive transformations only.
   */
  public static PCollectionTuple ofPrimitiveOutputsInternal(
      Pipeline pipeline,
      TupleTagList outputTags,
      WindowingStrategy<?, ?> windowingStrategy,
      IsBounded isBounded) {
    Map<TupleTag<?>, PCollection<?>> pcollectionMap = new LinkedHashMap<>();
    for (TupleTag<?> outputTag : outputTags.tupleTags) {
      if (pcollectionMap.containsKey(outputTag)) {
        throw new IllegalArgumentException("TupleTag already present in this tuple");
      }

      // In fact, `token` and `outputCollection` should have
      // types TypeDescriptor<T> and PCollection<T> for some
      // unknown T. It is safe to create `outputCollection`
      // with type PCollection<Object> because it has the same
      // erasure as the correct type. When a transform adds
      // elements to `outputCollection` they will be of type T.
      @SuppressWarnings("unchecked")
      TypeDescriptor<Object> token = (TypeDescriptor<Object>) outputTag.getTypeDescriptor();
      PCollection<Object> outputCollection =
          PCollection.createPrimitiveOutputInternal(pipeline, windowingStrategy, isBounded)
              .setTypeDescriptorInternal(token);

      pcollectionMap.put(outputTag, outputCollection);
    }
    return new PCollectionTuple(pipeline, pcollectionMap);
  }
 @Override
 public void recordAsOutput(AppliedPTransform<?, ?, ?> transform) {
   int i = 0;
   for (Map.Entry<TupleTag<?>, PCollection<?>> entry : pcollectionMap.entrySet()) {
     TupleTag<?> tag = entry.getKey();
     PCollection<?> pc = entry.getValue();
     pc.recordAsOutput(transform, tag.getOutName(i));
     i++;
   }
 }
 public void startElement(
     String namespaceURI,
     String lName, // local name
     String qName, // qualified name
     Attributes attrs)
     throws SAXException {
   element = qName;
   if (element.compareToIgnoreCase("presence") == 0) {
     presenceTag = new PresenceTag();
     String entity = attrs.getValue("entity").trim();
     presenceTag.setEntity(entity);
   }
   if (element.compareToIgnoreCase("presentity") == 0) {
     presentityTag = new PresentityTag();
     String id = attrs.getValue("id").trim();
     presentityTag.setId(id);
   }
   if (element.compareToIgnoreCase("tuple") == 0) {
     tupleTag = new TupleTag();
     String id = attrs.getValue("id").trim();
     tupleTag.setId(id);
   }
   if (element.compareToIgnoreCase("status") == 0) {
     statusTag = new StatusTag();
   }
   if (element.compareToIgnoreCase("basic") == 0) {
     basicTag = new BasicTag();
   }
   if (element.compareToIgnoreCase("contact") == 0) {
     contactTag = new ContactTag();
     String priority = attrs.getValue("priority").trim();
     if (priority != null) {
       try {
         contactTag.setPriority(Float.parseFloat(priority));
       } catch (Exception e) {
         e.printStackTrace();
       }
     }
   }
   if (element.compareToIgnoreCase("note") == 0) {
     noteTag = new NoteTag();
   }
 }