Index: trunk/Utilities/HepMC/interface/Flow.h
===================================================================
--- trunk/Utilities/HepMC/interface/Flow.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/Flow.h	(revision 572)
@@ -179,5 +179,6 @@
     inline void Flow::clear() { m_icode.clear(); }
     inline bool Flow::erase( int code_index ) {
-	return (bool)m_icode.erase( code_index );
+	// this will return true if the number of elements removed is nonzero
+	return m_icode.erase( code_index )==0 ? false : true ;
     }
     inline Flow::iterator Flow::begin() { return m_icode.begin(); }
Index: trunk/Utilities/HepMC/interface/GenCrossSection.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenCrossSection.h	(revision 572)
+++ trunk/Utilities/HepMC/interface/GenCrossSection.h	(revision 572)
@@ -0,0 +1,116 @@
+#ifndef HEPMC_GEN_CROSS_SECTION_H
+#define HEPMC_GEN_CROSS_SECTION_H
+
+//--------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////
+// garren@fnal.gov, May 2009
+// 
+//////////////////////////////////////////////////////////////////////////
+//--------------------------------------------------------------------------
+
+#include <iostream>
+
+namespace HepMC {
+
+//! The GenCrossSection class stores the generated cross section
+
+///
+/// \class  GenCrossSection
+/// HepMC::GenCrossSection is used to store the generated cross section.
+/// This class is meant to be used to pass, on an event by event basis,
+/// the current best guess of the total cross section. 
+/// It is expected that the final cross section will be stored elsewhere.
+///
+///   - double cross_section;  		// cross section in pb
+///   - double cross_section_error;  	// error associated with this cross section   
+/// 
+/// The units of cross_section and cross_section_error are expected to be pb.
+/// 
+/// GenCrossSection information will be written if GenEvent contains a pointer 
+/// to a valid GenCrossSection object.
+///
+class GenCrossSection {
+
+public:
+  GenCrossSection()
+    : m_cross_section(0),
+      m_cross_section_error(0),
+      m_is_set(false)
+    {}
+  ~GenCrossSection() {}
+
+  GenCrossSection( GenCrossSection const & orig ); //!< copy
+
+  void swap( GenCrossSection & other); //!< swap
+  GenCrossSection &  operator = ( GenCrossSection const & rhs ); //!< shallow
+  /// check for equality
+  bool         operator==( const GenCrossSection& ) const;
+  /// check for inequality
+  bool         operator!=( const GenCrossSection& ) const;
+
+
+  // ---  accessors:
+
+  /// cross section in pb
+  double cross_section()          const { return m_cross_section; }
+  /// error associated with this cross section in pb
+  double cross_section_error()    const { return m_cross_section_error; }
+
+  /// True if the cross section has been set.  False by default.
+  bool   is_set()                 const { return m_is_set; }
+
+  // ---  mutators:
+  /// Set cross section and error in pb
+  void   set_cross_section( double xs, double xs_err );
+  /// set cross section in pb
+  void   set_cross_section( double );
+  /// set error associated with this cross section in pb
+  void   set_cross_section_error( double );
+  /// Clear all GenCrossSection info 
+  /// (disables output of GenCrossSection until the cross section is set again)
+  void   clear();
+ 
+  // ---  I/O:
+  /// write to an output stream
+  std::ostream &  write( std::ostream & ) const;
+  /// read from an input stream
+  std::istream &  read( std::istream & );
+
+private: // data members
+    double m_cross_section;
+    double m_cross_section_error;
+    bool   m_is_set;
+
+};
+
+//
+// streaming I/O
+
+inline std::ostream & operator << ( std::ostream & os, GenCrossSection & xs )
+{ return xs.write(os); }
+
+inline std::istream & operator >> ( std::istream & is, GenCrossSection & xs )
+{ return xs.read(is); }
+
+//
+// inline methods
+
+inline void GenCrossSection::set_cross_section( double xs, double xserr ) { 
+  set_cross_section(xs);
+  set_cross_section_error(xserr); 
+}
+
+inline void GenCrossSection::set_cross_section( double xs )        
+{
+  m_cross_section = xs;
+  m_is_set = true;
+}
+
+inline void GenCrossSection::set_cross_section_error( double xserr )  
+{
+  m_cross_section_error = xserr;
+}
+
+} // HepMC
+
+#endif  // HEPMC_GEN_CROSS_SECTION_H
Index: trunk/Utilities/HepMC/interface/GenEvent.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenEvent.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/GenEvent.h	(revision 572)
@@ -119,4 +119,8 @@
 //   parent_event() return value will return a pointer to the event which owns
 //   it (or null if its an orphan).
+// - Please note that the barcodes are intended for internal use within HepMC 
+//   as a unique identifier for the particles and vertices.
+//   Using the barcode to encode extra information is an abuse of 
+//   the barcode data member and causes confusion among users. 
 // 
 
@@ -124,7 +128,9 @@
 #include "GenParticle.h"
 #include "WeightContainer.h"
+#include "GenCrossSection.h"
 #include "HeavyIon.h"
 #include "PdfInfo.h"
 #include "Units.h"
+#include "HepMCDefs.h"
 #include <map>
 #include <string>
@@ -134,4 +140,9 @@
 
 namespace HepMC {
+
+    class GenEventVertexRange;
+    class ConstGenEventVertexRange;
+    class GenEventParticleRange;
+    class ConstGenEventParticleRange;
 
     //! The GenEvent class is the core of HepMC
@@ -146,5 +157,5 @@
 	friend class GenVertex;  
     public:
-        /// default constructor creates null pointers to HeavyIon and PdfInfo
+        /// default constructor creates null pointers to HeavyIon, PdfInfo, and GenCrossSection
 	GenEvent( int signal_process_id = 0, int event_number = 0,
 		  GenVertex* signal_vertex = 0,
@@ -202,4 +213,7 @@
 	/// pair of pointers to the two incoming beam particles
 	std::pair<HepMC::GenParticle*,HepMC::GenParticle*> beam_particles() const;
+	/// check GenEvent for validity
+	/// A GenEvent is presumed valid if it has particles and/or vertices.
+	bool is_valid() const;
 
 	/// direct access to the weights container is allowed. 
@@ -211,9 +225,12 @@
 	const WeightContainer&  weights() const; //!< direct access to WeightContainer
 
+	/// access the GenCrossSection container if it exists
+	GenCrossSection const *     cross_section() const;
+	GenCrossSection*            cross_section();
 	/// access the HeavyIon container if it exists
-	HeavyIon const *          heavy_ion() const;
+	HeavyIon const *         heavy_ion() const;
 	HeavyIon*                heavy_ion();
 	/// access the PdfInfo container if it exists
-	PdfInfo const *           pdf_info() const;
+	PdfInfo const *          pdf_info() const;
 	PdfInfo*                 pdf_info();
 
@@ -230,5 +247,11 @@
 	bool    vertices_empty() const;
 
+	/// Write the unit information to an output stream.  
+	/// If the output stream is not defined, use std::cout.
         void write_units( std::ostream & os = std::cout ) const; 
+	/// If the cross section is defined,
+	/// write the cross section information to an output stream.  
+	/// If the output stream is not defined, use std::cout.
+	void write_cross_section( std::ostream& ostr = std::cout ) const;
 
 	/// Units used by the GenParticle momentum FourVector.
@@ -236,4 +259,7 @@
 	/// Units used by the GenVertex position FourVector.
 	Units::LengthUnit   length_unit()   const;
+	
+	std::ostream& write(std::ostream&);
+	std::istream& read(std::istream&);
 
 	/////////////////////
@@ -261,4 +287,6 @@
 	void set_random_states( const std::vector<long>& randomstates );
 
+	/// provide a pointer to the GenCrossSection container
+	void set_cross_section( const GenCrossSection& );
 	/// provide a pointer to the HeavyIon container
 	void set_heavy_ion( const HeavyIon& ion );
@@ -271,4 +299,13 @@
 	/// the string must match the enum exactly
         void use_units( std::string&, std::string& );
+	
+	/// vertex range
+	GenEventVertexRange vertex_range();
+	/// vertex range
+	ConstGenEventVertexRange vertex_range() const;
+	/// particle range
+	GenEventParticleRange particle_range();
+	/// particle range
+	ConstGenEventParticleRange particle_range() const;
 
     public:
@@ -320,4 +357,9 @@
 	    std::map<int,HepMC::GenVertex*,std::greater<int> >::const_iterator 
 	                                                        m_map_iterator;
+	private:
+	    /// Pre-fix increment -- is not allowed
+	    vertex_const_iterator&  operator--(void);
+	    /// Post-fix increment -- is not allowed
+	    vertex_const_iterator   operator--(int);
 	};
 	friend class vertex_const_iterator;
@@ -377,4 +419,10 @@
 	    std::map<int,HepMC::GenVertex*,std::greater<int> >::iterator 
 	                                                       m_map_iterator;
+	private:
+	    /// Pre-fix increment
+	    vertex_iterator&  operator--(void);
+	    /// Post-fix increment
+	    vertex_iterator   operator--(int);
+
 	};
 	friend class vertex_iterator;
