Index: trunk/Utilities/HepMC/interface/GenEvent.h
===================================================================
--- trunk/Utilities/HepMC/interface/GenEvent.h	(revision 349)
+++ 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);
     }
 
