code: private void reset() {
      elements.clear();
      for(ImageElement e : elementsToTrack) 
        elements.put(e, null);
      
    }
    
    @Override
    void leaveEnclosingElement() throws IOException {
      ImageElement elem = elemQ.pop();
      // If we're done with a block, write out our results and start over
      if (elem == ImageElement.BLOCK) {
        writeLine();
        reset();
      } else if (elem == ImageElement.INODE) {
        super.rollIfNeeded();
      }
    }
  
    /**
     * Iterate through all the elements we're tracking and, if a value was
     * recorded for it, write it out.
     */
    private void writeLine() throws IOException {
      Iterator<ImageElement> it = elementsToTrack.iterator();
      
      while(it.hasNext()) {
        ImageElement e = it.next();
        String v = elements.get(e);
        if(v != null)
          write(v);
        else 
          write(defaultValue);
        if(it.hasNext())
          write(delimiter);
      }
      write("\n");
    }
  
    @Override
    void visit(ImageElement element, String value) throws IOException {
      if(elements.containsKey(element))
        elements.put(element, value);
      if (element.equals(ImageElement.GENERATION_STAMP)
          && (elemQ.element() == null ||
              !elemQ.element().equals(ImageElement.BLOCK))) {
        // Write fake block with current namenode generation stamp
        writeLine();
      }
    }
  
    @Override
    void visitEnclosingElement(ImageElement element) throws IOException {
      elemQ.push(element);
    }
  
    @Override
    void visitEnclosingElement(ImageElement element, ImageElement key,
        String value) throws IOException {
      elemQ.push(element);
    }
    
    @Override
    void start() throws IOException { /* Nothing to do */ }
  }
docs: Reset the values of the elements we're tracking in order to handle
  the next file