@@ -439,4 +487,9 @@
 	    /// const iterator to the GenParticle map
 	    std::map<int,HepMC::GenParticle*>::const_iterator m_map_iterator;
+	private:
+	    /// Pre-fix increment
+	    particle_const_iterator&  operator--(void);
+	    /// Post-fix increment
+	    particle_const_iterator   operator--(int);
 	};	
 	friend class particle_const_iterator;
@@ -492,4 +545,9 @@
 	    /// iterator for GenParticle map
 	    std::map<int,HepMC::GenParticle*>::iterator m_map_iterator;
+	private:
+            /// Pre-fix increment
+	    particle_iterator&  operator--(void);
+            /// Post-fix increment
+	    particle_iterator   operator--(int);
 	};
 	friend class particle_iterator;
@@ -526,4 +584,24 @@
 	bool use_length_unit( Units::LengthUnit );
 	bool use_length_unit( std::string& );
+	
+	// the following internal methods are used by read() and write()
+
+	/// send the beam particles to ASCII output
+	std::ostream & write_beam_particles( std::ostream &, 
+                	     std::pair<HepMC::GenParticle *,HepMC::GenParticle *> );
+	/// send a GenVertex to ASCII output
+	std::ostream & write_vertex( std::ostream &, GenVertex const * );
+	/// send a GenParticle to ASCII output
+	std::ostream & write_particle( std::ostream&, GenParticle const * );
+	/// find the file type
+	std::istream & find_file_type( std::istream & );
+	/// find the key at the end of the block
+	std::istream & find_end_key( std::istream &, int & );
+        /// get unit information from ASCII input
+        std::istream & read_units( std::istream & );
+	/// get weight names from ASCII input
+        std::istream & read_weight_names( std::istream & );
+	/// read the event header line
+        std::istream & process_event_line( std::istream &, int &, int &, int &, int & );
 
     private: // data members
@@ -544,4 +622,5 @@
 	std::map< int,HepMC::GenVertex*,std::greater<int> >   m_vertex_barcodes;
 	std::map< int,HepMC::GenParticle*,std::less<int> >    m_particle_barcodes;
+	GenCrossSection*         m_cross_section; 	      // undefined by default
 	HeavyIon*             m_heavy_ion; 	      // undefined by default
 	PdfInfo*              m_pdf_info; 	      // undefined by default
@@ -549,6 +628,22 @@
 	Units::LengthUnit     m_position_unit;    // default value set by configure switch
 
-	//static unsigned int   s_counter;
     };
+
+
+    ///////////////////////////
+    // IO Free Functions     //
+    ///////////////////////////
+  
+    /// standard streaming IO output operator
+    std::ostream & operator << (std::ostream &, GenEvent &);
+    /// standard streaming IO input operator
+    std::istream & operator >> (std::istream &, GenEvent &);
+    /// set the units for this input stream
+    std::istream & set_input_units(std::istream &, 
+                                   Units::MomentumUnit, Units::LengthUnit);
+    /// Explicitly write the begin block lines that IO_GenEvent uses
+    std::ostream & write_HepMC_IO_block_begin(std::ostream & );
+    /// Explicitly write the end block line that IO_GenEvent uses
+    std::ostream & write_HepMC_IO_block_end(std::ostream & );
 
 
@@ -596,4 +691,10 @@
     inline const WeightContainer& GenEvent::weights() const 
     { return m_weights; }
+
+    inline GenCrossSection const * GenEvent::cross_section() const 
+    { return m_cross_section; }
+
+    inline GenCrossSection*  GenEvent::cross_section()  
+    { return m_cross_section; }
 
     inline HeavyIon const * GenEvent::heavy_ion() const 
@@ -639,9 +740,21 @@
     }
 
+    inline void GenEvent::set_cross_section( const GenCrossSection& xs )
+    { 
+        delete m_cross_section;
+        m_cross_section = new GenCrossSection(xs); 
+    }
+
     inline void GenEvent::set_heavy_ion( const HeavyIon& ion )
-    { m_heavy_ion = new HeavyIon(ion); }
+    { 
+        delete m_heavy_ion;
+        m_heavy_ion = new HeavyIon(ion); 
+    }
 
     inline void GenEvent::set_pdf_info( const PdfInfo& p )
