text: #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertexContainer.h"
  #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h"
  #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
  
  typedef edm::RefVector<edm::HepMCProduct, HepMC::GenVertex> GenVertexRefVector;
  typedef edm::Ref<edm::HepMCProduct, HepMC::GenVertex> GenVertexRef;
  
  // Constructors
  
  TrackingVertex::TrackingVertex() : position_(LorentzVector(0, 0, 0, 0)), eId_(0) {
    //  daughterTracks_.clear();
  }
  
  TrackingVertex::TrackingVertex(const LorentzVector& p, const bool inVolume, const EncodedEventId eId)
      : position_(p), inVolume_(inVolume), eId_(eId) {
    //  daughterTracks_.clear();
  }
  
  // Add a reference to vertex vectors
  
  void TrackingVertex::addG4Vertex(const SimVertex& v) { g4Vertices_.push_back(v); }
  
  void TrackingVertex::addGenVertex(const GenVertexRef& ref) { genVertices_.push_back(ref); }
  
  // Add a reference to track vectors
  
  void TrackingVertex::addDaughterTrack(const TrackingParticleRef& ref) { daughterTracks_.push_back(ref); }
  
  void TrackingVertex::addParentTrack(const TrackingParticleRef& ref) { sourceTracks_.push_back(ref); }
  
  void TrackingVertex::clearDaughterTracks() { daughterTracks_.clear(); }
  
  void TrackingVertex::clearParentTracks() { sourceTracks_.clear(); }
  
  // Iterators over vertices and tracks
  
  TrackingVertex::genv_iterator TrackingVertex::genVertices_begin() const { return genVertices_.begin(); }
  TrackingVertex::genv_iterator TrackingVertex::genVertices_end() const { return genVertices_.end(); }
  TrackingVertex::g4v_iterator TrackingVertex::g4Vertices_begin() const { return g4Vertices_.begin(); }
  TrackingVertex::g4v_iterator TrackingVertex::g4Vertices_end() const { return g4Vertices_.end(); }
  
  TrackingVertex::tp_iterator TrackingVertex::daughterTracks_begin() const { return daughterTracks_.begin(); }
  TrackingVertex::tp_iterator TrackingVertex::daughterTracks_end() const { return daughterTracks_.end(); }
  TrackingVertex::tp_iterator TrackingVertex::sourceTracks_begin() const { return sourceTracks_.begin(); }
  TrackingVertex::tp_iterator TrackingVertex::sourceTracks_end() const { return sourceTracks_.end(); }
  
  // Accessors for whole vectors
  
  const std::vector<SimVertex>& TrackingVertex::g4Vertices() const { return g4Vertices_; }
  const GenVertexRefVector& TrackingVertex::genVertices() const { return genVertices_; }
  const TrackingParticleRefVector& TrackingVertex::sourceTracks() const { return sourceTracks_; }
  const TrackingParticleRefVector& TrackingVertex::daughterTracks() const { return daughterTracks_; }
  
  std::ostream& operator<<(std::ostream& s, const TrackingVertex& v) {
    using std::endl;
    typedef GenVertexRefVector::iterator genv_iterator;
    typedef std::vector<SimVertex>::const_iterator g4v_iterator;
    typedef TrackingParticleRefVector::iterator tp_iterator;
    typedef std::vector<SimTrack>::const_iterator g4t_iterator;
  
    s << "Vertex Position & Event #" << v.position() << " " << v.eventId().bunchCrossing() << "." << v.eventId().event()
      << endl;
    s << " Associated with " << v.daughterTracks().size() << " tracks" << endl;
    for (genv_iterator genV = v.genVertices_begin(); genV != v.genVertices_end(); ++genV) {
      s << " HepMC vertex position " << (*(*genV)).position().x() << "," << (*(*genV)).position().y()
        << (*(*genV)).position().z() << endl;
    }
  
    for (g4v_iterator g4V = v.g4Vertices_begin(); g4V != v.g4Vertices_end(); ++g4V) {
      s << " Geant vertex position " << (*g4V).position() << endl;
      // Probably empty all the time, currently
    }
  
    // Loop over daughter track(s)
    for (tp_iterator iTP = v.daughterTracks_begin(); iTP != v.daughterTracks_end(); ++iTP) {
      s << " Daughter starts:      " << (*(*iTP)).vertex();
      for (g4t_iterator g4T = (*(*iTP)).g4Track_begin(); g4T != (*(*iTP)).g4Track_end(); ++g4T) {
        s << " p " << g4T->momentum();
      }
      s << endl;
    }
  
    // Loop over source track(s) (can be multiple since vertices are collapsed)
    for (tp_iterator iTP = v.sourceTracks_begin(); iTP != v.sourceTracks_end(); ++iTP) {
      s << " Source   starts: " << (*(*iTP)).vertex();
      for (g4t_iterator g4T = (*iTP)->g4Track_begin(); g4T != (*iTP)->g4Track_end(); ++g4T) {
        s << ", p " << g4T->momentum();
      }
      s << endl;
    }
    return s;
  }
  