#ifndef H_CORAL_IO_XMI_2
#define H_CORAL_IO_XMI_2
// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

#include "io.h"

#include <ostream>
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <utility>

#include <coral/core/ElementDefinition.h>
#include "xmi_writer_common.h"

#ifdef SWIG
#error SWIG should not include coral/core/io/xmi_writer_2.h
#endif

namespace coral {
     class EXPORTFWD_coral Element;
     class EXPORTFWD_coral Slot;
     class EXPORTFWD_coral Set;
     class EXPORTFWD_coral Language;

     namespace io {
	  class XMIStreamer2: public XMIStreamerCommon {
	  private:
		  void saveElement(std::set<const coral::Element*>& saved_elements,
				   coral::Set* all,
				   std::ostream& out,
				   const coral::Element* elem,
				   int margin,
				   const char* slotname,
				   coral::kind_t,
				   bool require_ns_prefix,
				   const AbstractElementDefinition* should_be_of_type);
		  void writeField_xmi2(std::ostream& out,
				       const coral::Property* p,
				       const coral::ElementPrimitive* e,
				       int margin);
		  /*
		   * For keeping track of xmlns definitions.
		   * Must be ordered, since xmlns declarations
		   * are valid only within the XML node they
		   * were created.
		   */
		  typedef struct {
		       int depth;
		       const coral::Package* pkg;
		       std::string xmiNsPrefix;
		  } lu_contents_t;
		  typedef std::vector<lu_contents_t>
		    packages_used_t;
		  packages_used_t packages_used;
		  int cur_depth;

		  std::string invent_unique_xmi_ns_prefix(
		       const packages_used_t& pu,
		       const Package* p);
							  
		  std::pair<bool, const std::string>
		       get_ns_prefix(const Package* P);
		  const std::string writeXMLNS(const Package* P,
					       std::ostream& out);
	  public:
		  XMIStreamer2();
		  virtual ~XMIStreamer2() throw ();
		  void saveModel(const coral::Collection*,
				 std::ostream& out = std::cout)
			  throw (std::exception);
	  };
     }
}

#endif