-    { m_pdf_info = new PdfInfo(p); }
+    { 
+        delete m_pdf_info;
+        m_pdf_info = new PdfInfo(p); 
+    }
 
     inline void GenEvent::set_random_states( const std::vector<long>&
@@ -649,5 +762,5 @@
     { m_random_states = randomstates; }
 
-    inline void GenEvent::remove_barcode( HepMC::GenParticle* p )
+    inline void GenEvent::remove_barcode( GenParticle* p )
     { m_particle_barcodes.erase( p->barcode() ); }
 
@@ -668,4 +781,9 @@
     /// The barcodes are chosen and set automatically when a vertex or particle
     /// comes under the ownership of an event (i.e. it is contained in an event).
+    /// 
+    /// Please note that the barcodes are intended for internal use within 
+    /// HepMC as a unique identifier for the particles and vertices.
+    /// Using the barcode to encode extra information is an abuse of 
+    /// the barcode data member and causes confusion among users. 
     inline GenParticle* GenEvent::barcode_to_particle( int barCode ) const
     { 
@@ -688,4 +806,9 @@
     /// The barcodes are chosen and set automatically when a vertex or particle
     /// comes under the ownership of an event (i.e. it is contained in an event).
+    /// 
+    /// Please note that the barcodes are intended for internal use within 
+    /// HepMC as a unique identifier for the particles and vertices.
+    /// Using the barcode to encode extra information is an abuse of 
+    /// the barcode data member and causes confusion among users. 
     inline GenVertex* GenEvent::barcode_to_vertex( int barCode ) const
     {
@@ -709,6 +832,6 @@
     
     // beam particles
-    inline std::pair<HepMC::GenParticle*,HepMC::GenParticle*> GenEvent::beam_particles() const {
-        return std::pair<GenParticle*,GenParticle*> (m_beam_particle_1, m_beam_particle_2);
+    inline std::pair<HepMC::GenParticle *,HepMC::GenParticle *> GenEvent::beam_particles() const {
+        return std::pair<GenParticle *,GenParticle *> (m_beam_particle_1, m_beam_particle_2);
     }
 
Index: trunk/Utilities/HepMC/interface/GenParticle.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenParticle.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/GenParticle.h	(revision 572)
@@ -30,4 +30,5 @@
 #include "Polarization.h"
 #include "SimpleVector.h"
+#include "IteratorRange.h"
 #include <iostream>
 #ifdef _WIN32
@@ -43,4 +44,8 @@
     class GenEvent; 
 
+    class GenParticleProductionRange;
+    class ConstGenParticleProductionRange;
+    class GenParticleEndRange;
+    class ConstGenParticleEndRange;
 
     //! The GenParticle class contains information about generated particles
@@ -119,7 +124,31 @@
 	///
 	/// The barcode is the particle's reference number, every vertex in the
-	///  event has a unique barcode. Particle barcodes are positive numbers,
-	///  vertex barcodes are negative numbers.
+	/// event has a unique barcode. Particle barcodes are positive numbers,
+	/// vertex barcodes are negative numbers.
+	/// 
+	/// Please note that the barcodes are intended for internal use within 
+	/// HepMC as a unique identifier for the particles and vertices.
+	/// Using the barcode to encode extra information is an abuse of 
+	/// the barcode data member and causes confusion among users. 
+	/// 
 	int                  barcode() const; //!< particle barcode
+	
+	/// Convenience method.  Returns true if status==1
+	bool                 is_undecayed() const;
+	/// Convenience method.  Returns true if status==2
+	bool                 has_decayed() const;
+	/// Convenience method.  Returns true if status==4
+	/// Note that using status 4 for beam particles is a new convention which
+	/// may not have been implemented by the code originating this GenEvent.
+	bool                 is_beam() const;
+
+	/// incoming particle range
+	GenParticleProductionRange particles_in( IteratorRange range = relatives );
+	/// incoming particle range
+	ConstGenParticleProductionRange particles_in( IteratorRange range = relatives ) const;
+	/// outgoing particle range
+	GenParticleEndRange particles_out( IteratorRange range = relatives );
+	/// outgoing particle range
+	ConstGenParticleEndRange particles_out( IteratorRange range = relatives ) const;
 
 	/////////////////////
@@ -225,4 +254,14 @@
     inline void GenParticle::set_barcode_( int bc ) { m_barcode = bc; }
 
+    inline bool GenParticle::is_undecayed() const {
+        return ( m_status==1 ) ?  true : false;
+    }
+    inline bool GenParticle::has_decayed() const {
+        return ( m_status==2 ) ?  true : false;
+    }
+    inline bool GenParticle::is_beam() const {
+        return ( m_status==4 ) ?  true : false;
+    }
+
 } // HepMC
 
Index: trunk/Utilities/HepMC/interface/GenRanges.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenRanges.h	(revision 572)
+++ trunk/Utilities/HepMC/interface/GenRanges.h	(revision 572)
@@ -0,0 +1,328 @@
+#ifndef HEPMC_GEN_EVENT_ITERATORS_H
+#define HEPMC_GEN_EVENT_ITERATORS_H
+
+//--------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////
+// garren@fnal.gov, May 2009
+// 
+//////////////////////////////////////////////////////////////////////////
+//--------------------------------------------------------------------------
+
+#include <stdexcept>
+
+#include "GenEvent.h"
+#include "GenVertex.h"
+
+namespace HepMC {
+
+//! GenEventVertexRange acts like a collection of vertices
+
+///
+/// \class  GenEventVertexRange
+/// HepMC::GenEventVertexRange is used to mimic a collection of
+/// vertices for ease of use - especially with utilities such as 
+/// the Boost foreach funtion
+///
+class GenEventVertexRange {
+
+public:
+
+  /// the constructor requires a GenEvent
+  GenEventVertexRange( GenEvent & e ) : m_event(e) {}
+  /// 
+  GenEvent::vertex_iterator begin() { return m_event.vertices_begin(); }
+  GenEvent::vertex_iterator end()   { return m_event.vertices_end(); }
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenEvent::vertex_range().
+  GenEventVertexRange& operator=( GenEventVertexRange & );
+
+private:
+  GenEvent & m_event;
+
+};
+
+//! ConstGenEventVertexRange acts like a collection of vertices
+
+///
+/// \class  ConstGenEventVertexRange
+/// HepMC::ConstGenEventVertexRange is used to mimic a collection of
+/// vertices for ease of use - especially with utilities such as 
+/// the Boost foreach funtion
+/// This is the const partner of GenEventVertexRange
+///
+class ConstGenEventVertexRange {
+
+public:
+
+  /// the constructor requires a const GenEvent
+  ConstGenEventVertexRange( GenEvent const & e ) : m_event(e) {}
+  /// 
+  GenEvent::vertex_const_iterator begin() const { return m_event.vertices_begin(); }
+  GenEvent::vertex_const_iterator end()   const { return m_event.vertices_end(); }
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenEvent::vertex_range().
+  ConstGenEventVertexRange& operator=( ConstGenEventVertexRange & );
+
+private:
+  GenEvent const & m_event;
+
+};
+
+//! GenEventParticleRange acts like a collection of particles
+
+///
+/// \class  GenEventParticleRange
+/// HepMC::GenEventParticleRange is used to mimic a collection of
+/// particles for ease of use - especially with utilities such as 
+/// the Boost foreach funtion
+///
+class GenEventParticleRange {
+
+public:
+
+  /// the constructor requires a GenEvent
+  GenEventParticleRange( GenEvent & e ) : m_event(e) {}
+  /// 
+  GenEvent::particle_iterator begin() { return m_event.particles_begin(); }
+  GenEvent::particle_iterator end()   { return m_event.particles_end(); }
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenEvent::particle_range().
+  GenEventParticleRange& operator=( GenEventParticleRange & );
+
+private:
+  GenEvent & m_event;
+
+};
+
+//! ConstGenEventParticleRange acts like a collection of particles
+
+///
+/// \class  ConstGenEventParticleRange
+/// HepMC::ConstGenEventParticleRange is used to mimic a collection of
+/// particles for ease of use - especially with utilities such as 
+/// the Boost foreach funtion
+/// This is the const partner of GenEventParticleRange
+///
+class ConstGenEventParticleRange {
+
+public:
+
+  /// the constructor requires a const GenEvent
+  ConstGenEventParticleRange( GenEvent const & e ) : m_event(e) {}
+  /// 
+  GenEvent::particle_const_iterator begin() const { return m_event.particles_begin(); }
+  GenEvent::particle_const_iterator end()   const { return m_event.particles_end(); }
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenEvent::particle_range().
+  ConstGenEventParticleRange& operator=( ConstGenEventParticleRange & );
+
+private:
+  GenEvent const & m_event;
+
+};
+
+//! GenVertexParticleRange acts like a collection of particles
+
+///
+/// \class  GenVertexParticleRange
+/// HepMC::GenVertexParticleRange is used to mimic a collection of
+/// particles for ease of use - especially with utilities such as 
+/// the Boost foreach funtion
+///
+class GenVertexParticleRange {
+
+public:
+
+  /// the constructor requires a GenVertex
+  GenVertexParticleRange( GenVertex & v, IteratorRange range = relatives ) 
+  : m_vertex(v),m_range(range) {}
+  /// 
+  GenVertex::particle_iterator begin() { return m_vertex.particles_begin(m_range); }
+  GenVertex::particle_iterator end()   { return m_vertex.particles_end(m_range); }
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenVertex::particles().
+  GenVertexParticleRange& operator=( GenVertexParticleRange & );
+
+private:
+  GenVertex     & m_vertex;
+  IteratorRange   m_range;
+
+};
+
+//! GenParticleProductionRange acts like a collection of particles
+
+///
+/// \class  GenParticleProductionRange
+/// HepMC::GenParticleProductionRange is used to mimic a collection of
+/// particles associated with the particle's production vertex for ease of use 
+/// Utilities such as the Boost foreach funtion will want to use this class.
+///
+class GenParticleProductionRange {
+
+public:
+
+  /// the constructor requires a GenParticle
+  GenParticleProductionRange( GenParticle const & p, IteratorRange range = relatives ) 
+  : m_particle(p),m_range(range) {}
+  /// begin iterator throws an error if the particle production_vertex is undefined
+  GenVertex::particle_iterator begin();
+  /// end iterator throws an error if the particle production_vertex is undefined
+  GenVertex::particle_iterator end(); 
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenVertex::particles_in().
+  GenParticleProductionRange& operator=( GenParticleProductionRange & );
+
+private:
+  GenParticle const & m_particle;
+  IteratorRange       m_range;
+
+};
+
+class ConstGenParticleProductionRange {
+
+public:
+
+  /// the constructor requires a GenParticle
+  ConstGenParticleProductionRange( GenParticle const & p, IteratorRange range = relatives ) 
+  : m_particle(p),m_range(range) {}
+  /// begin iterator throws an error if the particle production_vertex is undefined
+  GenVertex::particle_iterator begin();
+  /// end iterator throws an error if the particle production_vertex is undefined
+  GenVertex::particle_iterator end(); 
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenVertex::particles_in().
+  ConstGenParticleProductionRange& operator=( ConstGenParticleProductionRange & );
+
+private:
+  GenParticle const & m_particle;
+  IteratorRange       m_range;
+
+};
+
+//! GenParticleEndRange acts like a collection of particles
+
+///
+/// \class  GenParticleEndRange
+/// HepMC::GenParticleEndRange is used to mimic a collection of
+/// particles associated with the particle's end vertex for ease of use 
+/// Utilities such as the Boost foreach funtion will want to use this class.
+///
+class GenParticleEndRange {
+
+public:
+
+  /// the constructor requires a GenParticle
+  GenParticleEndRange( GenParticle const & p, IteratorRange range = relatives ) 
+  : m_particle(p),m_range(range) {}
+  /// begin iterator throws an error if the particle end_vertex is undefined
+  GenVertex::particle_iterator begin();
+  /// end iterator throws an error if the particle end_vertex is undefined
+  GenVertex::particle_iterator end(); 
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenVertex::particles_out().
+  GenParticleEndRange& operator=( GenParticleEndRange & );
+
+private:
+  GenParticle const & m_particle;
+  IteratorRange       m_range;
+
+};
+
+class ConstGenParticleEndRange {
+
+public:
+
+  /// the constructor requires a GenParticle
+  ConstGenParticleEndRange( GenParticle const & p, IteratorRange range = relatives ) 
+  : m_particle(p),m_range(range) {}
+  /// begin iterator throws an error if the particle end_vertex is undefined
+  GenVertex::particle_iterator begin();
+  /// end iterator throws an error if the particle end_vertex is undefined
+  GenVertex::particle_iterator end(); 
+
+private:
+  /// Because the class contains a reference, assignments are not allowed.
+  /// However, we need the copy constructor for GenVertex::particles_out().
+  ConstGenParticleEndRange& operator=( ConstGenParticleEndRange & );
+
+private:
+  GenParticle const & m_particle;
+  IteratorRange       m_range;
+
+};
+
+
+inline GenVertex::particle_iterator GenParticleProductionRange::begin() 
+{ 
+    if ( ! m_particle.production_vertex() ) 
+        throw(std::range_error("GenParticleProductionRange: GenParticle has no production_vertex"));
+    return m_particle.production_vertex()->particles_begin(m_range); 
+}
+
+inline GenVertex::particle_iterator GenParticleProductionRange::end()
+{ 
+    if ( ! m_particle.production_vertex() ) 
+        throw(std::range_error("GenParticleProductionRange: GenParticle has no production_vertex"));
+    return m_particle.production_vertex()->particles_end(m_range); 
+}
+
+
+inline GenVertex::particle_iterator ConstGenParticleProductionRange::begin() 
+{ 
+    if ( ! m_particle.production_vertex() ) 
+        throw(std::range_error("ConstGenParticleProductionRange: GenParticle has no production_vertex"));
+    return m_particle.production_vertex()->particles_begin(m_range); 
+}
+
+inline GenVertex::particle_iterator ConstGenParticleProductionRange::end()
+{ 
+    if ( ! m_particle.production_vertex() ) 
+        throw(std::range_error("ConstGenParticleProductionRange: GenParticle has no production_vertex"));
+    return m_particle.production_vertex()->particles_end(m_range); 
+}
+
+inline GenVertex::particle_iterator GenParticleEndRange::begin() 
+{ 
+    if ( ! m_particle.end_vertex() ) 
+        throw(std::range_error("GenParticleEndRange: GenParticle has no end_vertex"));
+    return m_particle.end_vertex()->particles_begin(m_range); 
+}
+inline GenVertex::particle_iterator GenParticleEndRange::end()
+{ 
+    if ( ! m_particle.end_vertex() ) 
+        throw(std::range_error("GenParticleEndRange: GenParticle has no end_vertex"));
+    return m_particle.end_vertex()->particles_end(m_range); 
+}
+
+inline GenVertex::particle_iterator ConstGenParticleEndRange::begin() 
+{ 
+    if ( ! m_particle.end_vertex() ) 
+        throw(std::range_error("ConstGenParticleEndRange: GenParticle has no end_vertex"));
+    return m_particle.end_vertex()->particles_begin(m_range); 
+}
+inline GenVertex::particle_iterator ConstGenParticleEndRange::end()
+{ 
+    if ( ! m_particle.end_vertex() ) 
+        throw(std::range_error("ConstGenParticleEndRange: GenParticle has no end_vertex"));
+    return m_particle.end_vertex()->particles_end(m_range); 
+}
+
+} // HepMC
+
+#endif  // HEPMC_GEN_EVENT_ITERATORS_H
Index: trunk/Utilities/HepMC/interface/GenVertex.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenVertex.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/GenVertex.h	(revision 572)
@@ -24,4 +24,5 @@
 #include "WeightContainer.h"
 #include "SimpleVector.h"
+#include "IteratorRange.h"
 #include <iostream>
 #include <iterator>
@@ -29,10 +30,14 @@
 #include <set>
 #include <algorithm>
+#include <cstddef>
 
 namespace HepMC {
 
-    /// type of iteration
-    enum IteratorRange { parents, children, family, 
-			 ancestors, descendants, relatives };
+    class GenVertexParticleRange;
+    class GenParticleProductionRange;
+    class ConstGenParticleProductionRange;
+    class GenParticleEndRange;
+    class ConstGenParticleEndRange;
+
     class GenParticle;
     class GenEvent;
@@ -110,6 +115,12 @@
 	///
 	/// The barcode is the vertex's reference number, every vertex in the
-	///  event has a unique barcode. Vertex barcodes are negative numbers,
-	///  particle barcodes are positive numbers.
+	/// event has a unique barcode. Vertex barcodes are negative numbers,
+	/// particle barcodes are positive numbers.
+	/// 
+	/// Please note that the barcodes are intended for internal use within 
+	/// HepMC as a unique identifier for the particles and vertices.
+	/// Using the barcode to encode extra information is an abuse of 
+	/// the barcode data member and causes confusion among users. 
+	/// 
 	int                     barcode() const; //!< unique identifier
 
@@ -121,4 +132,15 @@
 	/// const direct access to the weights container
 	const WeightContainer&  weights() const;
+
+	/// particle range
+	GenVertexParticleRange particles( IteratorRange range = relatives );
+	/// incoming particle range
+	GenParticleProductionRange particles_in( GenParticle&, IteratorRange range = relatives );
+	/// incoming particle range
+	ConstGenParticleProductionRange particles_in( GenParticle const &, IteratorRange range = relatives ) const;
+	/// outgoing particle range
+	GenParticleEndRange particles_out( GenParticle&, IteratorRange range = relatives );
+	/// outgoing particle range
+	ConstGenParticleEndRange particles_out( GenParticle const &, IteratorRange range = relatives ) const;
 
 	////////////////////
@@ -197,4 +219,9 @@
 	    /// root vertex of this iteration
 	    const GenVertex*  vertex_root() const;
+	private:
+	    /// Pre-fix increment -- is not allowed
+	    edge_iterator& operator--(void);
+	    /// Post-fix increment -- is not allowed
+	    edge_iterator  operator--(int);
 	private:
 	    const GenVertex*  m_vertex;
@@ -275,4 +302,10 @@
 					      recursive_v_iter );
 	private:
+	    /// Pre-fix increment -- is not allowed 
+	    vertex_iterator&    operator--(void);
+	    /// Post-fix increment -- is not allowed 
+	    vertex_iterator     operator--(int);
+
+	private:
 	    GenVertex*       m_vertex;   // the vertex associated to this iter
 	    IteratorRange    m_range;
Index: trunk/Utilities/HepMC/interface/HeavyIon.h
===================================================================
--- trunk/Utilities/HepMC/interface/HeavyIon.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/HeavyIon.h	(revision 572)
@@ -112,4 +112,7 @@
     float sigma_inel_NN()                const { return m_sigma_inel_NN; }
 
+    /// verify that the instance contains non-zero information
+    bool  is_valid()                     const;
+
   // ---  mutators:
     /// set number of hard scatterings
@@ -158,4 +161,11 @@
 };
 
+// Free Functions
+
+/// Write the contents of HeavyIon to an output stream.
+std::ostream & operator << (std::ostream &, HeavyIon const *);
+/// Read the contents of HeavyIon from an input stream.
+std::istream & operator >> (std::istream &, HeavyIon *);
+
 // inline operators
   /// Required members are
@@ -248,4 +258,22 @@
 }
 
+inline bool  HeavyIon::is_valid() const
+{
+    if( m_Ncoll_hard != 0 ) return true;
+    if( m_Npart_proj != 0 ) return true;
+    if( m_Npart_targ != 0 ) return true;
+    if( m_Ncoll != 0 ) return true;
+    if( m_spectator_neutrons != 0 ) return true;
+    if( m_spectator_protons != 0 ) return true;
+    if( m_N_Nwounded_collisions != 0 ) return true;
+    if( m_Nwounded_N_collisions != 0 ) return true;
+    if( m_Nwounded_Nwounded_collisions != 0 ) return true;
+    if( m_impact_parameter != 0 ) return true;
+    if( m_event_plane_angle != 0 ) return true;
+    if( m_eccentricity != 0 ) return true;
+    if( m_sigma_inel_NN != 0 ) return true;
+    return false;
+}
+
 } // HepMC
 
Index: trunk/Utilities/HepMC/interface/HepMCDefs.h
===================================================================
--- trunk/Utilities/HepMC/interface/HepMCDefs.h	(revision 572)
+++ trunk/Utilities/HepMC/interface/HepMCDefs.h	(revision 572)
@@ -0,0 +1,68 @@
+#ifndef HEPMC_DEFS_H
+#define HEPMC_DEFS_H
+// ----------------------------------------------------------------------
+//
+// HepMCDefs.h
+// Author:  Lynn Garren
+//
+//  Define various useful macros
+//  Most allow users to check for various code features
+//
+// ----------------------------------------------------------------------
+
+// the HeavyIon class is available in HepMC  
+#ifndef HEPMC_HAS_HEAVY_ION
+#define HEPMC_HAS_HEAVY_ION
+#endif
+
+// the IO_Ascii class is NOT available in HepMC   
+#ifndef HEPMC_IO_ASCII_REMOVED
+#define HEPMC_IO_ASCII_REMOVED
+#endif
+
+// the ParticleData class is NOT available in HepMC   
+#ifndef HEPMC_PARTICLE_DATA_REMOVED
+#define HEPMC_PARTICLE_DATA_REMOVED
+#endif
+
+// the IO_GenEvent class is available in HepMC   
+#ifndef HEPMC_HAS_IO_GENEVENT
+#define HEPMC_HAS_IO_GENEVENT
+#endif
+
+// the PdfInfo class is available in HepMC  
+#ifndef HEPMC_HAS_PDF_INFO
+#define HEPMC_HAS_PDF_INFO
+#endif
+
+// HepMC uses SimpleVector (FourVector) to store momentum and position  
+#ifndef HEPMC_HAS_SIMPLE_VECTOR
+#define HEPMC_HAS_SIMPLE_VECTOR
+#endif
+
+// units are defined in HepMC  
+#ifndef HEPMC_HAS_UNITS
+#define HEPMC_HAS_UNITS
+#endif
+
+// the GenCrossSection class is available in HepMC  
+#ifndef HEPMC_HAS_CROSS_SECTION
+#define HEPMC_HAS_CROSS_SECTION
+#endif
+
+// the iterator range classes are available in HepMC  
+#ifndef HEPMC_HAS_ITERATOR_RANGES
+#define HEPMC_HAS_ITERATOR_RANGES
+#endif
+
+// the HepMC::WeightContainer class allows named weights
+#ifndef HEPMC_HAS_NAMED_WEIGHTS
+#define HEPMC_HAS_NAMED_WEIGHTS
+#endif
+
+// define the version of HepMC. 
+#ifndef HEPMC_VERSION
+#define HEPMC_VERSION "2.06.05"
+#endif
+
+#endif  // HEPMC_DEFS_H
Index: trunk/Utilities/HepMC/interface/IO_AsciiParticles.h
===================================================================
--- trunk/Utilities/HepMC/interface/IO_AsciiParticles.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/IO_AsciiParticles.h	(revision 572)
@@ -8,5 +8,5 @@
 //////////////////////////////////////////////////////////////////////////
 //
-// Strategy for reading or writing events/particleData as machine readable
+// Strategy for reading or writing events as machine readable
 //  ascii to a file. When instantiating, the mode of file to be created 
 //  must be specified. Options are:
@@ -48,5 +48,5 @@
     ///
     /// \class IO_AsciiParticles
-    /// Strategy for reading or writing events/particleData as machine readable
+    /// Strategy for reading or writing events as machine readable
     ///  ascii to a file. When instantiating, the mode of file to be created 
     ///  must be specified. 
@@ -63,6 +63,4 @@
         /// get the next event
 	bool          fill_next_event( GenEvent* evt );
-    inline void          write_particle_data_table(const ParticleDataTable*);
-    inline bool          fill_particle_data_table( ParticleDataTable* );
 	/// insert a comment directly into the output file --- normally you
 	///  only want to do this at the beginning or end of the file. All
@@ -100,11 +98,4 @@
     inline void IO_AsciiParticles::setPrecision(int iprec) { m_precision=iprec; }
 
-    /////////////////////
-    // Inline dummies  //
-    /////////////////////
-
-  void IO_AsciiParticles::write_particle_data_table(const ParticleDataTable*) {;}
-  bool IO_AsciiParticles::fill_particle_data_table( ParticleDataTable* ) {return false;}
-
 } // HepMC
 
Index: trunk/Utilities/HepMC/interface/IO_BaseClass.h
===================================================================
--- trunk/Utilities/HepMC/interface/IO_BaseClass.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/IO_BaseClass.h	(revision 572)
@@ -20,5 +20,4 @@
 
 #include <iostream>
-#include "ParticleDataTable.h"
 #include "GenEvent.h"
 
@@ -41,17 +40,12 @@
 	/// fill this GenEvent
 	virtual bool fill_next_event( GenEvent* ) =0;
-	/// write this ParticleDataTable
-	virtual void write_particle_data_table( const ParticleDataTable* ) =0;
-	/// fill this ParticleDataTable
-	virtual bool fill_particle_data_table( ParticleDataTable* ) =0;
 	/// write output to ostr
 	virtual void print( std::ostream& ostr = std::cout ) const;
 	//
-	// the read_next_event() and read_particle_data_table() differ from
-	// the fill_***() methods in that they create a new event or pdt
+	// the read_next_event() differs from
+	// the fill_***() methods in that it creates a new event
 	// before calling the  corresponding fill_*** method
 	// (they are not intended to be over-ridden)
 	GenEvent*    read_next_event();  //!< do not over-ride
-	ParticleDataTable* read_particle_data_table();  //!< do not over-ride
 	//
 	// The overloaded stream operators >>,<< are identical to
@@ -72,11 +66,4 @@
 	/// the same as write_event
 	virtual       GenEvent*& operator<<( GenEvent*& );
-	/// the same as read_particle_data_table
-	virtual       ParticleDataTable*& operator>>( ParticleDataTable*& );
-	/// the same as write_particle_data_table
-	virtual const ParticleDataTable*& operator<<( const 
-						      ParticleDataTable*& );
-	/// the same as write_particle_data_table
-	virtual       ParticleDataTable*& operator<<( ParticleDataTable*& );
     };
 
@@ -98,18 +85,4 @@
 	//       since this statement is rarely reached
 	delete evt;
-	return 0;
-    }
-
-    inline ParticleDataTable* IO_BaseClass::read_particle_data_table() {
-	/// creates a new particle data table and fills it by calling 
-	/// the sister method read_particle_data_table( ParticleDataTable* )
-	//
-	// 1. create an empty pdt
-	ParticleDataTable* pdt = new ParticleDataTable();
-	// 2. fill the pdt container - if the read is successful, return the
-	//    pointer, otherwise return null and delete the evt
-	if ( fill_particle_data_table( pdt ) ) return pdt;
-	// next statement is only reached if read fails
-	delete pdt;
 	return 0;
     }
@@ -135,22 +108,4 @@
     }
 
-    inline ParticleDataTable*& IO_BaseClass::operator>>( 
-					   ParticleDataTable*& pdt ){
-	pdt = read_particle_data_table();
-	return pdt;
-    }
-
-    inline const ParticleDataTable*& IO_BaseClass::operator<<(
-					     const ParticleDataTable*& pdt ) {
-	write_particle_data_table( pdt );
-	return pdt;
-    }
-
-    inline ParticleDataTable*& IO_BaseClass::operator<<(
-	                                            ParticleDataTable*& pdt ) {
-	write_particle_data_table( pdt );
-	return pdt;
-    }
-
 } // HepMC
 
Index: trunk/Utilities/HepMC/interface/IO_Exception.h
===================================================================
--- trunk/Utilities/HepMC/interface/IO_Exception.h	(revision 572)
+++ trunk/Utilities/HepMC/interface/IO_Exception.h	(revision 572)
@@ -0,0 +1,50 @@
+#ifndef HEPMC_IO_EXCEPTION_H
+#define HEPMC_IO_EXCEPTION_H
+// ----------------------------------------------------------------------
+//
+// IO_Exception.h
+// Author:  Lynn Garren
+//
+// IO exception handling
+// IO_GenEvent, etc. catch the throw and set data members with the error type and message 
+// Some of the messages are constructed with transient information 
+//      (e.g., contents of a bad GenParticle)
+//
+// ----------------------------------------------------------------------
+
+
+
+#include <stdexcept>
+ 
+namespace HepMC {
+
+//! IO exception handling
+
+///
+/// \class  IO_Exception
+/// IO_GenEvent, etc. catch the throw and set data members with the error type and message 
+/// Some of the messages are constructed with transient information 
+///      (e.g., contents of a bad GenParticle)
+class IO_Exception : public std::runtime_error {
+public:
+  IO_Exception(const std::string & msg) 
+  : std::runtime_error(msg) { }
+
+  /// IO error types
+  enum ErrorType{ OK,
+                  NullEvent, 
+                  WrongFileType, 
+                  MissingStartKey, 
+		  EndOfStream, 
+		  EndKeyMismatch, 
+		  MissingEndKey, 
+		  InvalidData,
+                  InputAndOutput,
+		  BadOutputStream,
+		  BadInputStream };
+
+};
+
+}	// namespace HepMC
+
+#endif // HEPMC_IO_EXCEPTION_H
Index: trunk/Utilities/HepMC/interface/IO_GenEvent.h
===================================================================
--- trunk/Utilities/HepMC/interface/IO_GenEvent.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/IO_GenEvent.h	(revision 572)
@@ -16,201 +16,134 @@
 #include <vector>
 #include "IO_BaseClass.h"
-#include "TempParticleMap.h"
-#include "CommonIO.h"
+#include "IO_Exception.h"
 #include "Units.h"
 
 namespace HepMC {
 
-    class GenEvent;
-    class GenVertex;
-    class GenParticle;
-    class ParticleData;
-    class HeavyIon;
-    class PdfInfo;
+class GenEvent;
+class GenVertex;
+class GenParticle;
+class HeavyIon;
+class PdfInfo;
 
-    //! IO_GenEvent also deals with HeavyIon and PdfInfo 
+//! IO_GenEvent also deals with HeavyIon and PdfInfo 
 
-    ///
-    /// \class  IO_GenEvent
-    /// event input/output in ascii format for machine reading
-    /// extended format contains HeavyIon and PdfInfo classes
-    ///
-    /// Strategy for reading or writing events using iostreams
-    /// When instantiating with a file name, the mode of file to be created 
-    ///  must be specified. Options are:
-    ///      std::ios::in     open file for input 
-    ///      std::ios::out    open file for output
-    ///      std::ios::trunc  erase old file when opening (i.e. ios::out|ios::trunc
-    ///                    removes oldfile, and creates a new one for output )
-    ///      std::ios::app    append output to end of file
-    ///  for the purposes of this class, simultaneous input and output mode 
-    ///  ( std::ios::in | std::ios::out ) is not allowed.
-    /// 
-    /// Event listings are preceded by the key:
-    ///  "HepMC::IO_GenEvent-START_EVENT_LISTING\n"
-    ///  and terminated by the key:
-    ///  "HepMC::IO_GenEvent-END_EVENT_LISTING\n"
-    /// GenParticle Data tables are preceded by the key:
-    ///  "HepMC::IO_GenEvent-START_PARTICLE_DATA\n"
-    ///  and terminated by the key:
-    ///  "HepMC::IO_GenEvent-END_PARTICLE_DATA\n"
-    /// Comments are allowed. They need not be preceded by anything, though if
-    ///  a comment is written using write_comment( const string ) then it will be
-    ///  preceded by "HepMC::IO_GenEvent-COMMENT\n"
-    /// Each event, vertex, particle, particle data, heavy ion, or pdf info line
-    ///  is preceded by   "E ","V ","P ","D ","H ","F "    respectively.
-    /// Comments may appear anywhere in the file -- so long as they do not contain
-    ///  any of the start/stop keys.
-    ///
-    class IO_GenEvent : public IO_BaseClass {
-    public:
-        /// constructor requiring a file name and std::ios mode
-	IO_GenEvent( const std::string& filename="IO_GenEvent.dat", 
-		  std::ios::openmode mode=std::ios::out );
-        /// constructor requiring an input stream
-	IO_GenEvent( std::istream & );
-        /// constructor requiring an output stream
-	IO_GenEvent( std::ostream & );
-	virtual       ~IO_GenEvent();
+///
+/// \class  IO_GenEvent
+/// event input/output in ascii format for machine reading
+/// extended format contains HeavyIon and PdfInfo classes
+///
+/// Strategy for reading or writing events using iostreams
+/// When instantiating with a file name, the mode of file to be created 
+///  must be specified. Options are:
+///      std::ios::in     open file for input 
+///      std::ios::out    open file for output
+///      std::ios::trunc  erase old file when opening (i.e. ios::out|ios::trunc
+///                    removes oldfile, and creates a new one for output )
+///      std::ios::app    append output to end of file
+///  for the purposes of this class, simultaneous input and output mode 
+///  ( std::ios::in | std::ios::out ) is not allowed.
+/// 
+/// Event listings are preceded by the key:
+///  "HepMC::IO_GenEvent-START_EVENT_LISTING\n"
+///  and terminated by the key:
+///  "HepMC::IO_GenEvent-END_EVENT_LISTING\n"
+/// GenParticle Data tables are preceded by the key:
+///  "HepMC::IO_GenEvent-START_PARTICLE_DATA\n"
+///  and terminated by the key:
+///  "HepMC::IO_GenEvent-END_PARTICLE_DATA\n"
+/// Comments are allowed. They need not be preceded by anything, though if
+///  a comment is written using write_comment( const string ) then it will be
+///  preceded by "HepMC::IO_GenEvent-COMMENT\n"
+/// Each event, vertex, particle, particle data, heavy ion, or pdf info line
+///  is preceded by   "E ","V ","P ","D ","H ","F "    respectively.
+/// Comments may appear anywhere in the file -- so long as they do not contain
+///  any of the start/stop keys.
+///
+class IO_GenEvent : public IO_BaseClass {
+public:
+    /// constructor requiring a file name and std::ios mode
+    IO_GenEvent( const std::string& filename="IO_GenEvent.dat", 
+	      std::ios::openmode mode=std::ios::out );
+    /// constructor requiring an input stream
+    IO_GenEvent( std::istream & );
+    /// constructor requiring an output stream
+    IO_GenEvent( std::ostream & );
+    virtual       ~IO_GenEvent();
 
-        /// write this event
-	void          write_event( const GenEvent* evt );
-        /// get the next event
-	bool          fill_next_event( GenEvent* evt );
-	void          write_particle_data_table(const ParticleDataTable*);
-	bool          fill_particle_data_table( ParticleDataTable* );
-	/// insert a comment directly into the output file --- normally you
-	///  only want to do this at the beginning or end of the file. All
-	///  comments are preceded with "HepMC::IO_GenEvent-COMMENT\n"
-  	void          write_comment( const std::string comment );
+    /// write this event
+    void          write_event( const GenEvent* evt );
+    /// get the next event
+    bool          fill_next_event( GenEvent* evt );
+    /// insert a comment directly into the output file --- normally you
+    ///  only want to do this at the beginning or end of the file. All
+    ///  comments are preceded with "HepMC::IO_GenEvent-COMMENT\n"
+    void          write_comment( const std::string comment );
 
-	int           rdstate() const;  //!< check the state of the IO stream
-	void          clear();  //!< clear the IO stream
+    int           rdstate() const;  //!< check the state of the IO stream
+    void          clear();  //!< clear the IO stream
 
-        /// write to ostr
-	void          print( std::ostream& ostr = std::cout ) const;
+    /// write to ostr
+    void          print( std::ostream& ostr = std::cout ) const;
 
-	/// needed when reading a file without units if those units are 
-	/// different than the declared default units 
-	/// (e.g., the default units are MeV, but the file was written with GeV)
-	/// This method is not necessary if the units are written in the file
-	void use_input_units( Units::MomentumUnit, Units::LengthUnit );
+    /// needed when reading a file without units if those units are 
+    /// different than the declared default units 
+    /// (e.g., the default units are MeV, but the file was written with GeV)
+    /// This method is not necessary if the units are written in the file
+    void use_input_units( Units::MomentumUnit, Units::LengthUnit );
 
-    protected: // for internal use only
-	/// write vertex information
-	void          write_vertex( GenVertex* );
-	/// write beam particle information
-	void          write_beam_particles( std::pair<HepMC::GenParticle *,HepMC::GenParticle *> );
-	/// write heavy ion information
-	void          write_heavy_ion( HeavyIon const * );
-	/// write PDF information
-	void          write_pdf_info( PdfInfo const * );
-	/// write units
-	void          write_unit_info( const GenEvent* evt );
-	/// write particle information
-	void          write_particle( GenParticle* p );
-	/// write particle data information
-	void          write_particle_data( const ParticleData* d );
-	/// read vertex information
-	GenVertex*    read_vertex( TempParticleMap& particle_to_end_vertex );
-	/// read GenParticle information
-	GenParticle*  read_particle( TempParticleMap& particle_to_end_vertex );
-	/// read particle data table information
-	ParticleData* read_particle_data( ParticleDataTable* );
-	/// read heavy ion information
-	HeavyIon*     read_heavy_ion(  );
-	/// read units
-	void          read_unit_info( GenEvent* evt );
-	/// write end tag
-	bool          write_end_listing();
+    /// set output precision
+    /// The default precision is 16.
+    void precision( int );
+	
+    /// integer (enum) associated with read error
+    int           error_type()    const;
+    /// the read error message string
+    const std::string & error_message() const;
 
-	void          output( const double& );  //!< write double
-	void          output( const float& );  //!< write float
-	void          output( const int& ); //!< write int
-	void          output( const long& ); //!< write long
-	void          output( const char& );  //!< write a single character
-    private: // use of copy constructor is not allowed
-	IO_GenEvent( const IO_GenEvent& ) : IO_BaseClass() {}
-    private: // data members
-	std::ios::openmode  m_mode;
-	std::fstream        m_file;
-	std::ostream *      m_ostr;
-	std::istream *      m_istr;
-	std::ios *          m_iostr;
-	bool                m_finished_first_event_io;
-	bool                m_have_file;
-	CommonIO            m_common_io;
-	
-    };
+private: // use of copy constructor is not allowed
+    IO_GenEvent( const IO_GenEvent& ) : IO_BaseClass() {}
 
-    //////////////
-    // Inlines  //
-    //////////////
+private: // data members
+    std::ios::openmode  m_mode;
+    std::fstream        m_file;
+    std::ostream *      m_ostr;
+    std::istream *      m_istr;
+    std::ios *          m_iostr;
+    bool                m_have_file;
+    IO_Exception::ErrorType m_error_type;
+    std::string         m_error_message;
 
-    inline void IO_GenEvent::output( const double& d ) {
-	if( m_ostr  ) {
-	    if ( d == 0. ) {
-		*m_ostr << ' ' << (int)0;
-	    } else {
-		*m_ostr << ' ' << d;
-	    }
-	}
+};
+
+//////////////
+// Inlines  //
+//////////////
+
+inline int  IO_GenEvent::rdstate() const { 
+    int state;
+    if( m_istr ) {
+	state =  (int)m_istr->rdstate();
+    } else {
+	state =  (int)m_ostr->rdstate();
     }
-    inline void IO_GenEvent::output( const float& d ) {
-	if( m_ostr  ) {
-	    if ( d == 0. ) {
-		*m_ostr << ' ' << (int)0;
-	    } else {
-		*m_ostr << ' ' << d;
-	    }
-	}
+    return state; 
+}
+
+inline void IO_GenEvent::clear() { 
+    if( m_istr ) {
+	m_istr->clear();
+    } else {
+	m_ostr->clear();
     }
-    inline void IO_GenEvent::output( const int& i ) { 
-	if( m_ostr  ) {
-	    if ( i == 0. ) {
-		*m_ostr << ' ' << (int)0;
-	    } else {
-        	*m_ostr << ' ' << i; 
-	    }
-	}
-    }
-    inline void IO_GenEvent::output( const long& i ) {
-	if( m_ostr  ) {
-	    if ( i == 0. ) {
-		*m_ostr << ' ' << (int)0;
-	    } else {
-        	*m_ostr << ' ' << i; 
-	    }
-	}
-    }
-    inline void IO_GenEvent::output( const char& c ) {
-	if( m_ostr  ) {
-	    if ( c ) {
-        	*m_ostr << c; 
-	    } else {
-		*m_ostr << ' ' ;
-	    }
-	}
-    }
-    inline int  IO_GenEvent::rdstate() const { 
-        int state;
-	if( m_istr ) {
-	    state =  (int)m_istr->rdstate();
-	} else {
-	    state =  (int)m_ostr->rdstate();
-	}
-        return state; 
-    }
-    inline void IO_GenEvent::clear() { 
-	if( m_istr ) {
-	    m_istr->clear();
-	} else {
-	    m_ostr->clear();
-	}
-    }
-    // these are required by IO_BaseClass, but not used here
-    inline void IO_GenEvent::write_particle_data_table(const ParticleDataTable*) {;}
-    inline bool IO_GenEvent::fill_particle_data_table( ParticleDataTable* ) 
-    { return false;}
+}
+
+inline int IO_GenEvent::error_type() const {
+    return m_error_type;
+}
+
+inline const std::string & IO_GenEvent::error_message() const {
+    return m_error_message;
+}
 
 } // HepMC
Index: trunk/Utilities/HepMC/interface/PdfInfo.h
===================================================================
--- trunk/Utilities/HepMC/interface/PdfInfo.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/PdfInfo.h	(revision 572)
@@ -91,4 +91,7 @@
     double pdf2()                 const { return m_pdf2; }
 
+    /// verify that the instance contains non-zero information
+    bool  is_valid()                     const;
+
   // ---  mutators:
     /// set flavour code of first parton
@@ -124,4 +127,10 @@
 };
 
+// Free Functions
+
+// IO
+std::ostream & operator << (std::ostream &, PdfInfo const *);
+std::istream & operator >> (std::istream &, PdfInfo *);
+
 // inline operators
 inline PdfInfo::PdfInfo( int i1, int i2, double x1, double x2,
@@ -191,4 +200,18 @@
 }
 
+inline bool  PdfInfo::is_valid() const
+{
+    if( m_id1 != 0 ) return true;
+    if( m_id2 != 0 ) return true;
+    if( m_pdf_id1 != 0 ) return true;
+    if( m_pdf_id2 != 0 ) return true;
+    if( m_x1 != 0 ) return true;
+    if( m_x2 != 0 ) return true;
+    if( m_scalePDF != 0 ) return true;
+    if( m_pdf1 != 0 ) return true;
+    if( m_pdf2 != 0 ) return true;
+    return false;
+}
+
 } // HepMC
 
Index: trunk/Utilities/HepMC/interface/Polarization.h
===================================================================
--- trunk/Utilities/HepMC/interface/Polarization.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/Polarization.h	(revision 572)
@@ -34,5 +34,7 @@
     public:
         /// default constructor
-	Polarization( double theta = 0, double phi = 0 );
+	Polarization( );
+	/// constructor requiring at least one value
+	Polarization( double theta, double phi = 0 );
 	/// construct from another polarization object
 	Polarization( const Polarization& inpolar );
@@ -59,4 +61,5 @@
 	double        phi() const;      //!< returns azimuthal angle in radians
 	ThreeVector   normal3d() const; //!< unit 3 vector for easy manipulation
+	bool          is_defined() const;   //!< returns true if the Polarization has been defined
 
         /// set polar angle in radians 
@@ -68,4 +71,6 @@
 	/// sets polarization according to direction of 3 vec
 	ThreeVector   set_normal3d( const ThreeVector& vec3in ); 
+	/// declares the Polarization as undefined and zeros the values
+	void          set_undefined();
 
     private:
@@ -78,4 +83,5 @@
 	double m_theta; //polar angle of polarization in radians 0< theta <pi
 	double m_phi;   //azimuthal angle of polarization in rad. 0< phi <2pi
+	bool   m_defined; //used to flag if the Polarization has been defined
     };
 
@@ -93,5 +99,5 @@
     inline bool Polarization::operator==( const Polarization& a ) const 
     {
-	return ( a.theta() == this->theta() && a.phi() == this->phi() );
+	return ( a.theta() == this->theta() && a.phi() == this->phi() && a.is_defined() == this->is_defined() );
     }
 
Index: trunk/Utilities/HepMC/interface/SimpleVector.h
===================================================================
--- trunk/Utilities/HepMC/interface/SimpleVector.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/SimpleVector.h	(revision 572)
@@ -83,5 +83,4 @@
   double perp2() const;  //!< Transverse component of the spatial vector squared.
   double perp() const;   //!< Transverse component of the spatial vector (R in cylindrical system).
-  double mag() const;    //!< Magnitude of the spatial vector
 
   // Get spatial vector components in spherical coordinate system.
@@ -167,8 +166,6 @@
   double r()     const;  //!< The magnitude
 
-  double mag() const;  //!< The magnitude (r in spherical coordinate system).
-
-  void setPhi(double);  //!< Set phi keeping mag and theta constant (BaBar).
-  void setTheta(double);  //!< Set theta keeping mag and phi constant (BaBar).
+  void setPhi(double);  //!< Set phi keeping magnitude and theta constant (BaBar).
+  void setTheta(double);  //!< Set theta keeping magnitude and phi constant (BaBar).
 
   double perp2() const;  //!< The transverse component squared (rho^2 in cylindrical coordinate system).
Index: trunk/Utilities/HepMC/interface/SimpleVector.icc
===================================================================
--- trunk/Utilities/HepMC/interface/SimpleVector.icc	(revision 571)
+++ trunk/Utilities/HepMC/interface/SimpleVector.icc	(revision 572)
@@ -49,8 +49,4 @@
 }
 
-inline double  FourVector::mag() const { 
-return std::sqrt( m_x*m_x + m_y*m_y + m_z*m_z );
-}
-
 inline double FourVector::perp2() const { return m_x*m_x + m_y*m_y; }
 
@@ -78,5 +74,5 @@
 
 inline double FourVector::pseudoRapidity() const {
-  double m = mag();
+  double m = std::sqrt( m_x*m_x + m_y*m_y + m_z*m_z );
   if ( m==  0   ) return  0.0;   
   if ( m==  z() ) return  1.0E72;
@@ -106,9 +102,7 @@
 }
 
-inline double  ThreeVector::mag() const { 
+inline double ThreeVector::r()    const { 
 return std::sqrt( m_x*m_x + m_y*m_y + m_z*m_z );
 }
-
-inline double ThreeVector::r()    const { return mag(); }
 
 inline void ThreeVector::set(double x, double y, double z) {
@@ -125,5 +119,5 @@
 
 inline void ThreeVector::setTheta(double th) { 
-  double ma   = mag();
+  double ma   = r();
   double ph   = phi();
   setX(ma*std::sin(th)*std::cos(ph));
Index: trunk/Utilities/HepMC/interface/StreamHelpers.h
===================================================================
--- trunk/Utilities/HepMC/interface/StreamHelpers.h	(revision 572)
+++ trunk/Utilities/HepMC/interface/StreamHelpers.h	(revision 572)
@@ -0,0 +1,102 @@
+//--------------------------------------------------------------------------
+#ifndef HEPMC_STREAM_HELPERS_H
+#define HEPMC_STREAM_HELPERS_H
+
+//////////////////////////////////////////////////////////////////////////
+// garren@fnal.gov, March 2009
+//
+// This header contains helper functions used by streaming IO
+//////////////////////////////////////////////////////////////////////////
+
+#include <ostream>
+#include <istream>
+
+#include "GenEvent.h"
+#include "TempParticleMap.h"
+
+namespace HepMC {
+
+namespace detail {
+
+/// used by IO_GenEvent constructor
+std::ostream & establish_output_stream_info( std::ostream & );
+/// used by IO_GenEvent constructor
+std::istream & establish_input_stream_info( std::istream & );
+
+/// get a GenVertex from ASCII input
+/// TempParticleMap is used to track the associations of particles with vertices
+std::istream & read_vertex( std::istream &, TempParticleMap &, GenVertex * );
+
+/// get a GenParticle from ASCII input
+/// TempParticleMap is used to track the associations of particles with vertices
+std::istream & read_particle( std::istream&, TempParticleMap &, GenParticle * );
+
+/// write a double - for internal use by streaming IO
+inline std::ostream & output( std::ostream & os, const double& d ) {
+    if( os  ) {
+	if ( d == 0. ) {
+	    os << ' ' << (int)0;
+	} else {
+	    os << ' ' << d;
+	}
+    }
+    return os;
+}
+
+/// write a float - for internal use by streaming IO
+inline std::ostream & output( std::ostream & os, const float& d ) {
+    if( os  ) {
+	if ( d == 0. ) {
+	    os << ' ' << (int)0;
+	} else {
+	    os << ' ' << d;
+	}
+    }
+    return os;
+}
+
+/// write an int - for internal use by streaming IO
+inline std::ostream & output( std::ostream & os, const int& i ) { 
+    if( os  ) {
+	if ( i == 0. ) {
+	    os << ' ' << (int)0;
+	} else {
+            os << ' ' << i; 
+	}
+    }
+    return os;
+}
+
+/// write a long - for internal use by streaming IO
+inline std::ostream & output( std::ostream & os, const long& i ) {
+    if( os  ) {
+	if ( i == 0. ) {
+	    os << ' ' << (int)0;
+	} else {
+            os << ' ' << i; 
+	}
+    }
+    return os;
+}
+
+/// write a single char - for internal use by streaming IO
+inline std::ostream & output( std::ostream & os, const char& c ) {
+    if( os  ) {
+	if ( c ) {
+            os << c; 
+	} else {
+	    os << ' ' ;
+	}
+    }
+    return os;
+}
+
+/// used to read to the end of a bad event
+std::istream & find_event_end( std::istream & );
+
+} // detail
+
+} // HepMC
+
+#endif  // HEPMC_STREAM_HELPERS_H
+//--------------------------------------------------------------------------
Index: trunk/Utilities/HepMC/interface/TempParticleMap.h
===================================================================
--- trunk/Utilities/HepMC/interface/TempParticleMap.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/TempParticleMap.h	(revision 572)
@@ -60,5 +60,5 @@
 	m_particle_order[p->barcode()] = p;
         m_particle_to_end_vertex[p] = end_vtx_code;
-    }
+    }        
 
 } // HepMC
Index: trunk/Utilities/HepMC/interface/Version.h
===================================================================
--- trunk/Utilities/HepMC/interface/Version.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/Version.h	(revision 572)
@@ -12,8 +12,9 @@
 #include <string>
 #include <iostream>
+#include "HepMCDefs.h"
 
 namespace HepMC {
 
-void version( );			//!< print HepMC version
+void version( std::ostream & os = std::cout );			//!< print HepMC version
 void writeVersion( std::ostream & os );	//!< write HepMC version to os
 std::string versionName( );	//!< return HepMC version
@@ -21,11 +22,11 @@
 inline std::string versionName( )
 {
-    return "2.04.01";
+    return HEPMC_VERSION;
 }
 
-inline void version( )
+inline void version( std::ostream & os )
 {
-    std::cout << " --------------- HepMC Version " << versionName()
-              << " --------------- " << std::endl;
+    os << " --------------- HepMC Version " << versionName()
+       << " --------------- " << std::endl;
 }
 
Index: trunk/Utilities/HepMC/interface/WeightContainer.h
===================================================================
--- trunk/Utilities/HepMC/interface/WeightContainer.h	(revision 571)
+++ trunk/Utilities/HepMC/interface/WeightContainer.h	(revision 572)
@@ -9,9 +9,13 @@
 //
 // Container for the Weights associated with an event or vertex.
-// Basically just an interface to STL vector.
+//
+// This implementation adds a map-like interface in addition to the 
+// vector-like interface.
 //////////////////////////////////////////////////////////////////////////
 
 #include <iostream>
 #include <vector>
+#include <string>
+#include <map>
 
 namespace HepMC {
@@ -21,28 +25,39 @@
     ///
     /// \class  WeightContainer
-    /// Basically just an interface to STL vector.
+    /// This class has both map-like and vector-like functionality.
+    /// Named weights are now supported.
     class WeightContainer {
+	friend class GenEvent;
 
     public:
+        /// defining the size type used by vector and map
+	typedef std::size_t size_type;
+        /// iterator for the weight container
+	typedef std::vector<double>::iterator iterator;
+        /// const iterator for the weight container
+	typedef std::vector<double>::const_iterator const_iterator;
+	
         /// default constructor
-	WeightContainer( unsigned int n = 0, const double& value = 0. );
+	explicit WeightContainer( size_type n = 0, double value = 0. );
         /// construct from a vector of weights
 	WeightContainer( const std::vector<double>& weights );
         /// copy
 	WeightContainer( const WeightContainer& in );
-	virtual ~WeightContainer();
+	~WeightContainer();
 
         /// swap
         void swap( WeightContainer & other);
-        /// copy
+        /// copy assignment
 	WeightContainer& operator=( const WeightContainer& );
-        /// copy
+        /// alternate assignment using a vector of doubles
 	WeightContainer& operator=( const std::vector<double>& in );
 
         /// print weights
 	void          print( std::ostream& ostr = std::cout ) const;
+        /// write weights in a readable table
+	void          write( std::ostream& ostr = std::cout ) const;
 
         /// size of weight container
-	int           size() const;
+	size_type     size() const;
 	/// return true if weight container is empty
 	bool          empty() const;
@@ -54,9 +69,21 @@
 	void          clear();
 
-        /// access the weight container
-	double&       operator[]( unsigned int n );  // unchecked access
-        /// access the weight container
-	const double& operator[]( unsigned int n ) const;
-	
+	/// check to see if a name exists in the map
+	bool          has_key( const std::string& s ) const;
+
+        /// access the weight container
+	double&       operator[]( size_type n );  // unchecked access
+        /// access the weight container
+	const double& operator[]( size_type n ) const;
+        /// access the weight container
+	double&       operator[]( const std::string& s );  // unchecked access
+        /// access the weight container
+	const double& operator[]( const std::string& s ) const;
+
+        /// equality
+	bool operator==( const WeightContainer & ) const;
+        /// inequality
+	bool operator!=( const WeightContainer & ) const;
+ 	
 	/// returns the first element
 	double&       front();
@@ -68,19 +95,42 @@
 	const double& back() const;
 
-        /// iterator for the weight container
-	typedef std::vector<double>::iterator iterator;
+	/// begining of the weight container
+	iterator            begin();
+	/// end of the weight container
+	iterator            end();
+	/// begining of the weight container
+	const_iterator      begin() const;
+	/// end of the weight container
+	const_iterator      end() const;
+
+    private:
+        // for internal use only
+
+        /// maplike iterator for the weight container
+	/// for internal use only
+	typedef std::map<std::string,size_type>::iterator       map_iterator;
         /// const iterator for the weight container
-	typedef std::vector<double>::const_iterator const_iterator;
-	/// begining of the weight container
-	iterator            begin();
-	/// end of the weight container
-	iterator            end();
-	/// begining of the weight container
-	const_iterator      begin() const;
-	/// end of the weight container
-	const_iterator      end() const;
+	/// for internal use only
+	typedef std::map<std::string,size_type>::const_iterator const_map_iterator;
+	/// begining of the weight container
+	/// for internal use only
+	map_iterator            map_begin();
+	/// end of the weight container
+	/// for internal use only
+	map_iterator            map_end();
+	/// begining of the weight container
+	/// for internal use only
+	const_map_iterator      map_begin() const;
+	/// end of the weight container
+	/// for internal use only
+	const_map_iterator      map_end() const;
+	
+	/// used by the constructors to set initial names
+	/// for internal use only
+	void set_default_names( size_type n );
 	
     private:
-	std::vector<double>  m_weights;
+	std::vector<double>          m_weights;
+	std::map<std::string,size_type> m_names;
     };
 
@@ -89,21 +139,15 @@
     ///////////////////////////
 
-    inline WeightContainer::WeightContainer( unsigned int n,
-					     const double& value ) 
-	: m_weights(n,value)
+    inline WeightContainer::WeightContainer( const WeightContainer& in )
+	: m_weights(in.m_weights), m_names(in.m_names)
     {}
 
-    inline WeightContainer::WeightContainer( const std::vector<double>& wgts )
-	: m_weights(wgts)
-    {}
-
-    inline WeightContainer::WeightContainer( const WeightContainer& in )
-	: m_weights(in.m_weights)
-    {}
-
     inline WeightContainer::~WeightContainer() {}
 
     inline void WeightContainer::swap( WeightContainer & other)
-    { m_weights.swap( other.m_weights ); }
+    { 
+        m_weights.swap( other.m_weights ); 
+        m_names.swap( other.m_names ); 
+    }
 
     inline WeightContainer& WeightContainer::operator=
@@ -123,29 +167,19 @@
     }
 
-    inline void WeightContainer::print( std::ostream& ostr ) const 
+    inline WeightContainer::size_type WeightContainer::size() const { return m_weights.size(); }
+
+    inline bool WeightContainer::empty() const { return m_weights.empty(); }
+
+    inline void WeightContainer::clear() 
     { 
-	for ( const_iterator w = begin(); w != end(); ++w ) 
-	{ 
-	    ostr << *w << " ";
-	}
-	ostr << std::endl; 
-    }
-
-    inline int WeightContainer::size() const { return m_weights.size(); }
-
-    inline bool WeightContainer::empty() const { return m_weights.empty(); }
-
-    inline void WeightContainer::push_back( const double& value) 
-    { m_weights.push_back(value); }
-
-    inline void WeightContainer::pop_back() { m_weights.pop_back(); }
-
-    inline void WeightContainer::clear() { m_weights.clear(); }
-
-    inline double& WeightContainer::operator[]( unsigned int n ) 
-    { return m_weights[(int)n]; }
-
-    inline const double& WeightContainer::operator[]( unsigned int n ) const
-    { return m_weights[(int)n]; }
+	m_weights.clear(); 
+	m_names.clear(); 
+    }
+
+    inline double& WeightContainer::operator[]( size_type n ) 
+    { return m_weights[n]; }
+
+    inline const double& WeightContainer::operator[]( size_type n ) const
+    { return m_weights[n]; }
 
     inline double& WeightContainer::front() { return m_weights.front(); }
@@ -171,4 +205,16 @@
     { return m_weights.end(); }
 
+    inline WeightContainer::map_iterator WeightContainer::map_begin() 
+    { return m_names.begin(); }
+
+    inline WeightContainer::map_iterator WeightContainer::map_end() 
+    { return m_names.end(); }
+
+    inline WeightContainer::const_map_iterator WeightContainer::map_begin() const 
+    { return m_names.begin(); }
+
+    inline WeightContainer::const_map_iterator WeightContainer::map_end() const 
+    { return m_names.end(); }
+
 } // HepMC
 
