[GME-commit] GMESRC/Paradigms/MetaGME/BonExtension8/Rep Any.cpp, NONE, 1.1 Any.h, NONE, 1.1 AtomRep.cpp, NONE, 1.1 AtomRep.h, NONE, 1.1 AttributeRep.cpp, NONE, 1.1 AttributeRep.h, NONE, 1.1 CodeGen.cpp, NONE, 1.1 CodeGen.h, NONE, 1.1 CodeGenReg.cpp, NONE, 1.1 CodeGenTemplate.cpp, NONE, 1.1 ConnJoint.cpp, NONE, 1.1 ConnJoint.h, NONE, 1.1 ConnectionRep.cpp, NONE, 1.1 ConnectionRep.h, NONE, 1.1 Dumper.cpp, NONE, 1.1 Dumper.h, NONE, 1.1 FCO.cpp, NONE, 1.1 FCO.h, NONE, 1.1 FcoRep.cpp, NONE, 1.1 FcoRep.h, NONE, 1.1 FolderRep.cpp, NONE, 1.1 FolderRep.h, NONE, 1.1 MakeVisitor.cpp, NONE, 1.1 MakeVisitor.h, NONE, 1.1 Method.cpp, NONE, 1.1 Method.h, NONE, 1.1 ModelRep.cpp, NONE, 1.1 ModelRep.h, NONE, 1.1 PointerItem.cpp, NONE, 1.1 PointerItem.h, NONE, 1.1 ReferenceRep.cpp, NONE, 1.1 ReferenceRep.h, NONE, 1.1 RoleRep.cpp, NONE, 1.1 RoleRep.h, NONE, 1.1 RootFolder.cpp, NONE, 1.1 RootFolder.h, NONE, 1.1 SetRep.cpp, NONE, 1.1 SetRep.h, NONE, 1.1 Sheet.cpp, NONE, 1.1 Sheet.h, NONE, 1.1

Log messages of CVS commits gme-commit at list.isis.vanderbilt.edu
Fri Mar 14 16:13:54 CDT 2008


Update of /project/gme-repository/GMESRC/Paradigms/MetaGME/BonExtension8/Rep
In directory escher:/tmp/cvs-serv28536/Rep

Added Files:
	Any.cpp Any.h AtomRep.cpp AtomRep.h AttributeRep.cpp 
	AttributeRep.h CodeGen.cpp CodeGen.h CodeGenReg.cpp 
	CodeGenTemplate.cpp ConnJoint.cpp ConnJoint.h 
	ConnectionRep.cpp ConnectionRep.h Dumper.cpp Dumper.h FCO.cpp 
	FCO.h FcoRep.cpp FcoRep.h FolderRep.cpp FolderRep.h 
	MakeVisitor.cpp MakeVisitor.h Method.cpp Method.h ModelRep.cpp 
	ModelRep.h PointerItem.cpp PointerItem.h ReferenceRep.cpp 
	ReferenceRep.h RoleRep.cpp RoleRep.h RootFolder.cpp 
	RootFolder.h SetRep.cpp SetRep.h Sheet.cpp Sheet.h 
Log Message:
Rawcomponent implementation of BonXtender.


CVS User: Zoltan Molnar, ISIS (zolmol)

--- NEW FILE: CodeGen.h ---
#ifndef CODEGEN_H
#define CODEGEN_H

#include "FCO.h"
#include "FolderRep.h"
#include "ModelRep.h"
#include "SetRep.h"
#include "ReferenceRep.h"
#include "ConnectionRep.h"
#include "Method.h"

//#include "vector"

class CodeGen
{

public:
	static std::string fill( int i = 1);
	static std::string indent( int i = 0);


	/**
	 * Visitor related methods
	 */

	static std::string folderKidsTemplate();
	static std::string modelKidsTemplate();
	static Method acceptMethod( Any * any, bool pWithTraversalOfKids, bool pSpecialized, bool pRetValBool);
	//obsolete static Method folderAcceptMethod( Any * cont, bool pWithTraversalOfKids, bool pSpecialized);
	//static Method modelAcceptMethod( Any * cont, bool pWithTraversalOfKids, bool pSpecialized);
	
	/**
	 * Folder related generators
	 */
	static void folderGetter( const std::string& retval_folderkind, const std::string& sub_name, const std::string& method_name, bool extended, Any * cont, Method& m);
	static void folderGetterGeneric( const std::string& retval_folderkind, const std::string& sub_name, const std::string& method_name, bool extended, Any * cont, Method& m);

	static void dumpFoldGetter( FolderRep* sub, FolderRep *fold);

	static void kindGetter1( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m);
	static void kindGetter2( const std::string& retval_kind, const std::string& kind, const std::vector< std::string>& kind_vec, const std::string& method_name, Any * cont, Method& m);	
	static void kindGetter3( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m);

	static void kindGetter1Generic( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m);
	static void kindGetter2Generic( const std::string& retval_kind, const std::string& kind, const std::vector< std::string>& kind_vec, const std::string& method_name, Any * cont, Method& m);	
	static void kindGetter3Generic( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m);

	static void dumpKindGetter( FCO* fco, FolderRep * cont);


	/**
	 * Model related generators
	 */
	static void roleGetter1( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m);
	static void roleGetter1Generic( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m);

	static void roleGetter2( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m);
	static void roleGetter2Generic( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m);

	static void roleGetter3( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& role_name, const std::vector< std::string > & roles, const std::string& dummy_str, Any * cont, Method& m);
	static void roleGetter3Generic( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name,  const std::string& role_name, const std::vector< std::string > & roles, const std::string& dummy_str, Any * cont, Method& m);

	static void roleGetter4( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& desc_k_name, const std::string& role_name, const std::string& nmsp, Any * cont, Method& m);
	static void roleGetter4Generic( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& desc_k_name, const std::string& role_name, const std::string& nmsp, Any * cont, Method& m);

	static void dumpRoleGetter( FCO* fco, RoleRep * role, ModelRep *);

	/**
	 * Set related generators
	 */
	
	static Method dumpSetGetter( SetRep * cont, const FCO * fco, const std::string& comm_kind, bool aggreg = false, bool dummy_par = false);
	static Method dumpSetGetterGeneric( SetRep * cont, const FCO * fco, const std::string& comm_kind, bool aggreg = false, bool dummy_par = false);

	/**
	 * Reference related generators
	 */
	static Method dumpRefGetter( ReferenceRep * cont, FCO * fco, const std::string& comm_kind);

	
	
	/**
	 * Connection related generators
	 */
	
	// get<In, Out>ConnectionLinks
	static Method dumpGetInConnectionLinks( FCO *fco, ConnectionRep * conn);
	static Method dumpGetOutConnectionLinks( FCO *fco, ConnectionRep * conn);
	static Method dumpGetBothConnectionLinks( FCO *fco, ConnectionRep * conn);
	
	static Method dumpGetInConnectionLinksGeneric( FCO *fco, ConnectionRep * conn);
	static Method dumpGetOutConnectionLinksGeneric( FCO *fco, ConnectionRep * conn);
	static Method dumpGetBothConnectionLinksGeneric( FCO *fco, ConnectionRep * conn);

	// get<In, Out>ConnectionEnd
	static Method dumpGetInConnectionEnd( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);
	static Method dumpGetOutConnectionEnd( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);
	static Method dumpGetBothConnectionEnd( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);
	
	static Method dumpGetInConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);
	static Method dumpGetOutConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);
	static Method dumpGetBothConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep * conn, bool refport);

	//get<Src, Dst>
	static Method dumpGetSrc(FCO *fco, ConnectionRep * conn, bool refport);
	static Method dumpGetDst(FCO *fco, ConnectionRep * conn, bool refport);
};

#endif // CODEGEN_H
--- NEW FILE: ConnectionRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "ConnectionRep.h"
#include "logger.h"
#include "ModelRep.h"
#include "CodeGen.h"

#include "globals.h"
extern Globals global_vars;


ConnectionRep::ConnectionRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
{ 
	m_jointList.clear();
}


ConnectionRep::~ConnectionRep()
{
	m_jointList.clear();
}


void ConnectionRep::addJoint( ConnJoint & joint)
{
	m_jointList.push_back( joint);
}


void ConnectionRep::appendJointElements( const ConnJoint & old_joint)
{
	ConnJoint joint( old_joint); // create a copy of the old joint
	joint.setConnectionPtr( this); // set the new container connection

	if (m_jointList.empty())
		m_jointList.push_back( joint);
	else // with some constraint, but still copying
		m_jointList.push_back( joint);
}


void ConnectionRep::inherit()
{
	ModelRepPtrList models = this->modelsIAmPartOfFinal();
	
	// interface inheritance
	ModelRepPtrList_Iterator mod_it = models.begin();
	// for all models i am part of
	for( ; mod_it != models.end(); ++mod_it )
	{
		ModelRep* mod_ptr = *mod_it;

		// for all connJoints it has
		std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
		for( ; joint_it != m_jointList.end(); ++joint_it )
		{
			joint_it->intInherit( mod_ptr); // creates map containing src and dst roles
		}
	}

	// implementation inheritance
	// not needed since the inheritance provides the needed functionality
}


std::string ConnectionRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);

	dumpFCO( h_file, c_file);

	if ( !m_connMethods.empty())
		h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// connectionEnd getters\n";

	MethodLexicographicSort lex;
	std::sort( m_connMethods.begin(), m_connMethods.end(), lex);

	std::vector<Method>::iterator i = m_connMethods.begin();
	for( ; i != m_connMethods.end(); ++i)
	{
		h_file += i->getHeader() + "\n";
		c_file += i->getSource() + "";
	}

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}


bool ConnectionRep::checkConnectionTargets()
{
	bool res = true;
	std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
	for( ; joint_it != m_jointList.end(); ++joint_it )
	{
		res = res && joint_it->checkElements( getName());
	}
	return res;
}


bool ConnectionRep::calcLCD()
{
	std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
	for( ; joint_it != m_jointList.end(); ++joint_it )
		joint_it->calcLCD();

	return true;
}

bool ConnectionRep::createEndGetters()
{
	std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
	for( ; joint_it != m_jointList.end(); ++joint_it )
	{
		joint_it->createLinkGetters();
		joint_it->createSrcDstGetters();
		joint_it->createEndGetters();
	}
	return true;
}


--- NEW FILE: Method.cpp ---
#include "stdafx.h"

#include "method.h"
#include "Any.h"
#include "CodeGen.h"

static const std::string orn = "//********************************************************************************\n";
/*const*/ extern int h_ind;
/*const*/ extern int s_ind;

bool MethodLexicographicSort::operator()( const Method& op1, const Method& op2) const
{
	const std::string s1 = op1.m_signature;
	const std::string s2 = op2.m_signature;
	return ( s1.compare(s2) < 0);
}


Method::Method()
	: m_virtual( true)
	, m_static( false)
	, m_template( false)
	, m_returnValue()
	, m_signature()
	, m_implementation()
	, m_comment()
	, m_container(0)
{ }


std::string Method::getHeader()
{
	if ( m_template)
	{
		return  CodeGen::indent(h_ind) + orn +
				CodeGen::indent(h_ind) + "// " + m_comment + "\n" +
				CodeGen::indent(h_ind) + orn +
				m_returnValue + CodeGen::indent(2) + m_signature + "\n" + m_implementation;
	}

	std::string ret_val = (m_virtual?"virtual ":"") + m_returnValue;
	int fill_size = ret_val.size() < 20? 20 - ret_val.size(): ret_val.size() < 40? 40-ret_val.size(): ret_val.size() < 50? 50-ret_val.size():1;
	return CodeGen::indent(h_ind) + ret_val + CodeGen::fill( fill_size) + m_signature + ";";
}


std::string Method::getSource()
{
	if ( m_template || m_implementation.empty()) // templates or dummies like init/finalize
		return "";

	ASSERT( m_container);
	return 
		CodeGen::indent(s_ind) + orn + 
		CodeGen::indent(s_ind) + "// " + m_comment + "\n" + 
		CodeGen::indent(s_ind) + orn + 
		CodeGen::indent(s_ind) + m_returnValue + " " + m_container->getValidNmspc() + Any::NamespaceDelimiter_str + m_container->getValidNameImpl() + "::" + m_signature + "\n" + 
		m_implementation;
}


std::string Method::getExposed( const std::string& repl_cont)
{
	// the using directive needs the immediate parent to be specified before the '::'
	// so grandparent's name is not allowed
	// i.e: 
	//         A<>-----r
	//        /|\
	//         |
	//         B<>-----p
	//        /.\
	//         |
	//         C (implementation inheritance between B and C)
	//
	//  in such cases C inherits privately from A thus hides to its users the 
	//  methods inherited like: getr() and getp()
	//  these methods needed to be exposed by 
	//  using B::getp;
	//  using A::getr; directives
	//  but the latter i not allowed (A is granparent of C), so 'using B::getr;' has to be used
	//  this is valid since B does have getr() method (inherited)
	ASSERT( m_container);
	return CodeGen::indent(h_ind) + "using " + (repl_cont.empty()?m_container->getValidNameImpl():repl_cont) + "::" + m_signature.substr(0, m_signature.find('(')) + ";";
}


std::string Method::getHidden()
{
	return CodeGen::indent(h_ind) + (m_template?"":"virtual ") + m_returnValue + " " + m_signature + 
		" { throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + m_signature + " method.\"); }";
	
}


Method::operator bool()
{
	if ( m_container != 0) 
		return true;
	else
		return false;
}


--- NEW FILE: ModelRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "ReferenceRep.h"
#include "ModelRep.h"
#include "Dumper.h"
#include "CodeGen.h"

#include "logger.h"
#include <algorithm>

#include "globals.h"
extern Globals global_vars;
extern int h_ind;

ModelRep::ModelRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
	, m_initialRoleMap()
	, m_finalRoleMap()
	, m_methods()
{ 
}


ModelRep::~ModelRep()
{
	m_initialRoleMap.clear();
	m_finalRoleMap.clear();
	m_methods.clear();
}

	
void ModelRep::addRole( FCO* whose, RoleSeriesValue& role) 
{ 
	RoleMapValue &series = m_initialRoleMap[ whose ];

	// avoiding double insertion
	// searching for the role in the role register
	RoleSeries_Iterator it = std::find( series.begin(), series.end(), role);

	if ( it == series.end() ) // not found
		series.push_back( role);
	else 
		global_vars.err << "Error: Found duplicate role \"" << role.getSmartRoleName() << "\" in model \"" << getName() << "\"\n";
}


void ModelRep::initRoles()
{
	RoleMap_Iterator it = m_initialRoleMap.begin();
	for( ; it != m_initialRoleMap.end(); ++it)
	{
		RoleMapKey fco = it->first; // FCO *
		std::string nn = fco->getName();

		std::vector<FCO*> children;
		fco->getIntDescendants( children);

		//global_vars.err << getName() << ":" << nn << " # of int desc " << children.size() << "\n";

		int how_many_non_abstract = 0;
		if ( !fco->isAbstract()) ++how_many_non_abstract;
		for( unsigned int i = 0; i < children.size(); ++i)
		{
			std::string cn = children[i]->getName();
			if (! children[i]->isAbstract()) 
				++how_many_non_abstract;
		}

		// at this point the how_many_non_abstract
		// value indicates how many non abstract instances may exist
		// and how many will have the use the same role names
		// so if this value is greater than 1 then long form, otherwise 
		// short form (default) should be used

		if ( how_many_non_abstract > 1 ) // long_form_flag needs to be true for this fco's roles
		{
			RoleMapValue &series = it->second;
			RoleSeries_Iterator role_it = series.begin();
			for(; role_it != series.end(); ++role_it)
			{
				role_it->setLongForm( true);
			}
		}
	}
}


bool ModelRep::getRoles( FCO * ptr, RoleMapValue& map_val) const
{
	RoleMap_ConstIterator it = m_initialRoleMap.find( ptr);
	if ( it == m_initialRoleMap.end())
		return false;

	map_val = it->second;
	return true;
}


std::vector< ModelRep* > ModelRep::getInnerModels() const
{
	std::vector< ModelRep* > models;

	RoleMap_ConstIterator it = m_initialRoleMap.begin();
	while ( it != m_initialRoleMap.end())
	{
		FCO * const ptr = it->first; // ModelRep *
		if ( ptr->getMyKind() == Any::MODEL)
		{
			ModelRep * mod_ptr = dynamic_cast< ModelRep *> ( ptr);
			models.push_back( mod_ptr);
		}
		++it;
	}
	return models;
}


/*------------------------------------------------------------*/


void ModelRep::addFinalRole( FCO* whose, RoleSeriesValue& role) 
{ 
	RoleMapValue &series = m_finalRoleMap[ whose ];

	// avoiding double insertion
	// searching for the role in the role register
	RoleSeries_Iterator it = std::find( series.begin(), series.end(), role);

	if ( it == series.end() ) // not found
		series.push_back( role);
	else 
		global_vars.err << "Error: Found duplicate final role \"" << role.getSmartRoleName() << "\" in model \"" << getName() << "\"\n";
}

bool ModelRep::getFinalRoles( const FCO * ptr, RoleMapValue& map_val) const
{
	RoleMap_ConstIterator it = m_finalRoleMap.begin();
	while ( it != m_finalRoleMap.end() && it->first != ptr)
		++it;
	if ( it == m_finalRoleMap.end())
		return false;
	map_val = it->second;
	return true;
	/*RoleMap_ConstIterator it = m_finalRoleMap.find( ptr);
	if ( it == m_finalRoleMap.end())
		return false;

	map_val = it->second;
	return true;*/
}


std::vector< ModelRep* > ModelRep::getInnerModelsFinal() const
{
	std::vector< ModelRep* > models;

	RoleMap_ConstIterator it = m_finalRoleMap.begin();
	while ( it != m_finalRoleMap.end())
	{
		FCO * const ptr = it->first; // ModelRep *
		if ( ptr->getMyKind() == Any::MODEL)
		{
			ModelRep * mod_ptr = dynamic_cast< ModelRep *> ( ptr);
			models.push_back( mod_ptr);
		}
		++it;
	}
	return models;
}


std::vector< ReferenceRep *> ModelRep::getInnerModelReferencesFinal() const
{
	std::vector< ReferenceRep *> refs;
	RoleMap_ConstIterator it = m_finalRoleMap.begin();
	while ( it != m_finalRoleMap.end())
	{
		FCO * const ptr = it->first;
		if ( ptr->getMyKind() == Any::REF)
		{
			ReferenceRep * ref_ptr = dynamic_cast< ReferenceRep *> ( ptr);
			if ( ref_ptr->pointsToModels())
				refs.push_back( ref_ptr);
		}
		++it;
	}
	return refs;
}


// adding new roles for descendants of current members
//
//    B----x-<>Model1
//    |        <>  |
//   /^\       |   |
// A1   A2     y   ^
//        \    |   |
//         A3  | Model2
//           \ |
//            A4
//              \
//               A5
// in this case the A1,A2 and A3 may have its own roles in M, called inherited roles
// but A4 and A5 will have two roles: x and y

void ModelRep::inherit()
{
	//temp
	std::string m_name;
	std::string f_name;
	//temp
	
	RoleMap temp_map;
	std::vector<FCO*> model_descendants;
	this->getImpDescendants( model_descendants); // needed because of complexity
	model_descendants.push_back( this);

	// for each model implementation descendant
	std::vector<FCO*>::reverse_iterator model_it = model_descendants.rbegin();
	for( ; model_it != model_descendants.rend(); ++model_it)
	{
		if ( (*model_it)->getMyKind() != Any::MODEL)
			global_vars.err << std::string("ERROR: model inherit\n");
		ModelRep * mod_desc_ptr = dynamic_cast<ModelRep*>(*model_it);
		if (!mod_desc_ptr) global_vars.err << std::string("NULL PTR ERROR: model inherit\n");
		m_name = mod_desc_ptr->getName();
					
		RoleMap_Iterator fco_it( m_initialRoleMap.begin());
		// for each FCO
		for( ; fco_it != m_initialRoleMap.end(); ++fco_it)
		{ 
			RoleMapKey fco_ptr = fco_it->first;
			std::vector<FCO*> children;
			
			fco_ptr->getIntDescendants( children);
			children.push_back( fco_ptr);

			// take its roleList
			RoleSeries &roles = fco_it->second; // RoleMapValue

			RoleSeries_Iterator role_it = roles.begin();
			// for each role
			for( ; role_it != roles.end(); ++role_it)
			{
				std::vector<FCO*>::iterator desc_it = children.begin();
				// for each interface descendant
				for( ; desc_it != children.end(); ++desc_it)
				{
					f_name = (*desc_it)->getName();

					// the descendants must have a separate role for each initial role
					// this role is inherited and has long form depending on the hierarchy_flag
					//TO( role_it->getOnlyRoleName());
					RoleRep r( 
						role_it->getOnlyRoleName(),
						*desc_it,
						mod_desc_ptr,//role_it->getModelRepPtr(), // = this
						role_it->isPort(),
						role_it->getCardinality(),
						mod_desc_ptr != this,//true, // inherited role
						role_it->isLongForm());
					
					mod_desc_ptr->addFinalRole( *desc_it, r);
					(*desc_it)->iAmPartOfFinal( mod_desc_ptr);//(*desc_it)->iAmPartOf( this);
					//TO( bon_ptr->GetName() + " < " + r.getRoleName().c_str() + " > " + bon_m_ptr->GetName());
				}
			}
		}
	}
}


bool ModelRep::check()
{
	return true;
}


/*
used when the long form is NOT needed for role
*/
/*static*/ std::string ModelRep::roleGetterMethodName2(FCO * fco, RoleRep* role, bool use_fco_name, const std::string& diff_nmsp)
{
#if(LONG_NAMES)
	return "get_Role_" + (role->getOnlyRoleName().empty()?fco->getValidName():role->getOnlyRoleName());
#else
	return "get" + diff_nmsp + (role->getOnlyRoleName().empty()?fco->getValidName():role->getOnlyRoleName());
#endif
}


/*
used when the long form is needed for role
*/
/*static*/ std::string ModelRep::roleGetterMethodName3(FCO * fco, RoleRep* role, bool use_fco_name, const std::string& diff_nmsp)
{
#if(LONG_NAMES)
	return "get_Role_" + (role->getOnlyRoleName().empty()?fco->getValidName():fco->getValidName() + role->getOnlyRoleName());
#else
	return "get" + diff_nmsp + (role->getOnlyRoleName().empty()?fco->getValidName():fco->getValidName() + role->getOnlyRoleName());
#endif
}


void ModelRep::createMethods()
{
	RoleMap_Iterator r_it = m_initialRoleMap.begin();
	while ( r_it != m_initialRoleMap.end())
	{
		RoleMapKey ptr = r_it->first;
		RoleMapValue &roles = r_it->second;
		RoleSeries_Iterator jt = roles.begin();
		for( ; jt != roles.end() ; ++jt)
		{
			CodeGen::dumpRoleGetter( ptr, &*jt, this);
		}
		++r_it;
	}
}


std::string ModelRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);
	dumpFCO( h_file, c_file);

	if ( !m_methods.empty())
		h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// kind and role getters\n";

	MethodLexicographicSort lex;
	std::sort( m_methods.begin(), m_methods.end(), lex);
	
	std::vector<Method>::iterator i = m_methods.begin();
	for( ; i != m_methods.end(); ++i)
	{
		if ( !i->m_template)
		{
			h_file += i->getHeader() + "\n";
			c_file += i->getSource() + "";
		}
		else
			h_file += i->getHeader() + "\n";
	}

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}

std::string ModelRep::expose( const std::string& repl_container)
{
	std::string h_file;
	h_file += FCO::expose( repl_container);

	if (!m_methods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// exposed kind and role getters\n";
	std::vector<Method>::iterator i = m_methods.begin();
	for( ; i != m_methods.end(); ++i)
		h_file += i->getExposed( repl_container) + "\n";

	return h_file;
}


std::string ModelRep::hide()
{
	std::string h_file;
	h_file += FCO::hide();

	if (!m_methods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// hidden kind and role getters\n";
	std::vector<Method>::iterator i = m_methods.begin();
	for( ; i != m_methods.end(); ++i)
		h_file += i->getHidden() + "\n";

	return h_file;
}


--- NEW FILE: MakeVisitor.cpp ---
#include "stdafx.h"
#include "MakeVisitor.h"
#include "Dumper.h"

#include "algorithm"

#include "globals.h"
extern Globals global_vars;

/*static*/ ClassAndNamespace ClassAndNamespace::makeIt( Any *ptr)
{
	return ClassAndNamespace( ptr->getValidName(), ptr->getValidNmspc(), ptr->getStrictNmspc());
}

ClassAndNamespace::ClassAndNamespace( const std::string& pName, const std::string& pSpace, const std::string& pStrictSpace)
	: m_name( pName)
	, m_space( pSpace)
	, m_strictSpace( pStrictSpace)
{
}

std::string ClassAndNamespace::name() const
{
	return m_name;
}

std::string ClassAndNamespace::space() const
{
	return m_space;
}

std::string ClassAndNamespace::strictSpace() const
{
	return m_strictSpace;
}



std::string ClassAndNamespace::infoName() const
{
	if( Dumper::m_iVisitSign == 1) // altered, short form like: visitComp
		return m_name;
	else                           // more informative: visitPicmlComp (namespace included)
		return m_strictSpace + m_name; // used only in places where the concatenation is informative, but not necessarily correct syntactically
}

std::string ClassAndNamespace::exactType() const
{
	return m_space + Any::NamespaceDelimiter_str + m_name;
}

void MakeVisitor::addEntity( Any::KIND_TYPE kind, const ClassAndNamespace& ent)
{
	m_entities[kind].push_back( ent);
}

std::string MakeVisitor::dumpVisitorHeader()
{
	std::string short_form_header_file;
	int pos = global_vars.header_file_name.rfind( '\\');
	if ( pos != std::string::npos)
	{
		if ( pos + 1 < global_vars.header_file_name.length())
			short_form_header_file = global_vars.header_file_name.substr( pos + 1);
		else
			short_form_header_file = "insert_your_specialized_header_filename_here.h";
	}
	else
		short_form_header_file = global_vars.header_file_name;

	std::string capitalized_name = m_className;
	std::transform( capitalized_name.begin(), capitalized_name.end(), capitalized_name.begin(), toupper);

	std::string mmm;
	mmm += "#ifndef " + capitalized_name + "_H\n";
	mmm += "#define " + capitalized_name + "_H\n";
	mmm += "\n";
	mmm += "#include \"BON.h\"\n";
	mmm += "#include \"BONImpl.h\"\n";
	mmm += "#include \"Extensions.h\"\n";
	mmm += "#include \"" + short_form_header_file + "\"\n";
	mmm += "\n";
	mmm += "namespace " + global_vars.m_namespace_name +"\n";
	mmm += "{\n";
	mmm += "\n";

	mmm += "class " + m_className + "\n";
	mmm += "	: public BON::Visitor\n";
	mmm += "{\n";
	//mmm += "		" + m_className + "();\n"; need any constructor?
	//mmm += "\n";

	mmm += "	public : \n";
	mmm += "		" + m_className + "();\n"; // constructor
	mmm += "		virtual ~" + m_className + "();\n\n"; // destructor
	if( Dumper::m_bGenAcceptSpeci) // custom visitor
	{
		
		// custom visitor does not need the generic visitors
		mmm += "	public :\n";

		for( unsigned int j = 0; j < HOW_MANY_ITEMS; ++j)
		for( unsigned int i = 0; i != m_entities[j].size(); ++i)
		{
			ClassAndNamespace& ent = m_entities[j][i];
			mmm += "		virtual bool visit" + ent.infoName() + "( const " + ent.exactType() + "& object );\n";
		}
		mmm += "};\n";
	}
	else
	{
		mmm += "	public :\n";

		mmm += "		void visitObjectImpl( const BON::Object& object );\n";
		if ( !m_entities[Any::FCO_REP].empty())
			mmm += "		void visitFCOImpl( const BON::FCO& fco );\n";
		if ( !m_entities[Any::ATOM].empty())
			mmm += "		void visitAtomImpl( const BON::Atom& atom );\n";
		if ( !m_entities[Any::SET].empty())
			mmm += "		void visitSetImpl( const BON::Set& set);\n";
		if ( !m_entities[Any::REF].empty())
			mmm += "		void visitReferenceImpl( const BON::Reference& ref );\n";
		if ( !m_entities[Any::CONN].empty())
			mmm += "		void visitConnectionImpl( const BON::Connection& conn);\n";
		if ( !m_entities[Any::MODEL].empty())
			mmm += "		void visitModelImpl( const BON::Model& model );\n";
		if ( !m_entities[Any::FOLDER].empty())
			mmm += "		void visitFolderImpl( const BON::Folder& fold );\n";

		mmm += "	protected :\n";

		for( unsigned int j = 0; j < HOW_MANY_ITEMS; ++j)
		for( unsigned int i = 0; i != m_entities[j].size(); ++i)
		{
			ClassAndNamespace& ent = m_entities[j][i];
			mmm += "		virtual bool visit" + ent.infoName() + "( const " + ent.exactType() + "& object );\n";
		}
		mmm += "};\n";
	}
	mmm += "\n";
	mmm += "} // namespace\n";
	mmm += "\n";
	mmm += "#endif // " + capitalized_name + "_H\n";

	return mmm;
}


std::string MakeVisitor::dumpVisitorSource( )
{
	std::string mmm;

	mmm += "#include \"stdafx.h\"\n";
	mmm += "#include \"" + m_className +".h\"\n";
	mmm += "\n";
	//mmm += "using namespace BON;\n";
	mmm += "\nnamespace " + global_vars.m_namespace_name +"\n{\n\n";
	
	// ctors
	mmm += m_className + "::" + m_className + "()  { }\n\n";
	mmm += m_className + "::~" + m_className + "() { }\n\n";

	for( unsigned int j = 0; j < HOW_MANY_ITEMS; ++j)
	for( unsigned int i = 0; i != m_entities[j].size(); ++i)
	{
		ClassAndNamespace& ent = m_entities[j][i];
		mmm += dumpSpecificMethods( ent);
	}
	
	if( !Dumper::m_bGenAcceptSpeci) // not a custom visitor
		mmm += dumpGenericMethods();

	mmm += "\n} // namespace\n\n";

	return mmm;
}


std::string MakeVisitor::dumpSpecificMethods( const ClassAndNamespace& ent)
{
	std::string mmm;
	mmm+="bool " + m_className + "::visit" + ent.infoName() + "( const " + ent.exactType() + "& object )\n";
	mmm+="{\n";
	mmm+="	if ( !object)\n";
	mmm+="		return false;\n";
	mmm+="\n";
	mmm+="	return true;\n";
	mmm+="}\n\n\n";

	return mmm;
}


std::string MakeVisitor::dumpGenericMethods()
{
	std::string mmm;


	// visitObjectImpl
	mmm+="void " + m_className + "::visitObjectImpl( const BON::Object& obj )\n";
	mmm+="{}\n\n\n";


	// visitFCOImpl
	if ( !m_entities[Any::FCO_REP].empty()) {
	mmm+="void " + m_className + "::visitFCOImpl( const BON::FCO& fco )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::FCO_REP].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::FCO_REP][i].infoName() + "( fco))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other fco\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}


	// visitAtomImpl
	if ( !m_entities[Any::ATOM].empty()) {
	mmm+="void " + m_className + "::visitAtomImpl( const BON::Atom& atom )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::ATOM].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::ATOM][i].infoName() + "( atom))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Atom\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}


	// visitSetImpl
	if ( !m_entities[Any::SET].empty()) {
	mmm+="void " + m_className + "::visitSetImpl( const BON::Set& set )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::SET].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::SET][i].infoName() + "( set))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Set\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}


	// visitReferenceImpl
	if ( !m_entities[Any::REF].empty()) {
	mmm+="void " + m_className + "::visitReferenceImpl( const BON::Reference& ref )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::REF].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::REF][i].infoName() + "( ref))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Reference\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}


	// visitConnectionImpl
	if ( !m_entities[Any::CONN].empty()) {
	mmm+="void " + m_className + "::visitConnectionImpl( const BON::Connection& conn )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::CONN].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::CONN][i].infoName() + "( conn))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Connection\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}

	
	// visitModelImpl
	if ( !m_entities[Any::MODEL].empty()) {
	mmm+="void " + m_className + "::visitModelImpl( const BON::Model& model )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::MODEL].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::MODEL][i].infoName() + "( model))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Model\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}
	

	// visitFolderImpl
	if ( !m_entities[Any::FOLDER].empty()) {
	mmm+="void " + m_className + "::visitFolderImpl( const BON::Folder& fold )\n";
	mmm+="{\n";
	{
		for( unsigned int i = 0; i != m_entities[Any::FOLDER].size(); ++i) 
			mmm+="	if ( !visit" + m_entities[Any::FOLDER][i].infoName() + "( fold))\n";
	}
	mmm+="	{\n";
	mmm+="		// visiting other Folder\n";
	mmm+="	}\n";
	mmm+="}\n\n\n";
	}


	return mmm;
}
--- NEW FILE: ConnJoint.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "ConnJoint.h"
#include "ConnectionRep.h"
#include "logger.h"
#include "ModelRep.h"
#include "ReferenceRep.h"
#include "Dumper.h"
#include "CodeGen.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;
extern int ind;

std::string ConnJoint::m_srcLabel = "src";
std::string ConnJoint::m_dstLabel = "dst";


ConnJoint::ConnJoint
	(	ConnectionRep * ptr,
		const SDList& op1,
		const SDList& op2,
		bool bidirect,
		std::string card1 /*= ""*/, 
		std::string card2 /*= ""*/
	)
	: m_connPtr( ptr)

	, m_oper1( op1)
	, m_oper2( op2)
	
	, m_oper1TargetMap()
	, m_oper2TargetMap()
	
	, m_bidirect( bidirect)
	
	, m_oper1Card( card1)
	, m_oper2Card( card2)
	
	, m_srcLCD()
	, m_dstLCD()
	
	, m_oper1IsAnyReferencePort( false)
	, m_oper2IsAnyReferencePort( false)
{ }


ConnJoint::ConnJoint( const ConnJoint& peer)
	: m_connPtr( peer.m_connPtr)
	
	, m_oper1( peer.m_oper1)
	, m_oper2( peer.m_oper2)
	
	, m_oper1TargetMap( peer.m_oper1TargetMap)
	, m_oper2TargetMap( peer.m_oper2TargetMap)
	
	, m_bidirect( peer.m_bidirect)
	
	, m_oper1Card( peer.m_oper1Card)
	, m_oper2Card( peer.m_oper2Card)
	
	, m_srcLCD( peer.m_srcLCD)
	, m_dstLCD( peer.m_dstLCD)
	
	, m_oper1IsAnyReferencePort( peer.m_oper1IsAnyReferencePort)
	, m_oper2IsAnyReferencePort( peer.m_oper2IsAnyReferencePort)
{ }


const ConnJoint& ConnJoint::operator=( const ConnJoint& peer)
{
	if ( this == &peer ) return *this;
	m_connPtr = peer.m_connPtr;

	m_oper1 = peer.m_oper1;
	m_oper2 = peer.m_oper2;

	m_oper1TargetMap = peer.m_oper1TargetMap;
	m_oper2TargetMap = peer.m_oper2TargetMap;

	m_bidirect = peer.m_bidirect;

	m_oper1Card = peer.m_oper1Card;
	m_oper2Card = peer.m_oper2Card;

	m_srcLCD = peer.m_srcLCD;
	m_dstLCD = peer.m_dstLCD;

	m_oper1IsAnyReferencePort = peer.m_oper1IsAnyReferencePort;
	m_oper2IsAnyReferencePort = peer.m_oper2IsAnyReferencePort;

	return *this;
}


ConnJoint::~ConnJoint() 
{
	m_connPtr = 0;

	m_oper1.clear();
	m_oper2.clear();

	m_oper1TargetMap.clear();
	m_oper2TargetMap.clear();

	m_srcLCD.clear();
	m_dstLCD.clear();
}


// to be used upon copying
void ConnJoint::setConnectionPtr( ConnectionRep * conn_ptr)
{
	m_connPtr = conn_ptr;
}


const ConnJoint::SDList& ConnJoint::getOp1() const { return m_oper1; }
const ConnJoint::SDList& ConnJoint::getOp2() const { return m_oper2; }


bool ConnJoint::isBidirect() const { return m_bidirect; }


void ConnJoint::addTargetItem( int i, const ModelRep * model, const PointerItem & item)
{
	PointerItemSeries * series;
	if (i==0) series = &m_oper1TargetMap[model];
	else series = &m_oper2TargetMap[model];

	if ( std::find( series->begin(), series->end(), item)
		== series->end()) // not found
		series->push_back( item);
	/*else this may happen because of mutiple inheritance
		global_vars.err << "Connection target : " << item.name() << " added twice to connection.\n";*/
}


void ConnJoint::addTargetItem( int i, const ModelRep * model, const RoleRep & new_role)
{ 
	PointerItem item (new_role.getSmartRoleName(), new_role.getFCOPtr());
	addTargetItem( i, model, item);
}


void ConnJoint::addTargetItem( int i, const ModelRep * model, const RoleRep::RoleRepSeries & new_role_series)
{ 
	RoleRep::RoleRepSeries_ConstIterator r_it = new_role_series.begin();
	for( ; r_it != new_role_series.end(); ++r_it)
		addTargetItem( i, model, *r_it);
}

/*    rationale:
                 ___________________________
                |                           |
                <>                          |
     /-------<> M1<>--p-A1---isPort=true--<>M3
    C -------<> M1<>--r-A1---isPort=true--<>M3
		|\-------<> M2<>--x-A1---isPort=true--<>M3
     \-------<> M2<>--z-A1---isPort=false--<>M3
where C connects A1 kind of atoms
and M3 is contained by M1 and M2

this means that p,r,x,z can be extended with M3 p, M3 r, M3 x


	or another example:


    C -------<> M1<>----M4
		|\-------<> M2<>----M5
     \-------<> M3<>----M6
		            <>      <>
								 |     /
								 |   /
								 | /
	               A1
where C connects A1 kind of atoms
if (A1 containment M4..6) relation has the isPort attribute set to true
then the C has to be extended with the M4 A1, M5 A1, M6 A1 targets
*/
void ConnJoint::intInherit( ModelRep * mod_ptr)
{
	std::string con_name = m_connPtr->getName(); //t
	std::string mod_name = mod_ptr->getName(); //t

	const int number_of_endpoints = 2;
	bool reference_ports_also[ number_of_endpoints] = { false, false }; 

	TargetMap * target_map[ number_of_endpoints] = { &m_oper1TargetMap, &m_oper2TargetMap };

	std::vector<ModelRep*> inner_models1 = mod_ptr->getInnerModelsFinal();
	
	std::vector< const ModelRep*> inner_models( inner_models1.size());
	std::copy( inner_models1.begin(), inner_models1.end(), inner_models.begin());
	
	std::vector<ReferenceRep*> inner_modelreferences = mod_ptr->getInnerModelReferencesFinal();
	std::vector<ReferenceRep*>::iterator model_ref_it = inner_modelreferences.begin();
	for( ; model_ref_it != inner_modelreferences.end(); ++model_ref_it)
	{
		std::string m_r_n = (*model_ref_it)->getName();//t

		std::vector<const ModelRep *> models_ref_refers = (*model_ref_it)->getModelRefVector(); // all models the reference refers to
		std::vector<const ModelRep *>::iterator ref_model_it = models_ref_refers.begin();
		for( ; ref_model_it != models_ref_refers.end(); ++ref_model_it)
		{
			std::string r_m_n = (*ref_model_it)->getName();
			if ( std::find( inner_models.begin(), inner_models.end(), *ref_model_it) == inner_models.end())
				inner_models.push_back( *ref_model_it);
		}
	}
	// inner_models now contains all inner models and all models the inner references refer to
	// why? because the inner references may look like the model they refer to, so if a port is
	// visible on a model then that port is visible on all references (to that model)

	SDList* targets[ number_of_endpoints] = { &m_oper1, &m_oper2 };
	// for each target (src and dst)
	for( int i = 0; i < number_of_endpoints; ++i)
	{
		SDList_Iterator op_it = targets[i]->begin();
		for( ; op_it != targets[i]->end(); ++op_it)
		{
			FCO* target_ptr = *op_it;

			std::vector<FCO*> descendants;

			// inquiring the descendants who have the same Interface
			target_ptr->getIntDescendants( descendants);
			descendants.push_back( target_ptr);

			std::vector<FCO*>::reverse_iterator desc_it = descendants.rbegin();
			// for each desc
			for( ; desc_it != descendants.rend(); ++desc_it)
			{
				FCO * fco = *desc_it;
				std::string fco_name = fco->getName();

				//*desc_it -> is a potential target -> 
				if ( !fco->isAbstract() ) 
				{
					//inquire the roles this FCO has in this model
					//const RoleRepSeries & series = fco_ptr->getMyRoles( mod_ptr);
					RoleRep::RoleRepSeries series;
					bool has_some = mod_ptr->getFinalRoles( fco, series);
					if ( has_some && !series.empty()) 
					{
						// add the roles to the member list of the set ( in that model) 
						this->addTargetItem( i, mod_ptr, series);
					}

					std::vector<const ModelRep*>::iterator sub_mod_it = inner_models.begin();
					for(; sub_mod_it != inner_models.end(); ++sub_mod_it)
					{
						const ModelRep * sub_model = *sub_mod_it;
						std::string sm_name = sub_model->getName();
						// inquire the roles of fco in the sub_model
						RoleRep::RoleRepSeries roles_in_sub_model;
						bool has_some = sub_model->getFinalRoles( fco, roles_in_sub_model);
						RoleRep::RoleRepSeries_ConstIterator r_it = roles_in_sub_model.begin();
						for( ; has_some && r_it != roles_in_sub_model.end(); ++r_it) // if (!roles_in_sub_model.empty())
						{
							RoleRep sub_role = *r_it;	//TOF("    pe sub_role: " + sub_role.getSmartRoleName() + " in " + sub_model->getName());
							//check if any role is port
							if ( sub_role.isPort()) // this role may appear as a port of sub_model (and/or may appear as a port of a reference to this submodel too)
							{
								if ( sub_model->getMyKind() == Any::MODEL && !sub_model->isAbstract())
								{
									// fetch all roles of sub_model_desc in model
									RoleRep::RoleRepSeries sub_model_roles_in_model;
									bool has_some_subm = mod_ptr->getFinalRoles( sub_model, sub_model_roles_in_model ); // if the model contains sub_model with some roles
									RoleRep::RoleRepSeries_ConstIterator r_it_sm = sub_model_roles_in_model.begin();
									for( ; has_some_subm && r_it_sm != sub_model_roles_in_model.end(); ++r_it_sm )
									{
										std::string desc_sub_model_role_name = r_it_sm->getSmartRoleName();
										PointerItem item = desc_sub_model_role_name + " " + sub_role.getSmartRoleName();
										this->addTargetItem( i, mod_ptr, item);
									}
									// take a look on the references to sub_model
									const FCO::ReferenceRepList &ref_list = sub_model->getTransitiveReferencesToMe(); //references may point to submodel
									FCO::ReferenceRepList_ConstIterator ref_it = ref_list.begin();
									for( ; ref_it != ref_list.end(); ++ref_it)
									{
										if( !(*ref_it)->isAbstract() && (*ref_it)->amIPartOfFinal( mod_ptr) ) // if model may contain the reference
										{
											RoleRep::RoleRepSeries sub_ref_roles_in_model;
											bool ref_has_roles = mod_ptr->getFinalRoles( *ref_it, sub_ref_roles_in_model ); // if the model contains reference with some roles
											RoleRep::RoleRepSeries_ConstIterator r_it_ref = sub_ref_roles_in_model.begin();
											for( ; ref_has_roles && r_it_ref != sub_ref_roles_in_model.end(); ++r_it_ref )
											{
												std::string desc_sub_ref_role_name = r_it_ref->getSmartRoleName();
												PointerItem item = desc_sub_ref_role_name + " " + sub_role.getSmartRoleName();
												this->addTargetItem( i, mod_ptr, item);
												reference_ports_also[i] = true; // this will indicate
											}
											/* changed on 3/9/2004
											PointerItem item = (*ref_it)->getName() + " " + sub_role.getSmartRoleName();
											this->addTargetItem( i, mod_ptr, item);
											reference_ports_also[i] = true; // this will indicate
											*/
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	// these values may be set after several calls to intInherit, that is why
	m_oper1IsAnyReferencePort = m_oper1IsAnyReferencePort || reference_ports_also[0];
	m_oper2IsAnyReferencePort = m_oper2IsAnyReferencePort || reference_ports_also[1];
}


bool ConnJoint::checkElements( std::string connection_name)
{
	bool res = true;
	const int number_of_lists = 2;
	const int number_of_endpoints = 2;

	const SDList* lists [ number_of_endpoints]= 
	{
		&m_oper1, &m_oper2
	};

	for( int i = 0; i < number_of_endpoints; ++i)
	{
		SDList_ConstIterator fco_it = lists[i]->begin();
		// for all fcos of the src or dst lists
		for( ; fco_it != lists[i]->end(); ++fco_it)
		{
			FCO * member_ptr = *fco_it;

			if ( !member_ptr->checkIsPartOfFinal() && !member_ptr->isAbstract())
			{
				global_vars.err << "CHECK: \"" << member_ptr->getName() << "\" fco in connection \"" << connection_name << "\" is not contained by any model.\n";
				res = false;
			}
		}
	}
	return res;
}


bool ConnJoint::calcLCD()
{
	if (!m_bidirect && !m_oper1.empty())
	{
		m_srcLCD = FCO::lcdIntersect( m_oper1);
	}
	if (!m_bidirect && !m_oper2.empty())
	{
		m_dstLCD = FCO::lcdIntersect( m_oper2);
	}
	if (!m_bidirect)
	{
		std::string mmm = "Src lcd: ";
		std::vector<FCO*>::iterator it = m_srcLCD.begin();
		for(; it != m_srcLCD.end(); ++it)
		{
			mmm += (*it)->getName() + "\t";
		}
		mmm += "\nDst lcd: ";
		it = m_dstLCD.begin();
		for(; it != m_dstLCD.end(); ++it)
		{
			mmm += (*it)->getName() + "\t";
		}
		//TO( m_connPtr->getName() + " has\n" + mmm);
	}
	if (m_bidirect)
	{
		SDList union_list = m_oper1;
		union_list.insert( union_list.end(), m_oper2.begin(), m_oper2.end());
		m_srcLCD = FCO::lcdIntersect( union_list);

		std::string mmm = "Src/dst lcd: ";
		SDList_Iterator it = m_srcLCD.begin();
		for(; it != m_srcLCD.end(); ++it)
		{
			mmm += (*it)->getName() + "\t";
		}
		//TO( m_connPtr->getName() + " has\n" + mmm);
	}
	return true;
}


bool ConnJoint::createLinkGetters()
{
	//
	// 1st task
	// create methods like InPort::getInConnLinks() ; owned by the ConnEnds
	if ( !m_bidirect)
	{
		if ( FCO::equal( m_oper1, m_oper2))
		{
			SDList_Iterator op1_it = m_oper1.begin();
			for( ; op1_it != m_oper1.end(); ++op1_it)
			{
				if ( (*op1_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates)
					{
						(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionLinksGeneric( *op1_it, m_connPtr));
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionLinksGeneric( *op1_it, m_connPtr));
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinksGeneric( *op1_it, m_connPtr));
					}

					if ( Dumper::m_bGenRegular)
					{
						(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionLinks( *op1_it, m_connPtr));
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionLinks( *op1_it, m_connPtr));
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinks( *op1_it, m_connPtr));
					}
				}
			}
		}
		else // not equal m_oper1 and m_oper2
		{
			SDList_Iterator op1_it = m_oper1.begin(); // oper1s have outgoing conns
			for( ; op1_it != m_oper1.end(); ++op1_it)
			{
				if ( (*op1_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates) 
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionLinksGeneric( *op1_it, m_connPtr));

					if ( Dumper::m_bGenRegular) 
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionLinks( *op1_it, m_connPtr));
				}
			}
			SDList_Iterator op2_it = m_oper2.begin(); // oper2s have incoming conns
			for( ; op2_it != m_oper2.end(); ++op2_it)
			{
				if ( (*op2_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates) 
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionLinksGeneric( *op2_it, m_connPtr));

					if ( Dumper::m_bGenRegular) 
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionLinks( *op2_it, m_connPtr));
				}
			}
		}
	}
	else // if (m_bidirect)
	{
		if ( FCO::equal( m_oper1, m_oper2))
		{
			SDList_Iterator op1_it = m_oper1.begin();
			for( ; op1_it != m_oper1.end(); ++op1_it)
				if ( (*op1_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates) 
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinksGeneric( *op1_it, m_connPtr));

					if ( Dumper::m_bGenRegular) 
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinks( *op1_it, m_connPtr));
				}
		}
		else // though bidirect, different src and dest
		{
			SDList_Iterator op1_it = m_oper1.begin();
			for( ; op1_it != m_oper1.end(); ++op1_it)
				if ( (*op1_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates)
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinksGeneric( *op1_it, m_connPtr));

					if ( Dumper::m_bGenRegular)
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinks( *op1_it, m_connPtr));
				}

			SDList_Iterator op2_it = m_oper2.begin();
			for( ; op2_it != m_oper2.end(); ++op2_it)
				if ( (*op2_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates)
						(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinksGeneric( *op2_it, m_connPtr));

					if ( Dumper::m_bGenRegular)
						(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionLinks( *op2_it, m_connPtr));
				}
		}
	}
	return true;
}


bool ConnJoint::createSrcDstGetters()
{	
	//
	// 2nd task
	// creating methods like Connection::getSrc() ; owned by the connection itself
	// the m_connPtr is to be extended if reached this point
	if ( !m_bidirect)
	{
		SDList_Iterator op1_it = m_oper1.begin();
		for( ; op1_it != m_oper1.end(); ++op1_it)
			m_connPtr->addMethod( CodeGen::dumpGetSrc( *op1_it, m_connPtr, m_oper1IsAnyReferencePort));

		SDList_Iterator op2_it = m_oper2.begin();
		for( ; op2_it != m_oper2.end(); ++op2_it)
			m_connPtr->addMethod( CodeGen::dumpGetDst( *op2_it, m_connPtr, m_oper2IsAnyReferencePort));
	}
	else // bidirect, but has some lcd
	{
		if ( !m_srcLCD.empty())
		{
			std::vector<FCO*>::iterator return_value_it = m_srcLCD.begin();
			for( ; return_value_it != m_srcLCD.end(); ++return_value_it)
			{ // if multiple inheritance is present the for cycle performed more than once
				m_connPtr->addMethod( CodeGen::dumpGetSrc( *return_value_it, m_connPtr, m_oper1IsAnyReferencePort));
				m_connPtr->addMethod( CodeGen::dumpGetDst( *return_value_it, m_connPtr, m_oper2IsAnyReferencePort));
			}
		}
		else // m_srcLCD.empty = true
		{
			m_connPtr->addMethod( CodeGen::dumpGetSrc( 0, m_connPtr, m_oper1IsAnyReferencePort));
			m_connPtr->addMethod( CodeGen::dumpGetDst( 0, m_connPtr, m_oper2IsAnyReferencePort));
		}
	}
	return true;
}


bool ConnJoint::createEndGetters()
{
	//
	// 3rd task
	// create methods like InPort::getInConnEnds() ; owned by the connEnds
	//                     InPort::getParamConnSrcs()
	if ( !m_bidirect)
	{
		// obsolete !m_srcLCD.empty() && !m_dstLCD.empty())
		SDList_Iterator op1_it = m_oper1.begin();
		for( ; op1_it != m_oper1.end(); ++op1_it) // for all src labeled FCOs
		{
			if ( (*op1_it)->isToBeEx())
			{
				if ( !m_dstLCD.empty())
				{
					SDList_Iterator peer_it = m_dstLCD.begin();
					for( ; peer_it != m_dstLCD.end(); ++peer_it) // separate getters for all the peers' lcd
					{
						FCO* peer_ptr = 0;
						if ( (*peer_it)->isToBeEx()) // use peer name only if is to extended
							peer_ptr = *peer_it;
						else if ( (*peer_it)->getExtedAnc()) // if it has an extended ancestor
							peer_ptr = (*peer_it)->getExtedAnc();

						if ( Dumper::m_bGenTemplates)
							(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));

						if ( Dumper::m_bGenRegular)
							(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));
					}
				}
				else // no common denom (lcd) of dst nodes
				{
					if ( Dumper::m_bGenTemplates)
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));

					if ( Dumper::m_bGenRegular)
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
				}
			}
		}

		SDList_Iterator op2_it = m_oper2.begin();
		for( ; op2_it != m_oper2.end(); ++op2_it)
		{
			if ( (*op2_it)->isToBeEx())
			{
				if ( !m_srcLCD.empty())
				{
					std::vector<FCO*>::iterator peer_it = m_srcLCD.begin();
					for( ; peer_it != m_srcLCD.end(); ++peer_it)
					{
						FCO* peer_ptr = 0;
						if ( (*peer_it)->isToBeEx()) // use peer name only if is to extended
							peer_ptr = *peer_it;
						else if ( (*peer_it)->getExtedAnc()) // if it has an extended ancestor
							peer_ptr = (*peer_it)->getExtedAnc();

						if ( Dumper::m_bGenTemplates)
							(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));

						if ( Dumper::m_bGenRegular)
							(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
					}
				}
				else // no common denom (lcd) of src nodes
				{
					if ( Dumper::m_bGenTemplates)
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));

					if ( Dumper::m_bGenRegular)
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
				}
			}
		}
	}
	else if ( m_bidirect) // if bidirect then the srcLCD contains the lcds of m_oper1 and m_oper2 too
	{
		if ( !m_srcLCD.empty()) // this means that the lcd of union(oper1, oper2) is not FCO = the worst
		{
			if ( FCO::equal( m_oper1, m_oper2))
			{ // bidirect connection with same dst and src
				std::vector<FCO*>::iterator it = m_srcLCD.begin();
				for( ; it != m_srcLCD.end(); ++it)
				{
					FCO * peer_ptr = 0;
					if ( (*it)->isToBeEx()) // use peer name only if is to extended
						peer_ptr = *it;
					else if ( (*it)->getExtedAnc()) // if it has an extended ancestor
						peer_ptr = (*it)->getExtedAnc();

					SDList_Iterator op1_it = m_oper1.begin();
					for( ; op1_it != m_oper1.end(); ++op1_it) // though bidirect, some elements are still source
					{
						if ( (*op1_it)->isToBeEx())
						{
							if ( Dumper::m_bGenTemplates)
							{
								(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));

								(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
								(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
							}

							if ( Dumper::m_bGenRegular)
							{
								(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));

								(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
								(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
							}
						}
					}
				}
			}
			else
			{ // bidirect connection, where the src and dst are different
				std::vector<FCO*>::iterator it = m_srcLCD.begin();
				for( ; it != m_srcLCD.end(); ++it)
				{
					FCO * peer_ptr = 0;
					if ( (*it)->isToBeEx()) // use peer name only if is to extended
						peer_ptr = *it;
					else if ( (*it)->getExtedAnc()) // if it has an extended ancestor
						peer_ptr = (*it)->getExtedAnc();

					SDList_Iterator op1_it = m_oper1.begin();
					for( ; op1_it != m_oper1.end(); ++op1_it) // though bidirect, some elements are still source
					{
						if ( (*op1_it)->isToBeEx())
						{
							if ( Dumper::m_bGenTemplates)
							{
								(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));

								(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));
								(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));
							}

							if ( Dumper::m_bGenRegular)
							{
								(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));

								(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));
								(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op1_it, peer_ptr, m_connPtr, m_oper2IsAnyReferencePort));
							}
						}
					}

					SDList_Iterator op2_it = m_oper2.begin();
					for( ; op2_it != m_oper2.end(); ++op2_it) // though bidirect, some elements are still destination
					{
						if ( (*op2_it)->isToBeEx())
						{
							if ( Dumper::m_bGenTemplates)
							{
								(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionEndGeneric( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));

								(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
								(*op2_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
							}

							if ( Dumper::m_bGenRegular)
							{
								(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionEnd( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));

								(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
								(*op2_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op2_it, peer_ptr, m_connPtr, m_oper1IsAnyReferencePort));
							}
						}
					}
				}
			}
		}
		else // if bidirect, but the two ends don't have anything in common lcd = FCO
		{
			SDList_Iterator op1_it = m_oper1.begin();
			for( ; op1_it != m_oper1.end(); ++op1_it)
			{
				if ( (*op1_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates)
					{
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEndGeneric( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
						(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
					}
					
					if ( Dumper::m_bGenRegular)
					{
						(*op1_it)->addConnMethod( CodeGen::dumpGetBothConnectionEnd( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
						(*op1_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
						(*op1_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op1_it, 0, m_connPtr, m_oper2IsAnyReferencePort));
					}
				}
			}

			SDList_Iterator op2_it = m_oper2.begin();
			for( ; op2_it != m_oper2.end(); ++op2_it)
			{
				if ( (*op2_it)->isToBeEx())
				{
					if ( Dumper::m_bGenTemplates)
					{
						(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionEndGeneric( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEndGeneric( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
						(*op2_it)->addConnMethod( CodeGen::dumpGetOutConnectionEndGeneric( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
					}

					if ( Dumper::m_bGenRegular)
					{
						(*op2_it)->addConnMethod( CodeGen::dumpGetBothConnectionEnd( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
						(*op2_it)->addConnMethod( CodeGen::dumpGetInConnectionEnd( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
						(*op2_it)->addConnMethod( CodeGen::dumpGetOutConnectionEnd( *op2_it, 0, m_connPtr, m_oper1IsAnyReferencePort));
					}
				}
			}
		}
	}
	return true;
}


--- NEW FILE: AttributeRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "AttributeRep.h"
#include "FCO.h"
#include "CodeGen.h"

#include "cctype"
#include <algorithm>

#include "globals.h"
#include "Dumper.h"
extern Globals global_vars;
extern int ind;


AttributeRep::AttributeRep( IMgaFCO* ptr)
: Any( ptr) 
{
}


AttributeRep::~AttributeRep()
{
}


bool AttributeRep::isGlobal()
{
	return Util::getBoolAttr( m_ptr, "GlobalScope");
}


bool AttributeRep::isViewable()
{
	return Util::getBoolAttr( m_ptr, "IsViewable");
}


std::string AttributeRep::getPrompt()
{
	return Dumper::xmlFilter( Util::getStrAttr( m_ptr, "Prompt"));
}

std::string AttributeRep::getNameToUse()
{
	std::string p = getName();
	
	Any::convertToValidName(p);
	return p;
}


void AttributeRep::addOwner( FCO * owner)
{
	std::vector<FCO*>::iterator it =
		std::find( m_ownerList.begin(), m_ownerList.end(), owner);

	if ( it == m_ownerList.end()) // not found so insert it
		m_ownerList.push_back( owner);
	else
		global_vars.err << getName() << " attribute owned by " << owner->getName() << " twice\n";
}


int AttributeRep::hasAnyOwner() const
{
	return m_ownerList.size();
}


EnumAttributeRep::EnumAttributeRep( IMgaFCO* ptr)
: AttributeRep( ptr), m_noOfItems(0), m_noOfDefault(0)
{
	m_items.clear();
	m_itemsVal.clear();
}


bool EnumAttributeRep::getMenuItems()
{
/*
this method is capable of parsing enumerations like
elem1, value1
elem2
elem3, value3
, value4			-error case
elem4,				-error case


using special characters like: & < > " ' is not an error any more: are replaced with the xml escape codes
*/

	std::string items = Dumper::xmlFilter( Util::getStrAttr( m_ptr, "MenuItems"));

	items += '\n'; // like an EOF sign
	int len = items.length();

	std::string whitespace = "\r\n\t ";
	int start_i = 0;
	while (start_i < len && whitespace.find(items[start_i]) != std::string::npos )
		++start_i;//skip heading multiple newlines

	int i = start_i, comma_i = 0;
	while( i < len )
	{
		if ( items[i] == '\n' && i - start_i > 0) // pass till end of line
		{ 
			if ( comma_i != 0) // there is value also
			{
				int st,end;
				// from start_i, to comma_i
				st = start_i;
				while( st < comma_i && whitespace.find( items[st]) != std::string::npos) ++st; //leading whsp
				end = comma_i-1;
				while( end > start_i && whitespace.find( items[end]) != std::string::npos) --end; //tailing whsp

				if ( end>=st)
					m_items.push_back(items.substr( st, end - st + 1));
				else
				{
					m_items.push_back("Error");
					global_vars.err << MSG_ERROR << "Error: Enumitem #" << 1 + m_noOfItems << " of " << getPtr() << " has wrong format. (If comma is used a second value is required.)\n";
				}
				
				// from comma_i+1 to i
				st = comma_i+1;
				while( st < i && whitespace.find( items[st]) != std::string::npos) ++st; //leading whsp
				end = i;
				while( end > comma_i+1 && whitespace.find( items[end]) != std::string::npos) --end; //tailing whsp
				
				if ( end>=st && comma_i+1 < i)
					m_itemsVal.push_back(items.substr( st, end - st + 1));
				else
				{
					m_itemsVal.push_back("Error");
					global_vars.err << MSG_ERROR << "Error: Enumitem #" << 1 + m_noOfItems << " of " << getPtr() << " has wrong format. (If comma is used a second value is required.)\n";
				}

				comma_i = 0;
			}
			else // no comma means no value
			{
				int st,end;
				// from start_i to i
				st = start_i;
				while( st < i && whitespace.find( items[st]) != std::string::npos) ++st; //leading whsp
				end = i;
				while( end > start_i && whitespace.find( items[end]) != std::string::npos) --end; //tailing whsp

				if ( end>=st)
				{
					m_items.push_back(items.substr( st, end - st + 1));
					m_itemsVal.push_back(items.substr( st, end - st + 1));
				}
			}
			++m_noOfItems; 
			start_i = i+1;
			while (start_i < len && whitespace.find(items[start_i]) != std::string::npos) ++start_i;//skip multiple newlines, tabs, spaces
			i = start_i-1;
		}
		else if ( items[i] == ',') 
		{ 
			comma_i = i;
		}
		++i;
	}

	if( m_noOfItems == 0)
		global_vars.err << MSG_ERROR << "Error: No enumeration items found. Please check: " << getPtr() << ".\n";

	bool filled_def_item = Util::isAttrStatHere( m_ptr, "DefaultItem");
	std::string def_item = Dumper::xmlFilter( Util::getStrAttr( m_ptr, "DefaultItem"));

	bool found ( false);
	i = 0;
	while (i < m_noOfItems && !found)
	{
		if ( m_items[i] == def_item ) found = true;
		else ++i;
	}

	if (found)
		m_noOfDefault = i;
	else if( filled_def_item)
		global_vars.err << MSG_ERROR << "Error: Default enumitem not found among enumerated items at " << getPtr() << ".\n";

	return true;
}


// obsolete -> really? question asked on 2/2/2004
/*static*/ std::string EnumAttributeRep::enumTypeName( EnumAttributeRep * a)
{
	std::string type = a->getNameToUse();
	type += "_Type";
	return type;
}


/*virtual*/ std::string EnumAttributeRep::getMethodName()
{
	return "get" + getNameToUse();
}


/*virtual*/ std::string EnumAttributeRep::getSetMethodName()
{
	return "set" + getNameToUse();
}


Method EnumAttributeRep::createMethodForAttr( FCO * container)
{
	Method m2;
	if (m_noOfItems == 0) getMenuItems();
	if (m_noOfItems == 0) return m2;//throw("Enumtype is empty");

	std::string mmm = "";
	mmm = CodeGen::indent(1) + "typedef enum\n" + CodeGen::indent(1) + "{";
	for(int i = 0; i < m_noOfItems; ++i)
	{
		std::string item_i = m_itemsVal[i] + '_' + EnumAttributeRep::enumTypeName( this);
		if ( !Any::checkIfValidName( item_i))
		{
			global_vars.err << "Invalid enumeration value \"" << item_i << "\" defined in " << EnumAttributeRep::enumTypeName( this) << ". Non alphanumeric characters replaced with underscore.\n";
			Any::convertToValidName( item_i);
		}

		if ( i != 0) mmm += ",";
		mmm += "\n" + CodeGen::indent(2) + item_i;
	}
	mmm += "\n" + CodeGen::indent(1) + "} " + EnumAttributeRep::enumTypeName( this) + ";\n";

	container->addClassGlobal( mmm);

	std::string src;

	src = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) + "std::string val = FCOImpl::getAttribute(\"" + getName() + "\")->getStringValue();\n";
	for( i = 0; i < m_noOfItems; ++i)
	{
		std::string item_i = m_itemsVal[i] + '_' + EnumAttributeRep::enumTypeName( this);
		if ( !Any::checkIfValidName( item_i))
			Any::convertToValidName( item_i);

		src += "\n" + CodeGen::indent(1);
		if ( i != 0) src += "else ";
		src += "if ( val == \"" + m_itemsVal[i] + "\") return " + item_i + ";";
	}
	src += "\n" + CodeGen::indent(1) + "else throw(\"None of the possible items\");\n}\n\n\n";

	m2.m_returnValue = container->getLValidNameImpl() + "::" + EnumAttributeRep::enumTypeName( this);
	m2.m_signature = getMethodName() + "()";
	m2.m_container = container;
	m2.m_implementation = src;
	m2.m_comment = "";

	return m2;
}


Method EnumAttributeRep::createSetMethodForAttr( FCO * container)
{
	// we presume that the getter generator is called before this setter generator
	// for getMenuItems() 's sake
	Method m2;
	if (m_noOfItems == 0) return m2;//throw("Enumtype is empty");

	std::string src;

	src  = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) + "std::string str_val = \"\";\n\n";

	for( int i = 0; i < m_noOfItems; ++i)
	{
		std::string item_i = m_itemsVal[i] + '_' + EnumAttributeRep::enumTypeName( this);
		if ( !Any::checkIfValidName( item_i))
			Any::convertToValidName( item_i);

		src += CodeGen::indent(1);
		if ( i != 0) src += "else ";
		src += "if ( val == " + item_i + ") str_val = \"" + m_itemsVal[i] + "\";\n";
	}
	src += CodeGen::indent(1) + "else throw(\"None of the possible items\");\n";
	src += "\n";
	src += CodeGen::indent(1) + "FCOImpl::getAttribute(\"" + getName() + "\")->setStringValue( str_val);\n";
	src += "}\n\n\n";

	m2.m_returnValue = "void";
	m2.m_signature = getSetMethodName() + "( " + container->getValidNameImpl() + "::" + EnumAttributeRep::enumTypeName( this) + " val)";
	m2.m_container = container;
	m2.m_implementation = src;
	m2.m_comment = "";

	return m2;
}


/*virtual*/ std::string EnumAttributeRep::doDumpErroneousAttrHdr()
{
	std::string hdr;
	hdr = CodeGen::indent(1) + "/*virtual*/ inline std::string " + getMethodName() + "() ";
	hdr += "{ ";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += " }\n";

	// the signature has to match the parent's getter's in order to override it
	hdr += "\n";
	//hdr += CodeGen::indent(1) + "/*virtual*/ inline void " + getSetMethodName() + "(" + container->getValidNameImpl() + "::" + EnumAttributeRep::enumTypeName( this) + " val)";
	// but the container ptr is not available here, we presume that the current object has the enum values
	// inherited in its own scope
	hdr += CodeGen::indent(1) + "/*virtual*/ inline void " + getSetMethodName() + "(" + EnumAttributeRep::enumTypeName( this) + " val)";
	hdr += "{ ";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += " }\n";

	return hdr;
}


/*virtual*/ std::string EnumAttributeRep::doDumpErroneousAttrSrc( FCO*)
{
	return "";
}


/*virtual*/ std::string BoolAttributeRep::getMethodName()
{
	return "is" + getNameToUse();
}


/*virtual*/ std::string BoolAttributeRep::getSetMethodName()
{
	return "set" + getNameToUse();
}


Method BoolAttributeRep::createMethodForAttr( FCO * container)
{
	Method m;
	std::string src;
	src  = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) +   "return FCOImpl::getAttribute(\"" + getName() + "\")->getBooleanValue();\n";
	src += CodeGen::indent(0) + "}\n\n\n";

	m.m_returnValue = "bool";
	m.m_signature = getMethodName() + "() ";
	m.m_implementation = src;
	m.m_container = container;
	m.m_comment = "";
	return m;
}


Method BoolAttributeRep::createSetMethodForAttr( FCO * container)
{
	Method m;
	std::string src;
	src  = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) +   "FCOImpl::getAttribute(\"" + getName() + "\")->setBooleanValue( val);\n";
	src += CodeGen::indent(0) + "}\n\n\n";

	m.m_returnValue = "void";
	m.m_signature = getSetMethodName() + "( bool val)";
	m.m_implementation = src;
	m.m_container = container;
	m.m_comment = "";
	return m;
}


/*virtual*/ std::string BoolAttributeRep::doDumpErroneousAttrHdr()
{
	std::string hdr;
	hdr  = CodeGen::indent(1) + "/*virtual*/ inline bool " + getMethodName() + "() ";
	hdr += "{";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += "}\n";

	// the signature has to match the parent's getter's in order to override it
	hdr += "\n";
	hdr += CodeGen::indent(1) + "/*virtual*/ inline void " + getSetMethodName() + "( bool) ";
	hdr += "{";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += "}\n";


	return hdr;
}


/*virtual*/ std::string BoolAttributeRep::doDumpErroneousAttrSrc( FCO*)
{
	return "";
}


/*virtual*/ std::string FieldAttributeRep::getMethodName()
{
	return "get" + getNameToUse();
}


/*virtual*/ std::string FieldAttributeRep::getSetMethodName()
{
	return "set" + getNameToUse();
}


std::string FieldAttributeRep::getTypeStr()
{
	std::string val_type = Util::getStrAttr( m_ptr, "DataType");
	if ( val_type == "integer")
		return "long";
	else if ( val_type == "double")
		return "double";
	else if ( val_type == "string")
		return "std::string";

	return "Error";
}


std::string FieldAttributeRep::getSetTypeStr()
{
	std::string val_type = Util::getStrAttr( m_ptr, "DataType");
	if ( val_type == "integer")
		return "const long";
	else if ( val_type == "double")
		return "const double";
	else if ( val_type == "string")
		return "const std::string&";

	return "Error";
}


std::string FieldAttributeRep::getMethodStr()
{
	std::string val_type = Util::getStrAttr( m_ptr, "DataType");
	if ( val_type == "integer")
		return "Integer";
	else if ( val_type == "double")
		return "Real";
	else if ( val_type == "string")
		return "String";

	return "Error";
}


Method FieldAttributeRep::createMethodForAttr( FCO * container)
{
	Method m;
	std::string src;
	src  = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) +   "return FCOImpl::getAttribute(\"" + getName() + "\")->get" + getMethodStr() + "Value();\n";
	src += CodeGen::indent(0) + "}\n\n\n";

	m.m_returnValue = getTypeStr();
	m.m_signature = getMethodName() + "() ";
	m.m_implementation = src;
	m.m_container = container;
	m.m_comment = "";

	return m;
}


Method FieldAttributeRep::createSetMethodForAttr( FCO * container)
{
	Method m;
	std::string src;
	src  = CodeGen::indent(0) + "{\n";
	src += CodeGen::indent(1) +   "FCOImpl::getAttribute(\"" + getName() + "\")->set" + getMethodStr() + "Value( val);\n";
	src += CodeGen::indent(0) + "}\n\n\n";

	m.m_returnValue = "void";
	m.m_signature = getSetMethodName() + "( " + getSetTypeStr() + " val)";
	m.m_implementation = src;
	m.m_container = container;
	m.m_comment = "";

	return m;
}


/*virtual*/ std::string FieldAttributeRep::doDumpErroneousAttrHdr()
{
	std::string hdr;
	hdr  = CodeGen::indent(1) + "/*virtual*/ inline " + getTypeStr() + " " + getMethodName() + "() ";
	hdr += "{";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += "}\n";

	// the signature has to match the parent's getter's in order to override it
	hdr += "\n";
	hdr += CodeGen::indent(1) + "/*virtual*/ inline void " + getSetMethodName() + "( " + getSetTypeStr() + ") ";
	hdr += "{";
	hdr += "throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + getNameToUse() + " attribute\");";
	hdr += "}\n";

	return hdr;
}


/*virtual*/ std::string FieldAttributeRep::doDumpErroneousAttrSrc( FCO*)
{
	return "";
}
--- NEW FILE: CodeGenReg.cpp ---
#include "stdafx.h"
#include "CodeGen.h"
#include "Dumper.h"

/*const*/ extern int s_ind;


/*static*/ void CodeGen::folderGetter( const std::string& retval_folderkind, const std::string& folderkind, const std::string& method_name, bool extended, Any * cont, Method& m)
{
	std::string src, comm;
	
	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_folderkind + "> res;\n";
	src += indent(s_ind + 1) +   "std::set<BON::Folder> l = FolderImpl::getChildFolders();\n";
	src += indent(s_ind + 1) +   "for( std::set<BON::Folder>::iterator i = l.begin(); i != l.end(); ++i)\n";
	src += indent(s_ind + 1) +   "{\n";
	src += indent(s_ind + 2) +     retval_folderkind + " elem(*i);\n";
	if ( extended)
		src += indent(s_ind + 2) +   "if (elem)\n";
	else
		src += indent(s_ind + 2) +   "if (elem && elem->getObjectMeta().name() == \"" + folderkind + "\")\n";
	src += indent(s_ind + 3) +       "res.insert(elem);\n";
	src += indent(s_ind + 1) +   "}\n";
	src += indent(s_ind + 1) +   "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";

	comm = "getter for subfolder \"" + folderkind + "\"";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_folderkind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ void CodeGen::kindGetter1( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m)
{
	std::string src, comm;
	
	comm = "getter for kind \"" + kind + "\"";
	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "std::set<BON::Object> kinds = FolderImpl::getChildObjects";
	src +=               "(\"" + kind + "\");\n";
	src += indent(s_ind + 1) +   "for( std::set<BON::Object>::iterator i = kinds.begin(); i != kinds.end(); ++i)\n";
	src += indent(s_ind + 1) +   "{\n";
	src += indent(s_ind + 2) +     retval_kind + " elem(*i);\n";
	src += indent(s_ind + 2) +     "ASSERT(elem);\n";
	src += indent(s_ind + 2) +     "res.insert(elem);\n";
	src += indent(s_ind + 1) +   "}\n";
	src += indent(s_ind + 1) +   "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ void CodeGen::kindGetter2( const std::string& retval_kind, const std::string& kind, const std::vector< std::string>& kind_vec, const std::string& method_name, Any * cont, Method& m)
{
	std::string src, comm;

	// the number of non-abstract fcos
	char len_s[10]; sprintf(len_s, "%u", kind_vec.size()); std::string len_str( len_s);
	
	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "const int len = " + len_str + ";\n";
	src += indent(s_ind + 1) +   "std::set<BON::Object> kinds_vec[ len];\n";
	
	for( int k = 0; k < kind_vec.size(); ++k)
	{
		char k_s[10]; sprintf( k_s, "%i", k); std::string k_str( k_s);
		src += indent(s_ind + 1) + "kinds_vec[" + k_str + "] = FolderImpl::getChildObjects";
		src += "(\"" + kind_vec[k] + "\");\n";
	}
	src += indent(s_ind + 1) + "for( int k = 0; k < len; ++k)\n";
	src += indent(s_ind + 2) +   "for( std::set<BON::Object>::iterator i = kinds_vec[k].begin(); i != kinds_vec[k].end(); ++i)\n";
	src += indent(s_ind + 2) +   "{\n";
	src += indent(s_ind + 3) +     retval_kind + " elem(*i);\n";
	src += indent(s_ind + 3) +     "ASSERT(elem);\n";
	src += indent(s_ind + 3) +     "res.insert(elem);\n";
	src += indent(s_ind + 2) +   "}\n";
	src += indent(s_ind + 1) + "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";	

	comm = "aggregated getter for kind \"" + kind + "\" and its descendants";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;
}


/*static*/ void CodeGen::kindGetter3( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m)
{
	// currently not used
	std::string src, comm;

	comm = "EXCL getter for kind \"" + kind + "\"";

	src  = "{\n";
	src += "  std::set<" + retval_kind + "> res;\n";
	src += "  std::set<Object> l = FolderImpl::getChildObjects";
	src += "(\"" + kind + "\");\n";
	src += "  for( std::set<Object>::iterator i = l.begin(); i != l.end(); ++i)\n";
	src += "  {\n";
	src += "     " + retval_kind + " elem(*i);\n";
	src += "     ASSERT(elem);\n";
	src += "     res.insert(elem);\n";
	src += "  }\n";
	src += "  return res;\n";
	src += "}\n\n\n";	

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "_Excl()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;
}

/*static*/ void CodeGen::roleGetter1( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m)
{
	std::string src, comm;

	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs";
	src +=                       "(\"" + inquire + "\");\n";
	src += indent(s_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(s_ind + 1) +   "{\n";
	src += indent(s_ind + 2) +       retval_kind + " elem(*i);\n";
	src += indent(s_ind + 2) +      "ASSERT(elem);\n";
	src += indent(s_ind + 2) +      "res.insert(elem);\n";
	src += indent(s_ind + 1) +   "}\n";
	src += indent(s_ind + 1) +   "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";

	comm =  "getter for role \"" + inquire + "\" among \"" + fco_name + "\"s";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ void CodeGen::roleGetter2( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& m)
{
	std::string src, comm;

	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs";
	src +=                       "(\"" + inquire + "\");\n";
	src += indent(s_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(s_ind + 1) +   "{\n";
	src += indent(s_ind + 2) +      retval_kind + " elem(*i);\n";
	src += indent(s_ind + 2) +      "ASSERT(elem);\n";
	src += indent(s_ind + 2) +      "res.insert(elem);\n";
	src += indent(s_ind + 1) +   "}\n";
	src += indent(s_ind + 1) +   "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";

	comm = "getter for role \"" + inquire + "\" among \"" + fco_name + "\"s";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ void CodeGen::roleGetter3( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& role_name, const std::vector< std::string > & roles, const std::string& dummy_str, Any * cont, Method& m)
{
	std::string src, comm;

	char len_s[10]; sprintf(len_s, "%u", roles.size()); std::string len_str( len_s);

	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "const int len = " + len_str + ";\n";
	src += indent(s_ind + 1) +   "std::set<BON::FCO> roles_vec[ len];\n";
	
	for( int k = 0; k < roles.size(); ++k)
	{
		char k_s[10]; sprintf( k_s, "%i", k); std::string k_str( k_s);
		src += indent(s_ind + 1) + "roles_vec[" + k_str + "] = ModelImpl::getChildFCOsAs";
		src += "(\"";
		src += roles[k];
		src += "\");\n";
	}

	src += indent(s_ind + 1) + "for( int k = 0; k < len; ++k)\n";
	src += indent(s_ind + 2) +   "for( std::set<BON::FCO>::iterator i = roles_vec[k].begin(); i != roles_vec[k].end(); ++i)\n";
	src += indent(s_ind + 2) +   "{\n";
	src += indent(s_ind + 3) +      retval_kind + " elem(*i);\n";
	src += indent(s_ind + 3) +      "ASSERT(elem);\n";
	src += indent(s_ind + 3) +      "res.insert(elem);\n";
	src += indent(s_ind + 2) +   "}\n";
	src += indent(s_ind + 1) + "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";	

	comm = "aggregated getter for role \"" + role_name + "\" among \"" + fco_name + "\"s and its descendants";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">"; 
	m.m_signature = method_name + "(" + dummy_str + ")";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ void CodeGen::roleGetter4( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& desc_k_name, const std::string& role_name, const std::string& nmsp, Any * cont, Method& m)
{
	std::string src, comm;

	src  = indent(s_ind + 0) + "{\n";
	src += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	src += indent(s_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs";
	src +=                       "(\"";
	src +=                              nmsp + desc_k_name + role_name;
	src +=                       "\");\n";
	src += indent(s_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(s_ind + 1) +   "{\n";
	src += indent(s_ind + 2) +     retval_kind + " elem(*i);\n";
	src += indent(s_ind + 2) +     "ASSERT(elem);\n";
	src += indent(s_ind + 2) +     "res.insert(elem);\n";
	src += indent(s_ind + 1) +   "}\n";
	src += indent(s_ind + 1) +   "return res;\n";
	src += indent(s_ind + 0) + "}\n\n\n";

	comm = "getter for role \"" + nmsp + desc_k_name + role_name + "\" among \"" + nmsp + fco_name + "\"s and its descendants";

	m.m_virtual = true;
	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = method_name + "()";
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = comm;

	return;
}


/*static*/ Method CodeGen::dumpGetInConnectionLinks( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string mmm;

	mmm  = indent(s_ind + 0) + "{\n";
	mmm += indent(s_ind + 1) +   "std::set<" + conn->getLValidName() + "> result;\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getInConnLinks();\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	mmm += indent(s_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	mmm += indent(s_ind + 1) +   "{\n";
	mmm += indent(s_ind + 2) +     conn->getLValidName() + " c( *it);\n";
	mmm += indent(s_ind + 2) +     "if (c)\n";
	mmm += indent(s_ind + 3) +       "result.insert( c);\n";
	mmm += indent(s_ind + 1) +   "}\n";
	mmm += indent(s_ind + 1) +   "return result;\n";
	mmm += indent(s_ind + 0) + "}\n\n\n";

	m.m_signature = "getIn" + conn->getValidName() + "Links()";
	m.m_returnValue = "std::set<" + conn->getLValidName() + ">";
	m.m_implementation = mmm;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}



/*static*/ Method CodeGen::dumpGetOutConnectionLinks( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string mmm;

	mmm  = indent(s_ind + 0) + "{\n";
	mmm += indent(s_ind + 1) +   "std::set<" + conn->getLValidName() + "> result;\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getOutConnLinks();\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	mmm += indent(s_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	mmm += indent(s_ind + 1) +   "{\n";
	mmm += indent(s_ind + 2) +      conn->getLValidName() + " c( *it);\n";
	mmm += indent(s_ind + 2) +      "if (c)\n";
	mmm += indent(s_ind + 3) +        "result.insert( c);\n";
	mmm += indent(s_ind + 1) +   "}\n";
	mmm += indent(s_ind + 1) +   "return result;\n";
	mmm += indent(s_ind + 0) + "}\n\n\n";

	m.m_signature = "getOut" + conn->getValidName() + "Links()";
	m.m_returnValue = "std::set<" + conn->getLValidName() + ">";
	m.m_implementation = mmm;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}



/*static*/ Method CodeGen::dumpGetBothConnectionLinks( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string mmm;

	mmm  = indent(s_ind + 0) + "{\n";
	mmm += indent(s_ind + 1) +   "std::set<" + conn->getLValidName() + "> result;\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getConnLinks();\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	mmm += indent(s_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	mmm += indent(s_ind + 1) +   "{\n";
	mmm += indent(s_ind + 2) +     conn->getLValidName() + " c( *it);\n";
	mmm += indent(s_ind + 2) +     "if (c)\n";
	mmm += indent(s_ind + 3) +       "result.insert( c);\n";
	mmm += indent(s_ind + 1) +   "}\n";
	mmm += indent(s_ind + 1) +   "return result;\n";
	mmm += indent(s_ind + 0) + "}\n\n\n";

	m.m_signature = "get" + conn->getValidName() + "Links()";
	m.m_returnValue = "std::set<" + conn->getLValidName() + ">";
	m.m_implementation = mmm;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}


/*static*/ Method CodeGen::dumpGetInConnectionEnd( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string mmm, nnn;

	if ( peer_may_be_refport)
	{
		// if reference ports may be conn ends than the implementation is so simple
		nnn  = indent(s_ind + 0) + "{\n";
		nnn += indent(s_ind + 1) +   "return BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		nnn += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "get" + conn->getValidName() + "Srcs()";
		m.m_returnValue = "std::multiset<BON::ConnectionEnd>";
		m.m_implementation = nnn;
		m.m_container = fco;
		m.m_comment = "returns src " + peer_lcd + "s and referenceports";
	}
	else
	{
		// if we know that no reference ports are between the connends
		mmm  = indent(s_ind + 0) + "{\n";
		mmm += indent(s_ind + 1) +   "std::multiset<" + peer_lcd + "> res;\n";
		mmm += indent(s_ind + 1) +   "{\n";
		// the name getInConnEnds is confusing but does the right thing
		mmm += indent(s_ind + 2) +     "std::multiset<BON::ConnectionEnd> in_ends = BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		mmm += indent(s_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = in_ends.begin() ; cit != in_ends.end() ; ++cit )\n";
		mmm += indent(s_ind + 2) +     "{\n";
		mmm += indent(s_ind + 3) +       peer_lcd + " dst( *cit );\n";
		mmm += indent(s_ind + 3) +       "ASSERT(dst);\n";
		mmm += indent(s_ind + 3) +       "res.insert( dst);\n";
		mmm += indent(s_ind + 2) +     "}\n";
		mmm += indent(s_ind + 1) +   "}\n";
		mmm += indent(s_ind + 1) +   "return res;\n";
		mmm += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "get" + conn->getValidName() + "Srcs()";
		m.m_returnValue = "std::multiset<" + peer_lcd + ">";
		m.m_implementation = mmm;
		m.m_container = fco;
		m.m_comment = "returns src " + peer_lcd + "s";
	}
	return m;
}



/*static*/ Method CodeGen::dumpGetOutConnectionEnd( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string mmm, nnn;

	if ( peer_may_be_refport)
	{
		nnn  = indent(s_ind + 0) + "{\n";
		nnn += indent(s_ind + 1) +   "return BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		nnn += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "get" + conn->getValidName() + "Dsts()";
		m.m_returnValue = "std::multiset<BON::ConnectionEnd>";
		m.m_implementation = nnn;
		m.m_container = fco;
		m.m_comment = "returns dst " + peer_lcd + "s and referenceports";
	}
	else
	{
		mmm  = indent(s_ind + 0) + "{\n";
		mmm += indent(s_ind + 1) +   "std::multiset<" + peer_lcd + "> res;\n";
		mmm += indent(s_ind + 1) +   "{\n";
		mmm += indent(s_ind + 2) +     "std::multiset<BON::ConnectionEnd> out_ends = BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		mmm += indent(s_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = out_ends.begin() ; cit != out_ends.end() ; ++cit )\n";
		mmm += indent(s_ind + 2) +     "{\n";
		mmm += indent(s_ind + 3) +       peer_lcd + " dst( *cit );\n";
		mmm += indent(s_ind + 3) +       "ASSERT(dst);\n";
		mmm += indent(s_ind + 3) +       "res.insert( dst);\n";
		mmm += indent(s_ind + 2) +     "}\n";
		mmm += indent(s_ind + 1) +   "}\n";
		mmm += indent(s_ind + 1) +   "return res;\n";
		mmm += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "get" + conn->getValidName() + "Dsts()";
		m.m_returnValue = "std::multiset<" + peer_lcd + ">";
		m.m_implementation = mmm;
		m.m_container = fco;
		m.m_comment = "returns dst " + peer_lcd + "s";
	}

	return m;
}


/*static*/ Method CodeGen::dumpGetBothConnectionEnd( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string mmm, nnn;

	if ( peer_may_be_refport)
	{
		nnn  = indent(s_ind + 0) + "{\n";
		nnn += indent(s_ind + 1) +  "return BON::ConnectionEndImpl::getConnEnds(\"" + conn->getLStrictName() + "\");\n";
		nnn += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "get" + conn->getValidName() + "Ends()";
		m.m_returnValue = "std::multiset<BON::ConnectionEnd>";
		m.m_implementation = nnn;
		m.m_container = fco;
		m.m_comment = "returns src and dst " + peer_lcd + "s and referenceports";
	}
	else
	{
		mmm += indent(s_ind + 0) + "{\n";
		mmm += indent(s_ind + 1) +   "std::multiset<" + peer_lcd + "> res;\n";
		mmm += indent(s_ind + 1) +   "{\n";
		mmm += indent(s_ind + 2) +     "std::multiset<BON::ConnectionEnd> in_ends = BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		mmm += indent(s_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = in_ends.begin() ; cit != in_ends.end() ; ++cit )\n";
		mmm += indent(s_ind + 2) +     "{\n";
		mmm += indent(s_ind + 3) +       peer_lcd + " dst( *cit );\n";
		mmm += indent(s_ind + 3) +       "ASSERT(dst);\n";
		mmm += indent(s_ind + 3) +       "res.insert( dst);\n";
		mmm += indent(s_ind + 2) +     "}\n";
		mmm += indent(s_ind + 2) +     "std::multiset<BON::ConnectionEnd> out_ends = BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		mmm += indent(s_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cot = out_ends.begin() ; cot != out_ends.end() ; ++cot )\n";
		mmm += indent(s_ind + 2) +     "{\n";
		mmm += indent(s_ind + 3) +       peer_lcd + " dst( *cot );\n";
		mmm += indent(s_ind + 3) +       "ASSERT(dst);\n";
		mmm += indent(s_ind + 3) +       "res.insert( dst);\n";
		mmm += indent(s_ind + 2) +     "}\n";
		mmm += indent(s_ind + 1) +   "}\n";
		mmm += indent(s_ind + 1) +   "return res;\n";
		mmm += indent(s_ind + 0) + "}\n\n";

		m.m_signature = "get" + conn->getValidName() + "Ends()";
		m.m_returnValue = "std::multiset<" + peer_lcd + ">";
		m.m_implementation = mmm;
		m.m_container = fco;
		m.m_comment = "returns src and dst " + peer_lcd + "s";
	}
	return m;
}


/*static*/ Method CodeGen::dumpGetSrc( FCO *fco, ConnectionRep * conn, bool fco_may_be_refport)
{
	Method m;
	std::string oper1_lcd;
	if (fco && fco->isToBeEx())
		oper1_lcd = fco->getLValidName();
	else if ( fco && fco->getExtedAnc())
		oper1_lcd = fco->getExtedAnc()->getLValidName();
	else
		oper1_lcd = "BON::FCO";

	std::string mmm, nnn;

	if ( fco_may_be_refport)
	{
		nnn  = indent(s_ind + 0) + "{\n";
		nnn += indent(s_ind + 1) +   "return ConnectionImpl::getSrc();\n"; // otherwise recursive call resulted
		nnn += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "getSrc()";
		m.m_returnValue = "BON::ConnectionEnd";
		m.m_implementation = nnn;
		m.m_container = conn;
		m.m_comment = "getSrc() return value is a ConnectionEnd";
	}
	else
	{
		mmm  = indent(s_ind + 0) + "{\n";
		mmm += indent(s_ind + 1) +   "BON::ConnectionEnd ce = ConnectionImpl::getSrc();\n"; // otherwise recursive call resulted
		mmm += indent(s_ind + 1) +   oper1_lcd + " sp( ce);\n";
		mmm += indent(s_ind + 1) +   "if ( sp)\n";
		mmm += indent(s_ind + 2) +     "return sp;\n";
		mmm += indent(s_ind + 0) + "\n";
		mmm += indent(s_ind + 1) +   oper1_lcd + " empty;\n";
		mmm += indent(s_ind + 1) +   "return empty;\n";
		mmm += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "getSrc()";
		m.m_returnValue = oper1_lcd;
		m.m_implementation = mmm;
		m.m_container = conn;
		m.m_comment = "getSrc() return value is a ConnectionEnd casted to " + oper1_lcd;
	}
	return m;
}


/*static*/ Method CodeGen::dumpGetDst( FCO *fco, ConnectionRep * conn, bool fco_may_be_refport)
{
	Method m;
	std::string oper2_lcd;
	if (fco && fco->isToBeEx())
		oper2_lcd = fco->getLValidName();
	else if ( fco && fco->getExtedAnc())
		oper2_lcd = fco->getExtedAnc()->getLValidName();
	else
		oper2_lcd = "BON::FCO";

	std::string mmm, nnn;

	if ( fco_may_be_refport)
	{
		nnn  = indent(s_ind + 0) + "{\n";
		nnn += indent(s_ind + 1) +   "return ConnectionImpl::getDst();\n"; // otherwise recursive call would result
		nnn += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "getDst()";
		m.m_returnValue = "BON::ConnectionEnd";
		m.m_implementation = nnn;
		m.m_container = conn;
		m.m_comment = "getDst() return value is a ConnectionEnd";
	}
	else
	{
		mmm  = indent(s_ind + 0) + "{\n";
		mmm += indent(s_ind + 1) +   "BON::ConnectionEnd ce = ConnectionImpl::getDst();\n";
		mmm += indent(s_ind + 1) +   oper2_lcd + " sp( ce);\n";
		mmm += indent(s_ind + 1) +   "if ( sp)\n";
		mmm += indent(s_ind + 2) +     "return sp;\n";
		mmm += indent(s_ind + 0) + "\n";
		mmm += indent(s_ind + 1) +   oper2_lcd + " empty;\n";
		mmm += indent(s_ind + 1) +   "return empty;\n";
		mmm += indent(s_ind + 0) + "}\n\n\n";

		m.m_signature = "getDst()";
		m.m_returnValue = oper2_lcd;
		m.m_implementation = mmm;
		m.m_container = conn;
		m.m_comment = "getDst() return value is a ConnectionEnd casted to " + oper2_lcd;
	}
	return m;
}


/*static*/ Method CodeGen::dumpSetGetter( SetRep * cont, const FCO * fco, const std::string& common_kind, bool aggreg /*=false*/, bool dummy_par /*=false*/)
{
	ASSERT( fco || ( aggreg && !common_kind.empty())); //assert if fco is 0 and aggreg is false
	std::string retval_kind; // the return value cannot be "Compound" if Compound is not extended

	if (fco)
	{
		retval_kind = fco->getLValidName();

		if ( !fco->isToBeEx()) 
		{
			FCO * ext_anc = fco->getExtedAnc();
			if ( ext_anc)
				retval_kind = ext_anc->getLValidName();
			else
				retval_kind = "BON::" + Any::KIND_TYPE_STR[fco->getMyKind()];
		}
	}
	else if ( !common_kind.empty()) // using the common_kind if set
		retval_kind = common_kind;
	else // not intended for usage in such cases
		ASSERT(0);

	Method m;

	std::string mmm;
	mmm  = indent(s_ind + 0) + "{\n";
	mmm += indent(s_ind + 1) +   "std::set<" + retval_kind + "> res;\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::FCO> elems = BON::SetImpl::getMembers();\n";
	mmm += indent(s_ind + 1) +   "std::set<BON::FCO>::iterator elem = elems.begin();\n";
	mmm += indent(s_ind + 1) +   "for( ; elem != elems.end(); ++elem)\n";
	mmm += indent(s_ind + 1) +   "{\n";
	mmm += indent(s_ind + 2) +     retval_kind + " r( *elem);\n";

	if ( fco)
	{
		if ( !aggreg) // not aggregated getter
		{
			mmm += indent(s_ind + 2) +   "if ( r && r->getObjectMeta().name() == \"" + fco->getLStrictName() + "\")\n";
		}
		else // aggregated getter, casting to the common base, which is not a common kind
		{
			mmm += indent(s_ind + 2) + "if ( r)\n";
		}
	}
	else // aggregated getter casting to the common kind
		mmm += indent(s_ind + 2) +   "if ( r)\n";

	mmm += indent(s_ind + 3) +       "res.insert( r);\n";
	mmm += indent(s_ind + 1) +   "}\n";
	mmm += indent(s_ind + 1) +   "return res;\n";
	mmm += indent(s_ind + 0) + "}\n\n\n";

	m.m_returnValue = "std::set<" + retval_kind + ">";
	m.m_signature = cont->setGetterTemplate( fco) + "(" + (dummy_par?" int dummy":"") + ")";
	m.m_implementation = mmm;
	m.m_container = cont;
	if ( !aggreg)
		m.m_comment = "specialized getter for " + fco->getLValidName() + " setmembers";
	else //aggreg
		m.m_comment = "aggregated getter for setmembers";

	return m;
}




--- NEW FILE: CodeGenTemplate.cpp ---
#include "stdafx.h"
#include "CodeGen.h"
#include "Dumper.h"

/*const*/ extern int h_ind;

/*static*/ void CodeGen::folderGetterGeneric( const std::string& retval_folderkind, const std::string& folderkind, const std::string& method_name, bool extended, Any * cont, Method& m)
{
	std::string src, rtv, sgn;
	
	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_folderkind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_folderkind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::Folder> l = FolderImpl::getChildFolders();\n";
	src += indent(h_ind + 1) +   "for( std::set<BON::Folder>::iterator i = l.begin(); i != l.end(); ++i)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +     retval_folderkind + " elem(*i);\n";

	if ( extended)
		src += indent(h_ind + 2) +   "if (elem)\n";
	else
		src += indent(h_ind + 2) +   "if (elem && elem->getObjectMeta().name() == \"" + folderkind + "\")\n";

	src += indent(h_ind + 3) +       "res.insert(elem);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_container = cont;
	m.m_template = true;
	m.m_virtual = false;
	m.m_returnValue = rtv;
	m.m_signature = sgn;
	m.m_implementation = src;
	m.m_comment = "getter for subfolder \"" + folderkind + "\"";

	return;
}


/*static*/ void CodeGen::kindGetter1Generic( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m)
{
	std::string src, rtv, sgn;;
	
	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::Object> kinds = FolderImpl::getChildObjects(\"" + kind + "\");\n";
	src += indent(h_ind + 1) +   "for( std::set<BON::Object>::iterator i = kinds.begin(); i != kinds.end(); ++i)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +     retval_kind + " elem(*i);\n";
	src += indent(h_ind + 2) +     "ASSERT(elem);\n";
	src += indent(h_ind + 2) +     "res.insert(elem);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_template = true;
	m.m_virtual = false;
	m.m_returnValue = rtv;
	m.m_signature = sgn;
	m.m_implementation = src;
	m.m_comment = "getter for kind \"" + kind + "\"";
	m.m_container = cont;

	return;
}


/*static*/ void CodeGen::kindGetter2Generic( const std::string& retval_kind, const std::string& kind, const std::vector< std::string>& kind_vec, const std::string& method_name, Any * cont, Method& m)
{
	std::string src, rtv, sgn;;

	// the number of non-abstract fcos
	char len_s[10]; sprintf(len_s, "%u", kind_vec.size()); std::string len_str( len_s);
	
	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "const int len = " + len_str + ";\n";
	src += indent(h_ind + 1) +   "std::set<BON::Object> kinds_vec[ len];\n";
	
	for( int k = 0; k < kind_vec.size(); ++k)
	{
		char k_s[10]; sprintf( k_s, "%i", k); std::string k_str( k_s);
		src += indent(h_ind + 1) + "kinds_vec[" + k_str + "] = FolderImpl::getChildObjects";
		src += "(\"" + kind_vec[k] + "\");\n";
	}
	src += indent(h_ind + 1) + "for( int k = 0; k < len; ++k)\n";
	src += indent(h_ind + 2) +   "for( std::set<BON::Object>::iterator i = kinds_vec[k].begin(); i != kinds_vec[k].end(); ++i)\n";
	src += indent(h_ind + 2) +   "{\n";
	src += indent(h_ind + 3) +     retval_kind + " elem(*i);\n";
	src += indent(h_ind + 3) +     "ASSERT(elem);\n";
	src += indent(h_ind + 3) +     "res.insert(elem);\n";
	src += indent(h_ind + 2) +   "}\n";
	src += indent(h_ind + 1) + "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_template = true;
	m.m_virtual = false;
	m.m_returnValue = rtv;
	m.m_signature = sgn;
	m.m_implementation = src;
	m.m_comment = "aggregated getter for kind \"" + kind + "\" and its descendants";
	m.m_container = cont;
}


/*static*/ void CodeGen::kindGetter3Generic( const std::string& retval_kind, const std::string& kind, const std::string& method_name, Any * cont, Method& m)
{
	// currently not used
	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "_Excl(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) + "  std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) + "  std::set<Object> l = FolderImpl::getChildObjects(\"" + kind + "\");\n";
	src += indent(h_ind + 1) + "  for( std::set<Object>::iterator i = l.begin(); i != l.end(); ++i)\n";
	src += indent(h_ind + 1) + "  {\n";
	src += indent(h_ind + 2) + "     " + retval_kind + " elem(*i);\n";
	src += indent(h_ind + 2) + "     ASSERT(elem);\n";
	src += indent(h_ind + 2) + "     res.insert(elem);\n";
	src += indent(h_ind + 1) + "  }\n";
	src += indent(h_ind + 1) + "  return res;\n";
	src += indent(h_ind + 0) + "}\n";	

	m.m_template = true;
	m.m_virtual = false;
	m.m_returnValue = rtv;
	m.m_signature = sgn;
	m.m_implementation = src;
	m.m_container = cont;
	m.m_comment = "EXCL getter for kind \"" + kind + "\"";
}




/*static*/ void CodeGen::roleGetter1Generic( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& tm)
{
	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs(\"" + inquire + "\");\n";
	src += indent(h_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +       retval_kind + " elem(*i);\n";
	src += indent(h_ind + 2) +      "ASSERT(elem);\n";
	src += indent(h_ind + 2) +      "res.insert(elem);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	tm.m_virtual = false;
	tm.m_template = true;
	tm.m_returnValue = rtv;
	tm.m_signature = sgn;
	tm.m_implementation = src;
	tm.m_container = cont;
	tm.m_comment = "getter for role \"" + inquire + "\" among \"" + fco_name + "\"s";

	return;
}


/*static*/ void CodeGen::roleGetter2Generic( const std::string& retval_kind, const std::string& inquire, const std::string& method_name, const std::string& fco_name, Any * cont, Method& tm)
{
	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs(\"" + inquire + "\");\n";
	src += indent(h_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +      retval_kind + " elem(*i);\n";
	src += indent(h_ind + 2) +      "ASSERT(elem);\n";
	src += indent(h_ind + 2) +      "res.insert(elem);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	tm.m_virtual = false;
	tm.m_template = true;
	tm.m_returnValue = rtv;
	tm.m_signature = sgn;
	tm.m_implementation = src;
	tm.m_container = cont;
	tm.m_comment = "getter for role \"" + inquire + "\" among \"" + fco_name + "\"s";

	return;
}


/*static*/ void CodeGen::roleGetter3Generic( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& role_name, const std::vector< std::string > & roles, const std::string& dummy_str, Any * cont, Method& tm)
{
	std::string src, rtv, sgn, comm;

	char len_s[10]; sprintf(len_s, "%u", roles.size()); std::string len_str( len_s);

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(" + dummy_str + ((dummy_str.empty())?"":", ") + "TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) + "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) + "const int len = " + len_str + ";\n";
	src += indent(h_ind + 1) + "std::set<BON::FCO> roles_vec[ len];\n";
	
	for( int k = 0; k < roles.size(); ++k)
	{
		char k_s[10]; sprintf( k_s, "%i", k); std::string k_str( k_s);
		src += indent(h_ind + 1) + "roles_vec[" + k_str + "] = ModelImpl::getChildFCOsAs(\"" + roles[k] + "\");\n";
	}

	src += indent(h_ind + 1) + "for( int k = 0; k < len; ++k)\n";
	src += indent(h_ind + 2) +   "for( std::set<BON::FCO>::iterator i = roles_vec[k].begin(); i != roles_vec[k].end(); ++i)\n";
	src += indent(h_ind + 2) +   "{\n";
	src += indent(h_ind + 3) +      retval_kind + " elem(*i);\n";
	src += indent(h_ind + 3) +      "ASSERT(elem);\n";
	src += indent(h_ind + 3) +      "res.insert(elem);\n";
	src += indent(h_ind + 2) +   "}\n";
	src += indent(h_ind + 1) + "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	tm.m_virtual = false;
	tm.m_template = true;
	tm.m_returnValue = rtv;
	tm.m_signature = sgn;
	tm.m_implementation = src;
	tm.m_container = cont;
	tm.m_comment = "aggregated getter for role \"" + role_name + "\" among \"" + fco_name + "\"s and its descendants";

	return;
}


/*static*/ void CodeGen::roleGetter4Generic( const std::string& retval_kind, const std::string& method_name, const std::string& fco_name, const std::string& desc_k_name, const std::string& role_name, const std::string& nmsp, Any * cont, Method& tm)
{
	std::string src, rtv, sgn, comm;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = method_name + "(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::FCO> roles = ModelImpl::getChildFCOsAs(\"" + nmsp + desc_k_name + role_name + "\");\n";
	src += indent(h_ind + 1) +   "for( std::set<BON::FCO>::iterator i = roles.begin(); i != roles.end(); ++i)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +     retval_kind + " elem(*i);\n";
	src += indent(h_ind + 2) +     "ASSERT(elem);\n";
	src += indent(h_ind + 2) +     "res.insert(elem);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	tm.m_virtual = false;
	tm.m_template = true;
	tm.m_returnValue = rtv;
	tm.m_signature = sgn;
	tm.m_implementation = src;
	tm.m_container = cont;
	tm.m_comment = "getter for role \"" + nmsp + desc_k_name + role_name + "\" among \"" + nmsp + fco_name + "\"s and its descendants";

	return;
}


/*static*/ Method CodeGen::dumpGetInConnectionLinksGeneric( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + conn->getLValidName() + ", T>";
	sgn  = "getIn" + conn->getValidName() + "Links(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + conn->getLValidName() + ", T> result;\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getInConnLinks();\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	src += indent(h_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +      conn->getLValidName() + " c( *it);\n";
	src += indent(h_ind + 2) +      "if (c)\n";
	src += indent(h_ind + 3) +        "result.insert( c);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return result;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_virtual = false;
	m.m_template = true;
	m.m_signature = sgn;
	m.m_returnValue = rtv;
	m.m_implementation = src;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}

/*static*/ Method CodeGen::dumpGetOutConnectionLinksGeneric( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + conn->getLValidName() + ", T>";
	sgn  = "getOut" + conn->getValidName() + "Links(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + conn->getLValidName() + ", T> result;\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getOutConnLinks();\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	src += indent(h_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +      conn->getLValidName() + " c( *it);\n";
	src += indent(h_ind + 2) +      "if (c)\n";
	src += indent(h_ind + 3) +        "result.insert( c);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return result;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_virtual = false;
	m.m_template = true;
	m.m_signature = sgn;
	m.m_returnValue = rtv;
	m.m_implementation = src;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}

/*static*/ Method CodeGen::dumpGetBothConnectionLinksGeneric( FCO *fco, ConnectionRep * conn)
{
	Method m;

	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + conn->getLValidName() + ", T>";
	sgn  = "get" + conn->getValidName() + "Links(TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + conn->getLValidName() + ", T> result;\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection> conns = ConnectionEndImpl::getConnLinks();\n";
	src += indent(h_ind + 1) +   "std::set<BON::Connection>::iterator it = conns.begin();\n";
	src += indent(h_ind + 1) +   "for( ; it != conns.end(); ++it)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +      conn->getLValidName() + " c( *it);\n";
	src += indent(h_ind + 2) +      "if (c)\n";
	src += indent(h_ind + 3) +        "result.insert( c);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return result;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_virtual = false;
	m.m_template = true;
	m.m_signature = sgn;
	m.m_returnValue = rtv;
	m.m_implementation = src;
	m.m_container = fco;
	m.m_comment = "";

	return m;
}


/*static*/ Method CodeGen::dumpGetInConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string src, rtv, sgn;

	if ( peer_may_be_refport)
	{
		// if reference ports may be conn ends than the implementation is so simple
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<BON::ConnectionEnd, T>";
		sgn  = "get" + conn->getValidName() + "Srcs(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<BON::ConnectionEnd> ends = BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 1) +   "return std::multiset<BON::ConnectionEnd, T>( ends.begin(), ends.end());\n";
		src += indent(h_ind + 0) + "}\n";
		
		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns src " + peer_lcd + "s and referenceports";
	}
	else
	{
		// if we know that no reference ports are between the connends
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<" + peer_lcd + ", T>";
		sgn  = "get" + conn->getValidName() + "Srcs(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<" + peer_lcd + ", T> res;\n";
		src += indent(h_ind + 1) +   "{\n";
		// the name getInConnEnds is confusing but does the right thing
		src += indent(h_ind + 2) +     "std::multiset<BON::ConnectionEnd> in_ends = BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = in_ends.begin() ; cit != in_ends.end() ; ++cit )\n";
		src += indent(h_ind + 2) +     "{\n";
		src += indent(h_ind + 3) +       peer_lcd + " dst( *cit );\n";
		src += indent(h_ind + 3) +       "ASSERT(dst);\n";
		src += indent(h_ind + 3) +       "res.insert( dst);\n";
		src += indent(h_ind + 2) +     "}\n";
		src += indent(h_ind + 1) +   "}\n";
		src += indent(h_ind + 1) +   "return res;\n";
		src += indent(h_ind + 0) + "}\n";

		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns src " + peer_lcd + "s";;
	}
	return m;
}

/*static*/ Method CodeGen::dumpGetOutConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string src, rtv, sgn;

	if ( peer_may_be_refport)
	{
		// if reference ports may be conn ends than the implementation is so simple
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<BON::ConnectionEnd, T>";
		sgn  = "get" + conn->getValidName() + "Dsts(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<BON::ConnectionEnd> ends = BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 1) +   "return std::multiset<BON::ConnectionEnd, T>( ends.begin(), ends.end());\n";
		src += indent(h_ind + 0) + "}\n";

		
		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns dst " + peer_lcd + "s and referenceports";
	}
	else
	{
		// if we know that no reference ports are between the connends
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<" + peer_lcd + ", T>";
		sgn  = "get" + conn->getValidName() + "Dsts(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<" + peer_lcd + ", T> res;\n";
		src += indent(h_ind + 1) +   "{\n";
		// the name getOutConnEnds is confusing but does the right thing
		src += indent(h_ind + 2) +     "std::multiset<BON::ConnectionEnd> out_ends = BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = out_ends.begin() ; cit != out_ends.end() ; ++cit )\n";
		src += indent(h_ind + 2) +     "{\n";
		src += indent(h_ind + 3) +       peer_lcd + " dst( *cit );\n";
		src += indent(h_ind + 3) +       "ASSERT(dst);\n";
		src += indent(h_ind + 3) +       "res.insert( dst);\n";
		src += indent(h_ind + 2) +     "}\n";
		src += indent(h_ind + 1) +   "}\n";
		src += indent(h_ind + 1) +   "return res;\n";
		src += indent(h_ind + 0) + "}\n";

		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns dst " + peer_lcd + "s";
	}
	return m;
}


/*static*/ Method CodeGen::dumpGetBothConnectionEndGeneric( FCO *fco, FCO* peer, ConnectionRep* conn, bool peer_may_be_refport)
{
	Method m;
	std::string peer_lcd;
	if (peer)
		peer_lcd = peer->getLValidName();
	else
		peer_lcd = "BON::FCO";

	std::string src, rtv, sgn;

	if ( peer_may_be_refport)
	{
		// if reference ports may be conn ends than the implementation is so simple
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<BON::ConnectionEnd, T>";
		sgn  = "get" + conn->getValidName() + "Ends(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<BON::ConnectionEnd> ends = BON::ConnectionEndImpl::getConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 1) +   "return std::multiset<BON::ConnectionEnd, T>( ends.begin(), ends.end());\n";
		src += indent(h_ind + 0) + "}\n";
		
		
		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns src and dst " + peer_lcd + "s and referenceports";
	}
	else
	{
		rtv  = indent(h_ind + 0) + "template <class T>\n";
		rtv += indent(h_ind + 0) + "std::multiset<" + peer_lcd + ", T>";
		sgn  = "get" + conn->getValidName() + "Ends(TDP)";
		src  = indent(h_ind + 0) + "{\n";
		src += indent(h_ind + 1) +   "std::multiset<" + peer_lcd + ", T> res;\n";
		src += indent(h_ind + 1) +   "{\n";
		src += indent(h_ind + 2) +     "std::multiset<BON::ConnectionEnd> in_ends = BON::ConnectionEndImpl::getInConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cit = in_ends.begin() ; cit != in_ends.end() ; ++cit )\n";
		src += indent(h_ind + 2) +     "{\n";
		src += indent(h_ind + 3) +       peer_lcd + " dst( *cit );\n";
		src += indent(h_ind + 3) +       "ASSERT(dst);\n";
		src += indent(h_ind + 3) +       "res.insert( dst);\n";
		src += indent(h_ind + 2) +     "}\n";
		src += indent(h_ind + 2) +     "std::multiset<BON::ConnectionEnd> out_ends = BON::ConnectionEndImpl::getOutConnEnds(\"" + conn->getLStrictName() + "\");\n";
		src += indent(h_ind + 2) +     "for ( std::multiset<BON::ConnectionEnd>::iterator cot = out_ends.begin() ; cot != out_ends.end() ; ++cot )\n";
		src += indent(h_ind + 2) +     "{\n";
		src += indent(h_ind + 3) +       peer_lcd + " dst( *cot );\n";
		src += indent(h_ind + 3) +       "ASSERT(dst);\n";
		src += indent(h_ind + 3) +       "res.insert( dst);\n";
		src += indent(h_ind + 2) +     "}\n";
		src += indent(h_ind + 1) +   "}\n";
		src += indent(h_ind + 1) +   "return res;\n";
		src += indent(h_ind + 0) + "}\n";

		m.m_virtual = false;
		m.m_template = true;
		m.m_signature = sgn;
		m.m_returnValue = rtv;
		m.m_implementation = src;
		m.m_container = fco;
		m.m_comment = "returns src and dst " + peer_lcd + "s";
	}
	return m;
}


/*static*/ Method CodeGen::dumpSetGetterGeneric( SetRep * cont, const FCO * fco, const std::string& common_kind, bool aggreg /*=false*/, bool dummy_par /*=false*/)
{
	ASSERT( fco || ( aggreg && !common_kind.empty())); //assert if fco is 0 and aggreg is false
	std::string retval_kind; // the return value cannot be "Compound" if Compound is not extended

	if (fco)
	{
		retval_kind = fco->getLValidName();

		if ( !fco->isToBeEx()) 
		{
			FCO * ext_anc = fco->getExtedAnc();
			if ( ext_anc)
				retval_kind = ext_anc->getLValidName();
			else
				retval_kind = "BON::" + Any::KIND_TYPE_STR[fco->getMyKind()];
		}
	}
	else if ( !common_kind.empty()) // using the common_kind if set
		retval_kind = common_kind;
	else // not intended for usage in such cases
		ASSERT(0);

	Method m;

	std::string src, rtv, sgn;

	rtv  = indent(h_ind + 0) + "template <class T>\n";
	rtv += indent(h_ind + 0) + "std::set<" + retval_kind + ", T>";
	sgn  = cont->setGetterTemplate( fco) + "(" + (dummy_par?" int dummy, ":"") + "TDP)";
	src  = indent(h_ind + 0) + "{\n";
	src += indent(h_ind + 1) +   "std::set<" + retval_kind + ", T> res;\n";
	src += indent(h_ind + 1) +   "std::set<BON::FCO> elems = BON::SetImpl::getMembers();\n";
	src += indent(h_ind + 1) +   "std::set<BON::FCO>::iterator elem = elems.begin();\n";
	src += indent(h_ind + 1) +   "for( ; elem != elems.end(); ++elem)\n";
	src += indent(h_ind + 1) +   "{\n";
	src += indent(h_ind + 2) +     retval_kind + " r( *elem);\n";

	if ( fco)
	{
		if ( !aggreg) // not aggregated getter
		{
			src += indent(h_ind + 2) +   "if ( r && r->getObjectMeta().name() == \"" + fco->getValidName() + "\")\n";
		}
		else // aggregated getter, casting to the common base, which is not a common kind
		{
			src += indent(h_ind + 2) + "if ( r)\n";
		}
	}
	else // aggregated getter casting to the common kind
		src += indent(h_ind + 2) +   "if ( r)\n";

	src += indent(h_ind + 3) +       "res.insert( r);\n";
	src += indent(h_ind + 1) +   "}\n";
	src += indent(h_ind + 1) +   "return res;\n";
	src += indent(h_ind + 0) + "}\n";

	m.m_virtual = false;
	m.m_template = true;
	m.m_returnValue = rtv;
	m.m_signature = sgn;
	m.m_implementation = src;
	m.m_container = cont;
	if ( !aggreg)
		m.m_comment = "specialized getter for " + fco->getValidName() + " setmembers";
	else //aggreg
		m.m_comment = "aggregated getter for setmembers";

	return m;
}


--- NEW FILE: FolderRep.h ---
#ifndef FOLDERREP_H
#define FOLDERREP_H

#include "Any.h"
#include "FCO.h"
#include "FolderRep.h"
#include "ModelRep.h"
#include "AtomRep.h"
#include "ConnectionRep.h"
#include "SetRep.h"
#include "ReferenceRep.h"
#include "FcoRep.h"

#include "list"
#include "vector"
/*
class FolderElem
{
	FolderElem( const Any * m_ptr, const std::string &m_card);
	bool operator==( const FolderElem& peer);
	Any * getElem() const;
	const std::string & getCard() const;
private:
	const FolderElem& operator=(const FolderElem& peer);
	FolderElem( const FolderElem&);

	Any * m_elem;
	std::string m_card;
};
*/
class FolderRep : public Any
{
public: // types
	typedef std::vector<FCO*>::iterator FCO_Iterator;
	typedef std::vector<FolderRep*>::iterator SubFolder_Iterator;
	typedef std::vector<FolderRep*>::const_iterator SubFolder_ConstIterator;

public:
/*
A FolderRep is created by using the id, ptr and resp_ptr which is the object 
selected using the SameFolder Selection Mechanism when SameFolder relation is met.
That is why a folder has to redefine the getName operations
*/
	FolderRep( IMgaFCO* ptr, IMgaFCO* resp_ptr); 
	~FolderRep();

	/*virtual*/ Any::KIND_TYPE getMyKind() const { return Any::FOLDER; }
	/*virtual*/ std::string getName() const;

	void addFCO( FCO * ptr, const std::string & card);
	bool isFCOContained( FCO * otr);

	void addSubFolderRep( FolderRep * ptr, const std::string & card);
	void extendMembership();

	std::string doDump();

	void addMethod(Method& m) { m_methods.push_back( m); }
	void createMethods();

	static std::string subFolderGetterMethodName(FolderRep * fold, const std::string& diff_nmsp);
	static std::string kindGetterMethodName( FCO * fco, const std::string& diff_nmsp);

protected:
	std::vector<FCO *> m_fcoList;
	std::vector<std::string> m_fcoCardList;

	/**
	 * contains all subfolders (including itself)
	 */
	std::vector<FolderRep*> m_subFolderList;
	/* Cardinality for the folders above */
	std::vector<std::string> m_subCardList;

	/**
	 * This pointer is in charge of the aspect name, 
	 * may point to a Folder or a SameFolder operator
	 */
	CComPtr<IMgaFCO> m_respPointer;

	std::vector<Method> m_methods;

private: // forbiding copy
	FolderRep( const FolderRep&);
	const FolderRep& operator=( const FolderRep&);

};
#endif //FOLDERREP_H

--- NEW FILE: Any.h ---
#ifndef ANY_H
#define ANY_H

#define DO_MOF 0
#include "MyUtil.h"
#include "Any.h"
#include <string>
#include <vector>
#include <set>
#include "logger.h"
#include <fstream>
class Method;
/** This class is the abstract base of all kinds of parts/FCOs that can occur during a modeling process. */
class Any;

class AnyLexicographicSort
{
public:
  bool operator()( Any * op1, Any * op2) const;
};

class Any 
{
public: // constant strings
	static const std::string NamespaceDispSeparatorBeg_str;//"_"
	static const std::string NamespaceDispSeparatorEnd_str;//"_"
	static const std::string NamespaceDelimiter_str;//"::"
	static const std::string InRootFolder_str;//"InRootFolder"
	static const std::string NameSelectorNode_str; //"myNameIs"

	static const std::string m_startUPToken;
	static const std::string m_endUPToken;

	static const std::string MOFException_str;//"MOFException"
	static const std::string MOFOperation_str; //"MOFOperation"
	static const std::string MOFEnumeration_str;//"MOFEnumeration"
	static const std::string MOFStructure_str; //"MOFStructure"
	static const std::string MOFAlias_str; //"MOFAlias"

	static const std::string MOFStart_str;
	static const std::string MOFEnd_str;

public: // types
	typedef enum
	{
		ATOM,
		MODEL,
		CONN,
		SET,
		REF,
		FCO_REP, // abstract term only
		ASPECT,
		FOLDER,
		CONSTRAINT,
		CONSTRAINTFUNC,
		ATTRIBUTE
	} KIND_TYPE;

	const static std::string KIND_TYPE_STR[];/* =
		{
		"ATOM",	// defined in Any.cpp If the order changes update there please
		"MODEL",
		"CONN",
		"SET",
		"REF",
		"FCO",
		"ASPECT",
		"FOLDER",
		"CONSTRAINT",
		"CONSTRAINFUNC",
		"ATTRIBUTE"
		};*/

	typedef std::set< CComPtr<IMgaFCO> > EquivSet;
	typedef std::set< CComPtr<IMgaFCO> >::const_iterator EquivSet_ConstIterator;

public:
	Any( IMgaFCO* ptr);
	virtual ~Any();

public:	
	virtual void initAttributes();
	void initNamespace();
	void resetNamespace();

	virtual KIND_TYPE getMyKind() const = 0;
	std::string getMyKindStr() const;
	virtual std::string doDump() = 0;

	//
	// the term 'name' is used in the following ways
	// validated names: C++ typenames created from the original name, e.g. a return type must be a valid C++ identifier
	// strict names: metamodel kinds and roles (these are used upon inquiries like getChild, IMPLEMENT_BON macros, and getObjectMeta().name() == "..."
	// 
	// long names: names prefixed with the namespace
	// long strict names are meta-conforming kindnames: 'mynamespace::mykind1'
	// long validated names are valid typenames appearing in the target code: 'mymeta_BONX::mytype' or 'mynamespace::mykind1'
	// IMPORTANT: if an element in the metamodel is not part of any namespace in the generated BONX it will still be part of
	// the default main namespace (provided by the user), that is where strict names and validated names will be completely different

	virtual std::string getName() const;    // returning the selected name for a kind i.e. "1stNode"
	std::string getValidName() const;       // c++ identifier (validated name) for the kind: "_1stNode"
	std::string getValidNameImpl() const;   // "_1stNodeImpl"
	
	// short namespace
	std::string getStrictNmspc() const;     // strictly returning the MetaGME def'd namespace (i.e. "NM.1") if defined, otherwise ""
	std::string getNmspc() const;           // the target namespace: "NM.1" if specified in meta, otherwise default namespace "meta5_BONX" (or the user-provided one)
	std::string getValidNmspc() const;      // c++ identifier (validated name) for the namespace "NM.1" -> "NM_1"

	// LNames = long names: namespace + name
	std::string getLStrictName() const;     // "NM.1::1stNode" or "1stNode"
	std::string getLName() const;           // "NM.1::1stNode" or "meta5_BON::1stNode"
	std::string getLValidName() const;      // "NM_1::_1stNode"
	std::string getLValidNameImpl() const;  // "NM_1::_1stNodeImpl"

	// LNamespace = long namespace: namespace + "::"
	std::string getLStrictNmspc() const;    // "" or "NM.1::"
	std::string getLNmspc() const;          // "NM.1::" or "meta5_BONX::"
	std::string getLValidNmspc() const;     // "NM_1::"
	IMgaFCO* getPtr() const { return m_ptr; }

	bool isInRootFolder();

	IMgaFolder* getParentFolder() const { return m_parentFolder; }
	void setParentFolder( IMgaFolder* writableRegFolder, IMgaFolder* nmspHolderFolder) { m_parentFolder = writableRegFolder; m_nmspRootFolder = nmspHolderFolder;}
	void setEquivPeers( EquivSet& ps) { m_equivs = ps; }

	std::string getMyPrefix( int which = 0) const;
	virtual CComPtr<IMgaRegNode> getMyRegistry() const;
	CComPtr<IMgaRegNode> getMIRegistry() const;
	bool isFCO() const;

	static void convertToValidName( std::string & p);
	static bool checkIfValidName( const std::string & p);

	virtual void prepare();
	virtual void prepareMacros();
	virtual void prepareIniFin();
	void         prepareMOF();
	void         createAcceptMethod( bool pWithTraversalOfKids, bool pSpecialized, bool pRetValBool);

	void dumpGlobals();
	std::string dumpOrnament( bool is_abstract = false);

	virtual void dumpPre( std::string & h_file, std::string & c_file);
	virtual void dumpPost( std::string & h_file, std::string & c_file);
	virtual std::string dumpClassHeader();


	std::string getUserPart();

	bool isToBeEx() const;
	void toBeEx( bool t);

	static std::string processMOFNode( const CComPtr<IMgaRegNode> n, int ind = 2);
	static std::string parseMOFException( const std::string& exc_str);
	static std::string parseMOFOperation( const std::string& exc_str);

protected:
public:
	void makeBackup();
	void initOutS();
	void initOutH( std::string& resu);
	void finiOutS();
	void finiOutH();
protected:
	void sendOutS( const std::string& content );
	void sendOutH( const std::string& content );
	std::ofstream m_sStream;
	std::ofstream m_hStream;

protected:
	// pointer of the BON object
	CComPtr<IMgaFCO> m_ptr;

	// pointer of the parent folder
	CComPtr<IMgaFolder> m_parentFolder;

	// namespace info taken from this folder
	// typically same with m_parentFolder
	CComPtr<IMgaFolder> m_nmspRootFolder;

	// equivalent peers
	EquivSet m_equivs;
	bool	m_isInRootFolder;

	// indicates if it is to be extended or not
	bool m_toEx;

	std::vector< Method > m_inifinMethods;
	std::string m_sectionMOF;
	std::string m_globalHeader;
	std::string m_globalSource;

	// part of this namespace:
	std::string m_namespace;

private: // forbiding copy
	Any( const Any&);
	const Any& operator=( const Any&);
};

#endif //ANY_H

--- NEW FILE: FCO.cpp ---
#include "stdafx.h"

#include "myutil.h"

#include "FCO.h"
#include "ReferenceRep.h"
#include "CodeGen.h"
#include "logger.h"
#include <list>
#include <algorithm>

#include "globals.h"
extern Globals global_vars;

/*static*/ const std::string FCO::IsAbstract_str = "IsAbstract";

FCO::FCO( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: Any( ptr)
	, m_respPointer( resp_ptr)
[...1241 lines suppressed...]
}


/*used at least by the ReferenceRep::createMethods */
/*static*/ std::string FCO::lcdKindIntersect( const std::vector<FCO*>& elems)
{
	if ( elems.empty()) return "";


	std::vector<FCO*>::const_iterator it = elems.begin();
	bool same_kind( true);
	KIND_TYPE kt = (*it)->getMyKind();

	for( ++it; it != elems.end() && same_kind ; ++it)
		same_kind = same_kind && ( kt == (*it)->getMyKind());

	if (same_kind) 
		return "BON::" + Any::KIND_TYPE_STR[ kt];
	return "";
}

--- NEW FILE: FcoRep.h ---
#ifndef FCOREP_H
#define FCOREP_H
#include "Any.h"
#include "RoleRep.h"
#include "FCO.h"

/** Represents an Atom kind in a model. */
class FcoRep : public FCO 
{
public:

	FcoRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	Any::KIND_TYPE getMyKind() const { return Any::FCO_REP; }
	std::string doDump();

private: // forbiding copy
	FcoRep( const FcoRep&);
	const FcoRep& operator=( const FcoRep&);
};
#endif //FCOREP_H
--- NEW FILE: ReferenceRep.h ---
#ifndef REFERENCEREP_H
#define REFERENCEREP_H

#include "Any.h"
#include "FCO.h"
#include "vector"

class ReferenceRep : public FCO 
{
public: // types
	typedef std::vector<FCO *> RefereeList;
	typedef std::vector<FCO *>::iterator RefereeList_Iterator;
	typedef std::vector<FCO *>::const_iterator RefereeList_ConstIterator;

public:
	ReferenceRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~ReferenceRep(); 
	/*virtual*/ Any::KIND_TYPE getMyKind() const { return Any::REF; }
	/*virtual*/ std::string doDump();

	void addInitialReferee( FCO * refd );
	FCO * getInitialReferee() const;
	const RefereeList& getInitialReferees() const;
	
	void addFinalReferees( FCO * referee);
	void addFinalReferees( RefereeList & referees);
	const RefereeList& getFinalReferees() const;

	bool finalize();
	void inherit();

	bool pointsToModels() const; // true if points to models only
	std::vector<const ModelRep *> getModelRefVector() const;

	bool checkNotEmpty() const;
	bool checkAllTheSameKind() const; 

	std::string refGetterTemplate(FCO *);

	std::string dumpUsing();
	std::string dumpUsingLine( FCO *);
	void createMethods();
	std::string expose( const std::string& repl_container);
	std::string hide();

protected:
	std::vector<Method> m_refGetterMethods;
	// initialy "this" refers to
	RefereeList m_initialReferees;
	// finally "this" refers to
	RefereeList m_finalReferees;
	// member that contains all the referees (including multiple steps by referring to a reference)
	RefereeList m_allReferees;

private: // forbiding copy
	ReferenceRep( const ReferenceRep&);
	const ReferenceRep& operator=( const ReferenceRep&);

};

#endif //REFERENCEREP_H
--- NEW FILE: SetRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "SetRep.h"
#include "CodeGen.h"
#include "Dumper.h"

#include "logger.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;
extern int h_ind;

SetRep::SetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
	, m_memberList()
	, m_finalMemberList()
	, m_setMethods()
{
}


SetRep::~SetRep()
{ 
	m_memberList.clear();
	m_finalMemberList.clear();
	m_setMethods.clear();
}

	
void SetRep::addMember( FCO * member) 
{ 
	SetMemberList_ConstIterator it = 
		std::find( m_memberList.begin(), m_memberList.end(), member);

	if (it == m_memberList.end()) // not found
		m_memberList.push_back( member); 
	else
		global_vars.err << "Set member " << member->getName() << " is twice in set " << getName() << "\n";
} 


void SetRep::extendMembership()
{
	// insert in the m_finalMemberList all non-abstract interface descendants of the original members
	SetMemberList_ConstIterator member_it = m_memberList.begin();
	for( ; member_it != m_memberList.end(); ++member_it)
	{
		FCO * member_ptr = *member_it;
		std::vector<FCO*> family;
		member_ptr->getIntDescendants( family);
		family.push_back( member_ptr);
		std::vector<FCO*>::iterator desc_it = family.begin();
		for( ; desc_it != family.end(); ++desc_it)
		{
			FCO * new_member = *desc_it;
			if ( !new_member->isAbstract() &&
					 m_finalMemberList.end() == std::find( m_finalMemberList.begin(), m_finalMemberList.end(), new_member)) // not found
				m_finalMemberList.push_back( new_member);
		}
	}
}


void SetRep::createMethods()
{
	// getter for each potential member
	SetMemberList_Iterator it = m_finalMemberList.begin();
	for( ; it != m_finalMemberList.end(); ++it)
	{
		if ( Dumper::m_bGenRegular)
			m_setMethods.push_back( CodeGen::dumpSetGetter( this, *it, "", false, false));

		if ( Dumper::m_bGenTemplates)
			m_setMethods.push_back( CodeGen::dumpSetGetterGeneric( this, *it, "", false, false));
	}
	
	// aggregated getter with common ancestor of all potential members
	std::vector<FCO*> common_anc = FCO::lcdIntersect( m_finalMemberList); // the set may contain all of these fcos
	if ( !common_anc.empty())
	{
		std::vector<FCO*>::iterator c_it = common_anc.begin();
		if ( c_it != common_anc.end())
		{
			if ( Dumper::m_bGenRegular)
				m_setMethods.push_back( CodeGen::dumpSetGetter( this, *c_it, "", true, true)); // generate method for only 1 common ancestor and use the dummy trick to avoid name-conflict with plain getters

			if ( Dumper::m_bGenTemplates)
				m_setMethods.push_back( CodeGen::dumpSetGetterGeneric( this, *c_it, "", true, true)); // generate method for only 1 common ancestor and use the dummy trick to avoid name-conflict with plain getters
		}
	}
	else if ( common_anc.empty()) // empty, use common_kind
	{
		std::string common_kind = FCO::lcdKindIntersect( m_finalMemberList);
		if ( !common_kind.empty())
		{
			if ( Dumper::m_bGenRegular)
				m_setMethods.push_back( CodeGen::dumpSetGetter( this, 0, common_kind, true, false));

			if ( Dumper::m_bGenTemplates)
				m_setMethods.push_back( CodeGen::dumpSetGetterGeneric( this, 0, common_kind, true, false));

		}
		//else one solution remained: BON::FCO this is not adding any service to the plain Bon2 getMembers() call, so omitted
		else
			global_vars.err << "Note: " << getName() << "Impl::getAllMembers() omitted since it can return only what the SetImpl::getMembers() does."<< "\n";
	}
}


std::string SetRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);
	dumpFCO( h_file, c_file);

	if ( !m_setMethods.empty())
		h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// set getters\n";

	MethodLexicographicSort lex;
	std::sort( m_setMethods.begin(), m_setMethods.end(), lex);
	
	std::vector<Method>::iterator i = m_setMethods.begin();
	for( ; i != m_setMethods.end(); ++i)
	{
		h_file += i->getHeader() + "\n";
		c_file += i->getSource() + "";
	}

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}


bool SetRep::checkSetElements()
{
	bool res = true;
	const int number_of_lists = 1;
	const SetMemberList* lists[ number_of_lists] = {
		&m_memberList
	};

	for( int i = 0; i < number_of_lists; ++i)
	{
		SetMemberList_ConstIterator member_it = lists[i]->begin();
		// for all members of the set
		for( ; member_it != lists[i]->end(); ++member_it)
		{
			FCO * member_ptr = *member_it;

			if ( !member_ptr->checkIsPartOfFinal() && !member_ptr->isAbstract())
			{
				global_vars.err << std::string("CHECK: set member " + member_ptr->getName() + " [in set " + getName() + "] has no parent.\n");
				res = false;
			}
		}
	}
	return res;
}


std::string SetRep::setGetterTemplate( const FCO * fco)
{
#if(LONG_NAMES)
	if (fco)
	{
		bool same_nmsp = fco->getValidNmspc() == getValidNmspc();
		return "get" + ( same_nmsp ? fco->getValidName() : fco->getValidNmspc() + fco->getValidName())) + "Members";
	}
	else
		return "getAllMembers";
#else
	if (fco)
	{
		bool same_nmsp = fco->getValidNmspc() == getValidNmspc(); 
		return "get" + ( same_nmsp ? fco->getValidName() : ( fco->getValidNmspc() + fco->getValidName())) + "s";
	}
	else
		return "getAllMembers";
#endif
}


std::string SetRep::expose( const std::string& repl_container)
{
	std::string h_file;
	h_file += FCO::expose( repl_container);

	if (!m_setMethods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// exposed set getters\n";
	std::vector<Method>::iterator i = m_setMethods.begin();
	for( ; i != m_setMethods.end(); ++i)
	{
		h_file += i->getExposed( repl_container) + "\n";
	}

	return h_file;
}


std::string SetRep::hide()
{
	std::string h_file;
	h_file += FCO::hide();

	if (!m_setMethods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// hidden set getters\n";
	std::vector<Method>::iterator i = m_setMethods.begin();
	for( ; i != m_setMethods.end(); ++i)
	{
		h_file += i->getHidden() + "\n";
	}

	return h_file;
}



--- NEW FILE: CodeGen.cpp ---
#include "stdafx.h"
#include "CodeGen.h"
#include "Dumper.h"
#include "MakeVisitor.h"


/*const*/ int h_ind = 1;
/*const*/ int s_ind = 0;

/*static*/ std::string CodeGen::indent( int tabs /* = 0*/)
{
	return std::string( (unsigned) tabs, '\t');
}


/*static*/ std::string CodeGen::fill( int fill /* = 1*/)
{
	return std::string( (unsigned) fill, ' ');
}


/**
 * Folder related methods
 */

/*static*/ void CodeGen::dumpFoldGetter( FolderRep* sub, FolderRep *cont)
{
	std::string sub_nmsp( sub->getValidNmspc()), fol_nmsp( cont->getValidNmspc()), diff_nmsp( "");
	bool is_diff_nmsp = sub_nmsp != fol_nmsp;
	if( is_diff_nmsp) diff_nmsp = sub_nmsp;

	std::string method_name = FolderRep::subFolderGetterMethodName( sub, diff_nmsp);
	std::string retval_folderkind( sub->getLValidName()), folderkind( sub->getLStrictName());
	//retval_folderkind = folderkind = sub->getValidName();
	if ( !sub->isToBeEx())
		retval_folderkind = "BON::Folder";

	if ( Dumper::m_bGenRegular)
	{
		Method m;

		folderGetter( retval_folderkind, folderkind, method_name, sub->isToBeEx(), cont, m);

		cont->addMethod( m);
	}

	
	if ( Dumper::m_bGenTemplates)
	{
		Method m;

		folderGetterGeneric( retval_folderkind, folderkind, method_name, sub->isToBeEx(), cont, m);

		cont->addMethod( m);
	}
}

// used by the Folder only
/*static*/ void CodeGen::dumpKindGetter( FCO* fco, FolderRep * cont)
{
	std::string fco_nmsp( fco->getValidNmspc()), fol_nmsp( cont->getValidNmspc()), diff_nmsp( "");
	bool is_diff_nmsp = fco_nmsp != fol_nmsp;
	if( is_diff_nmsp) diff_nmsp = fco_nmsp;

	std::string method_name = FolderRep::kindGetterMethodName( fco, diff_nmsp);
	
	std::string retval_kind( fco->getLValidName()), kind( fco->getLStrictName());
	//retval_kind = kind = fco->getValidName();

	if (!fco->isToBeEx())
		retval_kind = "BON::FCO";

	std::string src, comm;
	
	std::vector<FCO*> r;
	fco->getIntDescendants( r);
	if ( r.empty())
	{
		if (!fco->isAbstract())
		{
			if ( Dumper::m_bGenRegular)
			{
				Method m;

				kindGetter1( retval_kind, kind, method_name, cont, m);

				cont->addMethod( m);
			}

			
			if ( Dumper::m_bGenTemplates)
			{
				Method m;

				kindGetter1Generic( retval_kind, kind, method_name, cont, m);

				cont->addMethod( m);
			}
		}
	}
	else // there are descendants
	{
		r.push_back( fco);
		
		std::vector< std::string > kind_vec;
		
		std::vector<FCO*>::iterator it = r.begin();
		for( ; it != r.end(); ++it)
		{
			if (!(*it)->isAbstract())
			{
				kind_vec.push_back( (*it)->getLStrictName());
			}
		}

		if ( !kind_vec.empty()) // there is non abstract desc of fco
		{
			if ( Dumper::m_bGenRegular)
			{
				Method m;

				kindGetter2( retval_kind, kind, kind_vec, method_name, cont, m);

				cont->addMethod( m);
			}

			
			if ( Dumper::m_bGenTemplates)
			{
				Method m;

				kindGetter2Generic( retval_kind, kind, kind_vec, method_name, cont, m);

				cont->addMethod( m);
			}
		}

		/* if there is a need for Excl getters
		if ( Dumper::m_bGenRegular)
		{
			Method m; // exclusive getter

			kindGetter3Generic( retval_kind, kind, method_name, cont, m);

			cont->addMethod( m);
		}


		if ( Dumper::m_bGenTemplates)
		{
			Method m; // exclusive getter

			kindGetter3Generic( retval_kind, kind, method_name, cont, m);

			cont->addMethod( m);
		}*/
	}
}



/**
 * Model related methods
 */

/*static*/ void CodeGen::dumpRoleGetter( FCO* fco, RoleRep * role, ModelRep * cont)
{
	// <!> fco == role->getFCOPtr() so fco could be removed from the parameter list
	std::string method_name;
	
	std::string src, comm; 

	std::string fco_nmsp( fco->getValidNmspc()), mod_nmsp( cont->getValidNmspc()), diff_nmsp( "");
	bool is_diff_nmsp = fco_nmsp != mod_nmsp;
	if( is_diff_nmsp) diff_nmsp = fco_nmsp;

	std::string l_fco_name = fco->getLName();
		
	std::vector<FCO*> desc;
	fco->getIntDescendants( desc);
	if ( desc.empty()) // no descendants, the RoleName can be used instead of the name
	{
		if ( !fco->isAbstract())
		{
			method_name = ModelRep::roleGetterMethodName2( fco, role, false, diff_nmsp );
			std::string inquire = fco->getLStrictNmspc() + role->getSmartRoleName(); 
			std::string retval_kind = fco->getLValidName();
			if ( !fco->isToBeEx())
			{
				FCO * ext_anc = fco->getExtedAnc();
				if ( ext_anc)
					retval_kind = ext_anc->getLValidName();
				else
					retval_kind = "BON::" + Any::KIND_TYPE_STR[fco->getMyKind()];
			}

			if ( Dumper::m_bGenRegular)
			{
				Method m;

				roleGetter1( retval_kind, inquire, method_name, l_fco_name, cont, m);

				cont->addMethod( m);
			}

			
			if ( Dumper::m_bGenTemplates)
			{
				Method tm;

				roleGetter1Generic( retval_kind, inquire, method_name, l_fco_name, cont, tm);

				cont->addMethod( tm);
			}
		}
		else { } // do nothing in case is abstract and it doesn't have descs
	}
	else // has descendants (some of them may be abstract)
	{
		method_name = ModelRep::roleGetterMethodName2( fco, role, false, diff_nmsp);

		desc.push_back( fco);
		int count = 0;
		std::vector<FCO*>::iterator it = desc.begin();
		for( ; it != desc.end(); ++it)
		{
			if (!(*it)->isAbstract())
				++count;
		}

		/*
		if count == 1 <==> if and only if isLongForm() == false
		meaning that no need to use long rolenames to distinguish
		*/
		if (count == 0) // are there non-abstract descs of fco (including itself)?
		{ 
			// all desc (including the roleowner) is abstract
			// no method generated
		}
		else if ( count == 1)
		{
			for( int k = 0; k < desc.size() && desc[k]->isAbstract(); ++k) { }
			if ( k >= desc.size()) throw("Index out of bound during dumpRoleGetter");

			method_name = ModelRep::roleGetterMethodName2( desc[k], role, false, diff_nmsp);

			std::string retval_kind = desc[k]->getLValidName();
			if( !desc[k]->isToBeEx())
			{
				FCO * ext_anc = desc[k]->getExtedAnc();
				if ( ext_anc)
					retval_kind = ext_anc->getLValidName();
				else
					retval_kind = "BON::" + Any::KIND_TYPE_STR[desc[k]->getMyKind()];
			}

			// there is only one non-abstract, meaning that short role name must be used
			
			//std::string inquire = role->getSmartRoleName();

			std::string inquire = desc[k]->getLStrictNmspc() + (role->getOnlyRoleName().empty()?desc[k]->getName():role->getOnlyRoleName());

			if ( Dumper::m_bGenRegular)
			{
				Method m;

				roleGetter2( retval_kind, inquire, method_name, l_fco_name, cont, m);

				cont->addMethod( m);
			}

			
			if ( Dumper::m_bGenTemplates)
			{
				Method tm;

				roleGetter2Generic( retval_kind, inquire, method_name, l_fco_name, cont, tm);

				cont->addMethod( tm);
			}
		}
		else if ( count > 1)
		{
			// more than one, so long role names to be used to the inquire
			
			// the aggregated can use "short form like" method name
			method_name = ModelRep::roleGetterMethodName2( fco, role, false, diff_nmsp); 

			std::string retval_kind = fco->getLValidName();
			if ( !fco->isToBeEx())
			{
				FCO * ext_anc = fco->getExtedAnc();
				if ( ext_anc)
					retval_kind = ext_anc->getLValidName();
				else
					retval_kind = "BON::" + Any::KIND_TYPE_STR[fco->getMyKind()];
			}

			std::string in_case_of_name_conflict_str;
			
			// name conflict happens if - role == "" AND
			//                          - contained fco (the role owner) is not abstract
			if (role->getOnlyRoleName().empty() && !role->getFCOPtr()->isAbstract())
				in_case_of_name_conflict_str = "int dummy"; // differentiate two methods with adding to the second method a dummy parameter
			
			std::vector< std::string > roles;
			for( int k = 0; k < desc.size(); ++k)
			{
				if ( !desc[k]->isAbstract())
				{
					roles.push_back( desc[k]->getLStrictNmspc() + desc[k]->getName() + role->getOnlyRoleName());
				}
			}

			if ( Dumper::m_bGenRegular)
			{
				Method m;

				roleGetter3( retval_kind, method_name, l_fco_name, role->getFCOPtr()->getLNmspc() + role->getOnlyRoleName(), roles, in_case_of_name_conflict_str, cont, m);

				cont->addMethod( m);
			}

			
			if ( Dumper::m_bGenTemplates)
			{
				Method tm;

				roleGetter3Generic( retval_kind, method_name, l_fco_name, role->getFCOPtr()->getLNmspc() + role->getOnlyRoleName(), roles, in_case_of_name_conflict_str, cont, tm);

				cont->addMethod( tm);
			}


			/* addition on 2/2/2004
			*/
			for( k = 0; k < desc.size(); ++k)
			{
				if ( !desc[k]->isAbstract())
				{
					method_name = ModelRep::roleGetterMethodName3( desc[k], role, false, diff_nmsp);// separate long form name for each 


					std::string retval_kind = desc[k]->getLValidName();
					if ( !desc[k]->isToBeEx())
					{
						FCO * ext_anc = desc[k]->getExtedAnc();
						if ( ext_anc)
							retval_kind = ext_anc->getLValidName();
						else
							retval_kind = "BON::" + Any::KIND_TYPE_STR[ desc[k]->getMyKind()];
					}

					if ( Dumper::m_bGenRegular)
					{
						Method m;

						roleGetter4( retval_kind, method_name, fco->getName(), desc[k]->getName(), role->getOnlyRoleName(), fco->getLStrictNmspc(), cont, m);

						cont->addMethod( m);
					}

					
					if ( Dumper::m_bGenTemplates)
					{
						Method tm;

						roleGetter4Generic( retval_kind, method_name, fco->getName(), desc[k]->getName(), role->getOnlyRoleName(), fco->getLStrictNmspc(), cont, tm);

						cont->addMethod( tm);
					}
				}
			}
		}
	}
}


/**
 * Reference related methods
 */

/*static*/ Method CodeGen::dumpRefGetter( ReferenceRep * cont, FCO * fco, const std::string& common_kind)
{
	Method m;
	std::string mmm, retval_kind;
	if (fco)
	{
		retval_kind = fco->getLValidName();

		if ( !fco->isToBeEx())
		{
			FCO * ext_anc = fco->getExtedAnc();
			if ( ext_anc)
				retval_kind = ext_anc->getLValidName();
			else
				retval_kind = "BON::" + Any::KIND_TYPE_STR[fco->getMyKind()];
		}
	}
	else if ( !common_kind.empty()) // using the common_kind if set
		retval_kind = common_kind;
	else
		retval_kind = "BON::FCO";

	mmm  = indent(s_ind + 0) + "{\n";
	mmm += indent(s_ind + 1) +   "BON::FCO r = BON::ReferenceImpl::getReferred();\n";
	mmm += indent(s_ind + 1) +   "return " + retval_kind + "(r);\n";
	mmm += indent(s_ind + 0) + "}\n\n\n";

	m.m_returnValue = retval_kind;
	m.m_signature = cont->refGetterTemplate(fco) + "()";
	m.m_implementation = mmm;
	m.m_container = cont;
	m.m_comment = "";

	return m;
}

/*static*/ std::string CodeGen::folderKidsTemplate()
{
	std::string mmm;
	mmm  = indent(s_ind + 1) +     "// then its children\n";
	mmm += indent(s_ind + 1) +     "std::set<BON::Folder> subfolders = BON::FolderImpl::getChildFolders();\n";
	mmm += indent(s_ind + 1) +     "for( std::set<BON::Folder>::const_iterator it = subfolders.begin(); it != subfolders.end(); ++it)\n";
	mmm += indent(s_ind + 1) +     "{\n";
	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
	mmm += indent(s_ind + 1) +     "}\n\n";
	
	mmm += indent(s_ind + 1) +     "std::set<BON::FCO> children = BON::FolderImpl::getRootFCOs();\n";
	mmm += indent(s_ind + 1) +     "for( std::set<BON::FCO>::const_iterator it = children.begin(); it != children.end(); ++it)\n";
	mmm += indent(s_ind + 1) +     "{\n";
	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
	mmm += indent(s_ind + 1) +     "}\n";

	return mmm;
}

/*static*/ std::string CodeGen::modelKidsTemplate()
{
	std::string mmm;
	mmm  = indent(s_ind + 1) +     "// then its children\n";
	mmm += indent(s_ind + 1) +     "std::set<BON::FCO> children = ModelImpl::getChildFCOs();\n";
	mmm += indent(s_ind + 1) +     "for( std::set<BON::FCO>::const_iterator it = children.begin(); it != children.end(); ++it)\n";
	mmm += indent(s_ind + 1) +     "{\n";
	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
	mmm += indent(s_ind + 1) +     "}\n";

	return mmm;
}


/*static*/ Method CodeGen::acceptMethod( Any * any, bool pWithTraversalOfKids, bool pSpecialized, bool pRetValBool)
{
	std::string kd = any->getMyKindStr();
	std::string nm = any->getValidName();
	std::string tp = any->getLValidName();
	ClassAndNamespace can = ClassAndNamespace::makeIt( any);
	//std::string sp1 = any->getValidNmspc();
	//std::string sp2 = any->getNmspc();
	std::string sp_val = any->getStrictNmspc();
	Any::convertToValidName( sp_val); // validated namespace name

	Method m;
	std::string mmm;

	// pWithTraversalOfKids is ignored
		mmm  = indent(s_ind + 0) + "{\n";
	if( pSpecialized)
	{
		mmm += indent(s_ind + 1) +     "// visit the " + tp + "\n";
		//mmm += indent(s_ind + 1) +     "pVisitor->visit" + ( Dumper::m_iVisitSign == 1?"":sp_val) + nm + "( " + tp + "( this));\n\n"; // for example: "pVisitor->visitTwoCompound( Two::Compound( this))"
		if( pRetValBool)
		{
			mmm += indent(s_ind + 1) +     "bool rv = pVisitor->visit" + can.infoName() + "( " + can.exactType() + "( this));\n";
		}
		else
		{
			mmm += indent(s_ind + 1) +     "pVisitor->visit" + can.infoName() + "( " + can.exactType() + "( this));\n";
		}
		
		if( pWithTraversalOfKids) // models 
		{
			if( any->getMyKind() == Any::MODEL)
			{
				mmm += "\n" + modelKidsTemplate();
			}
			else if( any->getMyKind() == Any::FOLDER)
			{
				mmm += "\n" + folderKidsTemplate();
			}
		}

		if( pRetValBool)
		{
			mmm += indent(s_ind + 1) +     "return rv;\n";
		}
	} else 
	{
		mmm += indent(s_ind + 1) +     "// visit the " + kd + "\n";
		mmm += indent(s_ind + 1) +     "pVisitor->visit" + kd + "( BON::" + kd + "( this));\n\n"; // for example: "pVisitor->visitModel( BON::Model( this))"

		if( pWithTraversalOfKids)
		{
			if( any->getMyKind() == Any::MODEL)
			{
				mmm += modelKidsTemplate();
			}
			else if( any->getMyKind() == Any::FOLDER)
			{
				mmm += folderKidsTemplate();
			}
		}
	}
	mmm += indent(s_ind + 0) + "}\n\n\n";


	m.m_virtual = true;
	if( pSpecialized)    //accept( SpecVisitor *pVisitor)
	{
		m.m_returnValue = pRetValBool ? "bool":"void";
		m.m_signature = "accept( " + global_vars.m_namespace_name + Any::NamespaceDelimiter_str + MakeVisitor::getVisitorName( Dumper::getInstance()->getValidName()) + " *pVisitor)";
	}
	else
	{
		m.m_returnValue = "void";
		m.m_signature = "accept( BON::Visitor *pVisitor)";
	}
	m.m_implementation = mmm;
	m.m_container = any;
	m.m_comment = "";


	return m;
}

///*obsolete*/
///*static*/ Method CodeGen::folderAcceptMethod( Any * cont, bool pWithTraversalOfKids, bool pSpecialized)
//{
//	Method m;
//	std::string mmm;
//
//	mmm  = indent(s_ind + 0) + "{\n";
//	mmm += indent(s_ind + 1) +     "// visit first the folder\n";
//	mmm += indent(s_ind + 1) +     "pVisitor->visitFolder( BON::Folder( this));\n\n";
//
//	mmm += indent(s_ind + 1) +     "// then its children\n";
//	mmm += indent(s_ind + 1) +     "std::set<BON::Folder> subfolders = BON::FolderImpl::getChildFolders();\n";
//	mmm += indent(s_ind + 1) +     "for( std::set<BON::Folder>::const_iterator it = subfolders.begin(); it != subfolders.end(); ++it)\n";
//	mmm += indent(s_ind + 1) +     "{\n";
//	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
//	mmm += indent(s_ind + 1) +     "}\n\n";
//	
//	mmm += indent(s_ind + 1) +     "std::set<BON::FCO> children = BON::FolderImpl::getRootFCOs();\n";
//	mmm += indent(s_ind + 1) +     "for( std::set<BON::FCO>::const_iterator it = children.begin(); it != children.end(); ++it)\n";
//	mmm += indent(s_ind + 1) +     "{\n";
//	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
//	mmm += indent(s_ind + 1) +     "}\n";
//	mmm += indent(s_ind + 0) + "}\n\n\n";
//
//	m.m_virtual = true;
//	m.m_returnValue = "void";
//	m.m_signature = "accept( BON::Visitor *pVisitor)";
//	m.m_implementation = mmm;
//	m.m_container = cont;
//	m.m_comment = "";
//
//	return m;
//}
//
///*static*/ Method CodeGen::modelAcceptMethod( Any * cont, bool pWithTraversalOfKids, bool pSpecialized)
//{
//	Method m;
//	std::string mmm;
//
//	mmm  = indent(s_ind + 0) + "{\n";
//	mmm += indent(s_ind + 1) +     "// visit first the model\n";
//	mmm += indent(s_ind + 1) +     "pVisitor->visitModel( BON::Model( this));\n\n";
//	mmm += indent(s_ind + 1) +     "// then its children\n";
//	mmm += indent(s_ind + 1) +     "std::set<BON::FCO> children = ModelImpl::getChildFCOs();\n";
//	mmm += indent(s_ind + 1) +     "for( std::set<BON::FCO>::const_iterator it = children.begin(); it != children.end(); ++it)\n";
//	mmm += indent(s_ind + 1) +     "{\n";
//	mmm += indent(s_ind + 2) +         "(*it)->accept( pVisitor);\n";
//	mmm += indent(s_ind + 1) +     "}\n";
//	mmm += indent(s_ind + 0) + "}\n\n\n";
//
//	m.m_virtual = true;
//	m.m_returnValue = "void";
//	m.m_signature = "accept( BON::Visitor *pVisitor)";
//	m.m_implementation = mmm;
//	m.m_container = cont;
//	m.m_comment = "";
//
//	return m;
//}


--- NEW FILE: PointerItem.h ---
#ifndef POINTERITEM_H
#define POINTERITEM_H

#include "FCO.h"

#include "string"
class PointerItem;

class PointerItemLex
{
public:
	bool operator()( const PointerItem& p1, const PointerItem& p2) const;
};


class PointerItem
{
private:
	std::string m_name;
	FCO * m_fcoPtr;
public:
	PointerItem( std::string name, FCO* fco = 0);
	PointerItem( const PointerItem& peer);
	const PointerItem& operator=( const PointerItem& peer);
	bool operator ==( const PointerItem& peer) const;
	bool operator !=( const PointerItem& peer) const;
	const std::string& name() const;
	FCO * fcoPtr() const; //<!> is this needed?
};

#endif //POINTERITEM_H

--- NEW FILE: FcoRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "FcoRep.h"
#include "logger.h"

FcoRep::FcoRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
{ 
}

std::string FcoRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);

	dumpFCO( h_file, c_file);

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}


--- NEW FILE: AtomRep.h ---
#ifndef ATOMREP_H
#define ATOMREP_H
#include "Any.h"
#include "RoleRep.h"
#include "FCO.h"

/** Represents an Atom kind in a model. */
class AtomRep : public FCO 
{
public:
	AtomRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	inline Any::KIND_TYPE getMyKind() const { return Any::ATOM; }
	std::string doDump();

private: // forbiding copy
	AtomRep( const AtomRep&);
	const AtomRep& operator=( const AtomRep&);

};
#endif //ATOMREP_H

--- NEW FILE: Method.h ---
#ifndef METHOD_H
#define METHOD_H

#include "string"

class Any;
class Method;

class MethodLexicographicSort
{
public:
  bool operator()( const Method& op1, const Method& op2) const;
};


class Method
{
public:
	bool m_virtual;
	bool m_static;
	bool m_template;
	std::string m_returnValue;
	std::string m_signature;
	std::string m_implementation;
	std::string m_comment;
	Any * m_container;

	std::string getHeader();
	std::string getSource();
	std::string getExposed( const std::string& repl_containter);
	std::string getHidden();

	Method();
	operator bool();
};



#endif
--- NEW FILE: AtomRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "AtomRep.h"
#include "logger.h"

AtomRep::AtomRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
{ 
}

std::string AtomRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);

	dumpFCO( h_file, c_file);

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}

--- NEW FILE: SetRep.h ---
#ifndef SETREP_H
#define SETREP_H

#include "myutil.h"
#include "Any.h"
#include "FCO.h"
#include "PointerItem.h"
#include "ModelRep.h"
#include "logger.h"

class SetRep : public FCO 
{
public: // types
	typedef std::vector<FCO*> SetMemberList;
	typedef std::vector<FCO*>::iterator SetMemberList_Iterator;
	typedef std::vector<FCO*>::const_iterator SetMemberList_ConstIterator;

	typedef std::vector< PointerItem> PointerItemSeries;
	typedef std::vector< PointerItem>::iterator PointerItemSeries_Iterator;
	typedef std::vector< PointerItem>::const_iterator PointerItemSeries_ConstIterator;
	typedef const ModelRep* Key;
	typedef std::map< Key, PointerItemSeries> SetMembersMap;
	typedef SetMembersMap::iterator SetMembersMap_Iterator;

public: // types
	SetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~SetRep();

	inline Any::KIND_TYPE getMyKind() const { return Any::SET; }

	// adds new elements to the m_memberList vector
	void addMember( FCO * member);
	void extendMembership();

	std::string doDump();

	bool checkSetElements();

	std::string setGetterTemplate( const FCO * fco);
	void createMethods();
	std::string expose( const std::string& repl_container);
	std::string hide();
protected:
	// stores those FCO-s which are in SET_MEMBER relationship with (*this)
	// coresponds to "initial"
	SetMemberList m_memberList;
	SetMemberList m_finalMemberList;

	std::vector<Method> m_setMethods;

private: // forbiding copy
	SetRep( const SetRep&);
	const SetRep& operator=( const SetRep&);

};

#endif //SETREP_H

--- NEW FILE: ModelRep.h ---
/* Generated by Together */

#ifndef MODELREP_H
#define MODELREP_H
#include "Any.h"
#include "RoleRep.h"
#include "FCO.h"
#include "Method.h"

class Sheet;
/**
 * Represents a Model kind. Since the containment relationship always refers to a model, this class has to have at least
 * references to the Roles. Has to contain the Aspect related information also.
 */
#include "list"
#include "map"
#include "vector"

class ModelRep : public FCO 
{
public: // types
	// roles
	typedef RoleRep RoleSeriesValue;
	typedef std::vector<RoleSeriesValue> RoleSeries;
	typedef RoleSeries::iterator RoleSeries_Iterator;
	typedef RoleSeries::const_iterator RoleSeries_ConstIterator;
	typedef FCO * RoleMapKey;
	typedef RoleSeries RoleMapValue;
	typedef std::map< RoleMapKey, RoleMapValue> RoleMap;
	typedef RoleMap::iterator RoleMap_Iterator;
	typedef RoleMap::const_iterator RoleMap_ConstIterator;

public:
	ModelRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~ModelRep();

	inline Any::KIND_TYPE getMyKind() const { return Any::MODEL; }
	std::string doDump();

	// Roles
	void addRole( RoleMapKey whose, RoleRep& role);
	void initRoles();
	bool getRoles( FCO * ptr, RoleMapValue& ) const;

	// Final roles
	void addFinalRole( RoleMapKey whose, RoleRep& role);
	bool getFinalRoles( const FCO * ptr, RoleMapValue& ) const;

	// inner models
	std::vector< ModelRep *> getInnerModels() const;
	std::vector< ModelRep *> getInnerModelsFinal() const;
	std::vector< ReferenceRep *> getInnerModelReferencesFinal() const;

	bool check();
	void inherit();

	void addMethod(Method& m) { m_methods.push_back( m); }
	void createMethods();
	std::string expose( const std::string& repl_container);
	std::string hide();

	static std::string roleGetterMethodName2( FCO * fco, RoleRep* role, bool use_fco_name, const std::string& diff_nmsp);
	static std::string roleGetterMethodName3( FCO * fco, RoleRep* role, bool use_fco_name, const std::string& diff_nmsp);

protected:
	RoleMap m_initialRoleMap;
	RoleMap m_finalRoleMap;

	std::vector<Method> m_methods;
	
private: // forbid copying
	ModelRep( const ModelRep&);
	const ModelRep& operator=( const ModelRep&);

};
#endif //MODELREP_H
--- NEW FILE: ConnectionRep.h ---
#ifndef CONNECTIONREP_H
#define CONNECTIONREP_H

#include "FCO.h"
#include "ConnJoint.h"
#include "list"

/** Represents a Connection kind. */
class ConnectionRep : public FCO 
{
public:
	ConnectionRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	/*virtual*/ ~ConnectionRep();

public:
	inline Any::KIND_TYPE getMyKind() const { return Any::CONN; }
	void addJoint( ConnJoint & joint);
	void appendJointElements( const ConnJoint & joint);
	
	void inherit();

	bool checkConnectionTargets();

	std::string doDump();

	bool calcLCD();
	bool createEndGetters();
	void addMethod( Method& m) { m_connMethods.push_back( m); }

protected:
	std::list<ConnJoint> m_jointList;
	std::vector< Method> m_connMethods;

private: // forbiding copy
	ConnectionRep( const ConnectionRep&);
	const ConnectionRep& operator=( const ConnectionRep&);
};

#endif //CONNECTIONREP_H

--- NEW FILE: FCO.h ---
#ifndef FCO_H
#define FCO_H

#include "Any.h"
#include "FCO.h"
#include "AttributeRep.h"

#include <vector>
#include <string>
#include <map>

#include "Method.h"
class ModelRep;
class ReferenceRep;
#include "RoleRep.h"

class FCO : public Any
{
public: // constant strings
	static const std::string IsAbstract_str;//"IsAbstract"
public: // typedefs
	typedef std::vector<ModelRep *> ModelRepPtrList;
	typedef std::vector<ModelRep *>::iterator ModelRepPtrList_Iterator;
	typedef std::vector<ModelRep *>::const_iterator ModelRepPtrList_ConstIterator;

	typedef std::vector<ReferenceRep *> ReferenceRepList;
	typedef std::vector<ReferenceRep *>::const_iterator ReferenceRepList_ConstIterator;
	typedef std::vector<ReferenceRep *>::iterator ReferenceRepList_Iterator;

	typedef std::vector<AttributeRep *> AttributeRepPtrList;
	typedef std::vector<AttributeRep *>::iterator AttributeRepPtrList_Iterator;
	typedef std::vector<AttributeRep *>::const_iterator AttributeRepPtrList_ConstIterator;

	typedef enum
	{
		REGULAR,
		INTERFACE,
		IMPLEMENTATION,
		NUMBER_OF_INHERITANCES // = 3
	} INHERITANCE_TYPE;

public:
	FCO( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	virtual ~FCO(); 
	virtual KIND_TYPE getMyKind() const = 0;

	/*virtual*/ std::string getName() const;

	/*virtual*/ void initAttributes();
	// abstract
	bool isAbstract() const;
	void abstract( bool is);

	// stores the references that refer to "this"
	void addRefersToMe( ReferenceRep * ref_obj);
	// gives back the reference list
	const ReferenceRepList& getReferences() const;
	
	// stores the final references that refer to "this"
	void addFinalRefersToMe( ReferenceRep * ref_obj);
	// gives back the final reference list
	const ReferenceRepList& getFinalReferences() const;

	// return all references (even those which are references to reference to "this")
	ReferenceRepList getTransitiveReferencesToMe() const;
	
	// stores the information that this is part of a ModelRep
	void iAmPartOf(ModelRep * mod_ptr); // nn
	void iAmPartOfFinal(ModelRep * mod_ptr);

	// which models is this part of
	const ModelRepPtrList& modelsIAmPartOf(); // nn
	const ModelRepPtrList& modelsIAmPartOfFinal();

	bool amIPartOf(const ModelRep * mod_ptr) const; // nn
	bool amIPartOfFinal(const ModelRep * mod_ptr) const;

	// checker if this is part of any model
	bool checkIsPartOf(); // nn
	bool checkIsPartOfFinal();

	// checker
	bool checkInheritance();

	//
	// Inheritance related methods
	//

	// adds one parent to the parent list
	void addParent( INHERITANCE_TYPE type, FCO * ptr);
	// adds one child to the children list
	void addChild( INHERITANCE_TYPE type,  FCO * ptr);
	// get all parents
	const std::vector<FCO *>&  getParents( INHERITANCE_TYPE type) const;
	// get all children
	const std::vector<FCO *>& getChildren( INHERITANCE_TYPE type) const;

	// sets the Ancestors and Descendants lists (currently only the INTERFACE and IMPLEMENTATION)
	void setAncestors( INHERITANCE_TYPE type, const std::vector<FCO*> &);
	void setDescendants( INHERITANCE_TYPE type, const std::vector<FCO*> &);

	// the desc's/ancest's who share the same intface (REGULAR and INTERFACE combined)
	void getIntDescendants( std::vector<FCO*> & descendants) const;
	void getIntAncestors( std::vector<FCO*> & ancestors) const;

	// the desc's/ancest's who should have the same constraints and attributes (REGULAR and IMPLEMENTATION combined)
	void getImpDescendants( std::vector<FCO*> & descendants) const;
	void getImpAncestors( std::vector<FCO*> & ancestors) const;
	
	// finds out if "this" has "par" as a "type" parent
	bool hasParent( const FCO * par, INHERITANCE_TYPE type) const;
	// finds out the same, but in strict sense ( no combining of REGULAR and other)
	bool hasExactParent( const FCO * par, INHERITANCE_TYPE type) const;

	std::vector<FCO *> getAllChildren() const;
	std::vector<FCO *> getAllParents() const;

	std::vector<FCO *> getAllAncestors() const;
	std::vector<FCO *> getAllDescendants() const;

	void getRootDescsUntilNonFcoRep( std::vector< FCO *> & family);
	bool hasParentOfSameKind();
	void getAllInMyHierarchy( std::vector< FCO *>& family);

	// which level in the hierarchy (INT or IMP only!!!)
	void setLevel( INHERITANCE_TYPE type, int);
	int getLevel( INHERITANCE_TYPE type);

	// which clique is the fco part of
	void setCliqueId( INHERITANCE_TYPE type, int);
	int getCliqueId( INHERITANCE_TYPE type);

	// sgets the closest extended ancestor
	void setExtedAnc( FCO * ptr);
	FCO * getExtedAnc() const;
	FCO* findRspPtr( const std::string& responsible);

	// adds a non-extended descendant which has to be included in the IMPLEMENT_BONEXT macro (its kind name)
	void addNonExtedDesc( FCO * ptr);
	const std::vector<FCO*>& getNonExtedDescVector() const;
	std::string dumpNonExtedDescKinds() const;

	// multiple and virtual inheritance detectors
	bool multipleInheritanceStep1();
	bool multipleInheritanceStep2();
	void showMultipleInheritance();

	const std::vector<FCO *> & getMultipleBaseClasses() const;
	void addMultipleBaseClasses( const std::vector<FCO *>& );

	const std::vector<FCO *> & getVirtualBaseClasses() const;
	void addVirtualBaseClasses( FCO * );
	void addVirtualBaseClasses( const std::vector<FCO *>& );

	// attributes of "this"
	void addInitialAttribute( AttributeRep * attr);
	const AttributeRepPtrList& getInitialAttributeRepPtrList() const;

	// dumpers

	/*virtual*/ void prepare();
	/*virtual*/ void prepareMacros();
	void prepareAttributes();

	void addClassGlobal( const std::string& m) { m_classGlobalPart += m; }
	void addConnMethod( Method& m) { m_connectionMethods.push_back( m); }
	void dumpConnMethods( std::string & h_file, std::string & c_file);
	void dumpAttrMethods( std::string & h_file, std::string & c_file);

	/*virtual*/ void dumpPre( std::string & h_file, std::string & c_file);
	/*virtual*/ std::string dumpClassHeader();
	void dumpFCO( std::string & h_file, std::string & c_file);

	virtual std::string hideAndExpose();
	virtual std::string expose( const std::string& repl); //specialize this in the ModelRep, SetRep, ReferenceRep
	virtual std::string hide(); //specialize this in the ModelRep, SetRep, ReferenceRep

	static std::vector<FCO *> intersect( const std::vector<FCO*>&, const std::vector<FCO*>&);
	static std::vector<FCO *> lcdIntersect( const std::vector<FCO*>&);
	static std::string lcdKindIntersect( const std::vector<FCO*>&);
	static bool equal( std::vector<FCO*>&, std::vector<FCO*>&);

protected:
	// the name responsible in case of equivalences
	CComPtr<IMgaFCO> m_respPointer;

	// the IsAbstract attribute value
	bool m_isAbstract;

	// store the list of references which refer to this
	std::vector<ReferenceRep *> m_references;
	// store the list of references which refer to this and to ancestors
	std::vector<ReferenceRep *> m_finalReferences;

	// models this FCO is Part OF (Containment)
	ModelRepPtrList m_partOf;
	ModelRepPtrList m_partOfFinal;

	// attributes
	AttributeRepPtrList m_initialAttributeList;

	// stores the direct descendant list according to 
	// Regular, Interface and Interface inheritance types
	std::vector<FCO *> m_childList[ NUMBER_OF_INHERITANCES ];
	
	// stores the direct ancestors
	std::vector<FCO *> m_parentList[ NUMBER_OF_INHERITANCES ];

	// stores all ancestors : currently REGULAR is empty, using it causes assertion
	std::vector<FCO*> m_ancestors[ NUMBER_OF_INHERITANCES ];

	// stores all descendants : currently REGULAR is empty, using it causes assertion
	std::vector<FCO*> m_descendants[ NUMBER_OF_INHERITANCES ];

	// the level the FCO stays in the inheritance hierarchy
	// initially the value is -1
	// 0 stands for the root level and so on
	// currently REGULAR is empty, using it causes an assertion
	int m_level[ NUMBER_OF_INHERITANCES ]; 


	// the clique (from inheritance point of view) the fco is part of
	// currently REGULAR is empty, using it causes an assertion
	int m_clique[ NUMBER_OF_INHERITANCES ]; ;

/*
       X
       |
 C1    A     C2
   \ / | \  /
    B1 F  B2
    |\   /
    |  D
     \ |
       E

D.m_multipleBaseClasses = A, X
E.m_multipleBaseClasses = A, X, B1, C1

B1.m_virtualBaseClasses = A !!!!
B2.m_virtualBaseClasses = A 
E.m_virtualBaseClasses = B1
D.m_virtualBaseClasses = B1
*/	
	
	std::vector<FCO*> m_multipleBaseClasses;
	std::vector<FCO*> m_virtualBaseClasses;

	std::string m_classGlobalPart;

	std::vector<Method> m_connectionMethods;
	std::vector<Method> m_attributeMethods;

	// stores the youngest ancestor which is extended
	FCO * m_extedAnc;
	// stores the descendants which have this as the extedAnc (the youngest ancestor which is extended)
	std::vector<FCO *> m_nonExtedDescs;

	// protected methods
	std::string exposeConnMethods();
	std::string exposeAttrMethods( const std::string& repl_container);
	std::string hideConnMethods();
	std::string hideAttrMethods();
	

private: // forbiding copy
	FCO( const FCO &);
	const FCO& operator=( const FCO&);

};
#endif //FCO_H

--- NEW FILE: Dumper.cpp ---
#include "stdafx.h"

#include "Dumper.h"
#include "MakeVisitor.h"

#include "algorithm"
#include <afxdlgs.h>

#include "globals.h"
extern Globals global_vars;

int ind; // indent

#include "SelConf.h"
#include "OptionsDlg.h"
#include "MakeVisitor.h"

const char* Dumper::m_strBonExtenderOptions           = "BonExtender_Options";
const char* Dumper::Yes_Str                           = "yes";
[...1039 lines suppressed...]


/*static*/ std::string Dumper::xmlFilter( const std::string& in)
{
	std::map<char, std::string> m;
	m['&'] = "&amp;";
	m['>'] = "&gt;";
	m['<'] = "&lt;";
	m['"'] = "&quot;";
	m['\''] = "&apos;";

	std::string ret;
	for( std::string::const_iterator i = in.begin(); i != in.end(); ++i)
		if ( m.find( *i) != m.end())
			ret += m[*i];
		else
			ret += *i;

	return ret;
}
--- NEW FILE: AttributeRep.h ---
#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H

#include "Any.h"
#include "Method.h"
#include "logger.h"
class FCO;

class AttributeRep : public Any
{
public:
	typedef enum {
		ENUM,
		BOOL,
		FIELD
	} ATTR_TYPE;

	AttributeRep( IMgaFCO* ptr);
	virtual ~AttributeRep();
	/*virtual*/ inline Any::KIND_TYPE  getMyKind() const { return Any::ATTRIBUTE; }
	/*virtual*/ std::string doDump() { return ""; }
	virtual Method createMethodForAttr( FCO* ) = 0;
	virtual Method createSetMethodForAttr( FCO* ) = 0;
	virtual std::string doDumpErroneousAttrHdr() = 0;
	virtual std::string doDumpErroneousAttrSrc( FCO*) = 0;

	virtual ATTR_TYPE getType() = 0;

	bool isGlobal();
	bool isViewable();
	std::string getPrompt();
	std::string getNameToUse();
	virtual std::string getMethodName() = 0;
	virtual std::string getSetMethodName() = 0;

	void addOwner( FCO * owner_fco);
	int hasAnyOwner() const;

protected:
	ATTR_TYPE attr;
	std::vector<FCO*> m_ownerList;

private:
	AttributeRep( const AttributeRep&);
	const AttributeRep& operator=( const AttributeRep &);
};


class EnumAttributeRep : public AttributeRep
{
public:
	EnumAttributeRep( IMgaFCO* ptr);
	virtual ~EnumAttributeRep() { }
	ATTR_TYPE getType() { return ENUM; }
	bool getMenuItems();
	/*virtual*/ std::string doDumpErroneousAttrHdr();
	/*virtual*/ std::string doDumpErroneousAttrSrc( FCO*);
	/*virtual*/ Method createMethodForAttr( FCO* );
	/*virtual*/ Method createSetMethodForAttr( FCO* );
	/*virtual*/ std::string getMethodName();
	/*virtual*/ std::string getSetMethodName();
	/*static*/ std::string enumTypeName( EnumAttributeRep * a);
protected:
	std::vector<std::string> m_items;
	std::vector<std::string> m_itemsVal;
	int m_noOfItems;
	int m_noOfDefault;
};

class BoolAttributeRep : public AttributeRep
{
public:
	BoolAttributeRep( IMgaFCO* ptr): AttributeRep( ptr) { }
	virtual ~BoolAttributeRep() { }
	ATTR_TYPE getType() { return BOOL; }
	/*virtual*/ std::string doDumpErroneousAttrHdr();
	/*virtual*/ std::string doDumpErroneousAttrSrc( FCO*);
	/*virtual*/ Method createMethodForAttr( FCO* );
	/*virtual*/ Method createSetMethodForAttr( FCO* );
	/*virtual*/ std::string getMethodName();
	/*virtual*/ std::string getSetMethodName();
};

class FieldAttributeRep : public AttributeRep
{
public:
	FieldAttributeRep( IMgaFCO* ptr): AttributeRep( ptr) { }
	virtual ~FieldAttributeRep() { }
	ATTR_TYPE getType() { return FIELD; }
	/*virtual*/ std::string doDumpErroneousAttrHdr();
	/*virtual*/ std::string doDumpErroneousAttrSrc( FCO*);
	/*virtual*/ Method createMethodForAttr( FCO* );
	/*virtual*/ Method createSetMethodForAttr( FCO* );
	std::string getTypeStr();
	std::string getSetTypeStr();
	std::string getMethodStr();
	/*virtual*/ std::string getMethodName();
	/*virtual*/ std::string getSetMethodName();
};

#endif // ATTRIBUTE_H


--- NEW FILE: RoleRep.cpp ---
#include "stdafx.h"

#include "RoleRep.h"
#include "FCO.h"

#include <fstream>
extern std::ofstream err;


bool StringLex::operator()( const std::string& peer1, const std::string& peer2) const
{ 
	return (peer1.compare(peer2) < 0);
}


RoleRep::RoleRep( 
	const std::string &role_name,
	FCO* ptr, 
	ModelRep * model_ptr,
	//ModelRep * owner_model_ptr,
	bool is_port,
	const std::string &cardinality,
	bool inh_role,
	bool long_form)
	:	m_roleName( role_name),
	m_ptr( ptr),
	m_model( model_ptr),
	//m_ownerModel( owner_model_ptr),
	m_isPort( is_port),
	m_cardinality( cardinality),
	m_inheritedRole( inh_role),
	m_longForm( long_form)
{ 
}

RoleRep::RoleRep( const RoleRep & peer) 
	:
	m_roleName( peer.m_roleName),
	m_ptr( peer.m_ptr), 
	m_model( peer.m_model),
	//m_ownerModel( peer.m_ownerModel),
	m_isPort( peer.m_isPort),
	m_cardinality( peer.m_cardinality),
	m_inheritedRole( peer.m_inheritedRole),
	m_longForm( peer.m_longForm)
{
}


const RoleRep& RoleRep::operator=( const RoleRep & peer) 
{ 
	if (this == &peer) return *this;
	m_roleName = peer.m_roleName;
	m_ptr = peer.m_ptr;
	m_model = peer.m_model;
	//m_ownerModel = peer.m_ownerModel;
	m_isPort = peer.m_isPort;
	m_cardinality = peer.m_cardinality; 
	m_inheritedRole = peer.m_inheritedRole;
	m_longForm = peer.m_longForm;
	return *this;
}


bool RoleRep::operator==( const RoleRep& peer) const 
{ 
	return
		m_roleName == peer.m_roleName &&
		m_ptr == peer.m_ptr &&
		m_model == peer.m_model &&
		//m_ownerModel == peer.m_ownerModel &&
		m_isPort == peer.m_isPort &&
		m_cardinality == peer.m_cardinality &&
		m_inheritedRole == peer.m_inheritedRole &&
		m_longForm == peer.m_longForm;
}


bool RoleRep::operator!=( const RoleRep& peer) const 
{ 
	return !(*this == peer); 
}


/*bool RoleRep::operator<( const RoleRep& peer) const 
{ 
	std::string m1 = this->getSmartRoleName() + m_ptr->getName();
	std::string m2 = peer.getSmartRoleName() + peer.getFCOPtr()->getName();
	err << m1 << " < " << m2 << "\n";
	return (m1.compare(m2) < 0);
}*/


const std::string& RoleRep::getOnlyRoleName() const 
{ 
	return m_roleName; 
}


std::string RoleRep::getSmartRoleName() const 
{ 
	if ( m_longForm) return m_ptr->getName() + m_roleName;
	else if (m_roleName != "") return m_roleName;
	else return m_ptr->getName();
}


FCO * RoleRep::getFCOPtr() const 
{ return m_ptr; }


ModelRep * RoleRep::getModelRepPtr() const
{ return m_model; }


/*ModelRep * RoleRep::getOwnerModelRepPtr() const
{ return m_ownerModel; }*/


bool RoleRep::isPort() const 
{ 
	return m_isPort; 
}


const std::string& RoleRep::getCardinality() const 
{ 
	return m_cardinality; 
}


void RoleRep::setInheritedRole( bool val) 
{ 
	m_inheritedRole = val; 
}


bool RoleRep::isInheritedRole() const
{ 
	return m_inheritedRole; 
}


void RoleRep::setLongForm( bool val)
{
	m_longForm = val;
}


bool RoleRep::isLongForm() const
{
	return m_longForm;
}

--- NEW FILE: Sheet.h ---
#ifndef SHEET_H
#define SHEET_H

#include "Any.h"
#include "FCO.h"
#include "FolderRep.h"
#include "ModelRep.h"
#include "AtomRep.h"
#include "ConnectionRep.h"
#include "SetRep.h"
#include "ReferenceRep.h"
#include "FcoRep.h"
#include "AttributeRep.h"
#include "RootFolder.h"

#include "list"
#include "vector"
#include "strstream"

class Sheet;

class Sheet 
{

protected:
	static Sheet * m_theOnlyInstance;
	Sheet();

public:
	//static Sheet * getInstance() ; to be implented in Derived classes
	static bool checkInstance() { return m_theOnlyInstance != 0; }
	virtual ~Sheet();
	virtual bool build() = 0;
	virtual bool finalize();
	void setProject( CComPtr<IMgaProject> project );
	std::string getValidName() { return m_validProjName; } 

	FcoRep* createFcoRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	AtomRep* createAtomRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	ModelRep* createModelRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	ConnectionRep* createConnectionRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	SetRep* createSetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	ReferenceRep* createReferenceRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	FolderRep* createFolderRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);

	AttributeRep* createBoolAttributeRep( IMgaFCO* ptr);
	AttributeRep* createEnumAttributeRep( IMgaFCO* ptr);
	AttributeRep* createFieldAttributeRep( IMgaFCO* ptr);

	FCO* findFCO( IMgaFCO* ptr);
	ReferenceRep* findRef( IMgaFCO* ptr);
	Any* findAny( IMgaFCO* ptr);

	std::string getNamespace() { return m_projNamespace; }

	CComPtr<IMgaFolder> m_BON_Project_Root_Folder2;

	std::set<CComPtr<IMgaModel> > m_setOfParadigmSheets2;

protected:
	std::vector< FCO *> Sheet::sortBasedOnLevels();
	int m_numberOfCliques[FCO::INHERITANCE_TYPE::NUMBER_OF_INHERITANCES]; // stores the number of cliques from inheritance point of view
	                                                                      // this may be different from INTERFACE and IMPLEMENTATION point of view
	typedef std::vector<FCO*>::iterator FCO_Iterator;
	typedef std::vector<Any*>::iterator Any_Iterator;

	typedef std::vector<FcoRep*>::iterator FcoRep_Iterator;
	typedef std::vector<AtomRep*>::iterator AtomRep_Iterator;
	
	typedef std::vector<ModelRep*>::iterator ModelRep_Iterator;
	
	typedef std::vector<ConnectionRep*>::iterator ConnectionRep_Iterator;
	typedef std::vector<ReferenceRep*>::iterator ReferenceRep_Iterator;
	typedef std::vector<SetRep*>::iterator SetRep_Iterator;
	typedef std::vector<FolderRep*>::iterator FolderRep_Iterator;
	typedef std::vector<AttributeRep*>::iterator AttributeRep_Iterator;

	void addAny( Any * ptr);
	void addFcoRep( FcoRep * ptr);
	void addAtomRep( AtomRep * ptr);
	void addModelRep( ModelRep * ptr);
	void addConnectionRep( ConnectionRep * ptr);
	void addReferenceRep( ReferenceRep * ptr);
	void addSetRep( SetRep * ptr);
	void addFolderRep( FolderRep * ptr);
	void addAttributeRep( AttributeRep* ptr);

	std::vector<FcoRep*> m_fcoRepList;
	std::vector<AtomRep*> m_atomList;
	std::vector<ModelRep*> m_modelList;
	std::vector<ConnectionRep*> m_connList;
	std::vector<ReferenceRep*> m_refList;
	std::vector<SetRep*> m_setList;

	std::vector<FolderRep*> m_folderList;

	std::vector<AttributeRep*> m_attributeList;

	std::string m_projName;
	std::string m_validProjName;
	std::string m_projNamespace;
	std::string m_validProjNamespace;
	RootFolder m_rootFolder;

private:
	void init();
	bool isInRootFolder( Any * elem);
	void initRoleNames();
	bool doInheritance( FCO::INHERITANCE_TYPE inh_type);
	bool multipleInheritance();
	
	// these methods deal with the order the fcos should
	// be dumped into the header file
	void order( FCO::INHERITANCE_TYPE type, std::vector<FCO*>& res);
	bool check( FCO::INHERITANCE_TYPE type, std::vector<FCO*>& res);

	typedef std::vector< unsigned int > UI_LIST;
	typedef std::vector< unsigned int > CLIQUE_VECTOR;
	typedef std::vector< FCO *> NODE_VECTOR;
	void gatherNodes( std::vector< FCO *>& nodes);
	void assignCliqueId( CLIQUE_VECTOR & clique, const NODE_VECTOR & nodes);
	bool edge( unsigned int i, unsigned int j, const NODE_VECTOR & nodes, FCO::INHERITANCE_TYPE inh_type);
	void vectorCopy( UI_LIST & target, const UI_LIST & source, UI_LIST & duplicates);
	void getChildren( unsigned int base, const NODE_VECTOR & nodes, UI_LIST & children, FCO::INHERITANCE_TYPE inh_type);
	unsigned int howManyCliques( CLIQUE_VECTOR & clique_id);
	void replaceCliqueId( CLIQUE_VECTOR & clique_id, unsigned int id1, unsigned int id2);
};
#endif //SHEET_H

--- NEW FILE: ReferenceRep.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "ReferenceRep.h"
#include "ModelRep.h"
#include "CodeGen.h"


#include <algorithm>

#include "globals.h"
extern Globals global_vars;
extern int h_ind;

ReferenceRep::ReferenceRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
	, m_initialReferees()
	, m_finalReferees()
	, m_allReferees()
{
}


ReferenceRep::~ReferenceRep() 
{ 
	m_initialReferees.clear();
	m_finalReferees.clear();
	m_allReferees.clear();
}


void ReferenceRep::addInitialReferee( FCO * refd ) 
{	
	if ( std::find( m_initialReferees.begin(), m_initialReferees.end(), refd) 
		== m_initialReferees.end()) // not found
		m_initialReferees.push_back( refd );
	else
		global_vars.err << "Warning: Reference \"" << getName() << "\" referring twice to fco: \"" << refd->getName() << "\". Disregarded.\n";
}


FCO * ReferenceRep::getInitialReferee() const
{
	if (checkNotEmpty()) return m_initialReferees[0];
	else return 0; // or an exception
}


const ReferenceRep::RefereeList& ReferenceRep::getInitialReferees() const
{
	return m_initialReferees;
}


const ReferenceRep::RefereeList& ReferenceRep::getFinalReferees() const
{
	return m_finalReferees;
}

/*
Return true if the reference refers to a Model (a non abstract model) beside other kinds like FCO or Reference
-----------------------------------------------------------------------------------------------
Since the inheritance is allowed to be homogenous the result is not depending 
if we checked the m_initialRefereeList or m_finalRefereeList
*/
bool ReferenceRep::pointsToModels() const
{
	int how_many_models = 0;
	std::string which_models;
	bool value_set = false;
	bool to_models = true;
	KIND_TYPE kind;

	for( unsigned int i = 0; i < m_allReferees.size(); ++i)
	{
		kind = m_allReferees[i]->getMyKind();
		if( kind != Any::FCO_REP && kind != Any::REF)
		{
			// consider the non-abstracts models only
			if ( !m_allReferees[i]->isAbstract())
			{
				to_models = to_models && (kind == Any::MODEL);

				value_set = true;

				if (kind == Any::MODEL)
				{
					how_many_models += 1;
					which_models += m_allReferees[i]->getName() + " ";
				}
			}
		}
	}

	if (value_set) return to_models;
	else return false;
}


/*
Should return vector<ModelRep *> if pointToModels is true
Returns non abstract models only !!! (see ESML paradigm)
*/
std::vector<const ModelRep *> ReferenceRep::getModelRefVector() const
{
	std::vector<const ModelRep *> models;
	unsigned int i = 0;
	while( i < m_allReferees.size()) 
	{
		if ( m_allReferees[i]->getMyKind() == Any::MODEL && !m_allReferees[i]->isAbstract())
		{
			const ModelRep * c_m = dynamic_cast<const ModelRep*>( m_allReferees[i]);
			if ( std::find( models.begin(), models.end(), c_m) == models.end())
				models.push_back( c_m);
		}
		++i;
	}

	return models;
}


void ReferenceRep::addFinalReferees( FCO * referee)
{
	// insert into m_finalReferees if not present already
	RefereeList_Iterator l_it = std::find( m_finalReferees.begin(), m_finalReferees.end(), referee);

	if ( l_it == m_finalReferees.end()) // not found
		m_finalReferees.push_back( referee);
	else { } // can happen if multiple inheritance is used

	referee->addFinalRefersToMe( this);
}


void ReferenceRep::addFinalReferees( RefereeList & referees )
{
	RefereeList_Iterator referee_it = referees.begin();
	for( ; referee_it != referees.end(); ++referee_it)
	{
		addFinalReferees( *referee_it);
		(*referee_it)->addFinalRefersToMe( this);
	}
}


void ReferenceRep::inherit()
{
	std::vector<FCO*> refnce_descendants;
	this->getImpDescendants( refnce_descendants); //implementation inheritance needed because the common ancestor of all referees is to be returned
	refnce_descendants.push_back( this);

	RefereeList_Iterator it = m_initialReferees.begin();
	for( ; it != m_initialReferees.end(); ++it)
	{
		FCO * target_ptr = *it;

		std::vector<FCO*> refree_descendants;

		// inquiring the refree_descendants who have the same Interface
		target_ptr->getIntDescendants( refree_descendants);
		//refree_descendants.push_back( target_ptr); see below
		std::vector<FCO*>::reverse_iterator refnce_it = refnce_descendants.rbegin();
		for( ; refnce_it != refnce_descendants.rend(); ++refnce_it) // for all impl desc of "this"
		{
			if ( (*refnce_it)->getMyKind() != Any::REF)
				global_vars.err << "Non-Reference descendant: " << (*refnce_it)->getName() <<" of reference: " << getName() <<"\n";
			else
			{
				ReferenceRep* one_refnce = dynamic_cast<ReferenceRep *>(*refnce_it);
				one_refnce->addFinalReferees( target_ptr); // put at first place the original referee
				one_refnce->addFinalReferees( refree_descendants); // adding all the interface desc of target_ptr
			}
		}
	}
}


bool ReferenceRep::finalize()
{
	bool value_set = false;
	bool same_kind = true;
	const ModelRep * mod_ptr = 0;
	KIND_TYPE kind;

	std::vector<FCO*> all_referees( m_finalReferees);

	unsigned int current = 0;
	while( !all_referees.empty() && current < all_referees.size())
	{
		if ( all_referees[current]->getMyKind() != Any::FCO_REP && 
			all_referees[current]->getMyKind() != Any::REF)
		{
			if (!value_set) 
			{
				kind = all_referees[current]->getMyKind();
				value_set = true;
			}
			else // value set already
				same_kind = same_kind && (all_referees[current]->getMyKind() == kind);
		}
		else if ( all_referees[current]->getMyKind() == Any::REF)
		{
			ReferenceRep * r = dynamic_cast<ReferenceRep *>( all_referees[current]);
			// get all referees
			const RefereeList &list = r->getFinalReferees();
			// copy if not present already into all_referees
			RefereeList_ConstIterator list_iter = list.begin();
			for( ; list_iter != list.end(); ++list_iter)
				if (std::find( all_referees.begin(), all_referees.end(), *list_iter) == all_referees.end())
					all_referees.push_back( *list_iter);
		}
		++current;
	}
	
	m_allReferees = all_referees;
	
	return same_kind;
}


void ReferenceRep::createMethods() 
{ 
	if ( m_initialReferees.empty()) return; // in such cases no specific getter is added, its base (if any) provides anyway the needed methods

	std::string getter_src, getter_hdr;
	std::vector<FCO*> common_anc = FCO::lcdIntersect( m_finalReferees); // the reference may point to all of these fcos
	if ( !common_anc.empty())
	{
		std::vector<FCO*>::iterator c_it = common_anc.begin();
		for( ; c_it != common_anc.end(); ++c_it)
			m_refGetterMethods.push_back( CodeGen::dumpRefGetter( this, *c_it, ""));
	}
	else if ( common_anc.empty()) // empty, use BON::FCO or common_kind
	{
		std::string common_kind = FCO::lcdKindIntersect( m_finalReferees);
  		m_refGetterMethods.push_back( CodeGen::dumpRefGetter( this, 0, common_kind));
	}
	else
	{
		// the reference doesn't have any referee so it doesn't deserve any getter
		// if inherits something from its base class (if any) the OK
		// otherwise ?
	}

	/*RefereeList_Iterator it = m_allReferees.begin();//m_finalReferees.begin();//m_initialReferees.begin();
	for( ; it != m_allReferees.end(); ++it )
	{
		m_refGetterMethods.push_back( ReferenceRep::dumpRefGetter( this, *it, ""));
	}*/
}


std::string ReferenceRep::doDump() 
{ 
	std::string h_file, c_file;

	dumpPre( h_file, c_file);
	dumpFCO( h_file, c_file);

	if ( !m_refGetterMethods.empty())
		h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// ref getters\n";

	MethodLexicographicSort lex;
	std::sort( m_refGetterMethods.begin(), m_refGetterMethods.end(), lex);

	std::vector<Method>::iterator i = m_refGetterMethods.begin();
	for( ; i != m_refGetterMethods.end(); ++i)
	{
		h_file += i->getHeader() + "\n";
		c_file += i->getSource() + "";
	}

	h_file += hideAndExpose();

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}


/*
It checks the m_initialReferees since the descendants of m_initialReferees will be exactly 
as diverse as the m_initialReferees
*/
bool ReferenceRep::checkNotEmpty() const
{
	return !m_initialReferees.empty();
}

bool ReferenceRep::checkAllTheSameKind() const
{
	if ( !checkNotEmpty()) return false;
	if ( m_finalReferees.empty()) return false;
	if ( m_allReferees.empty()) return false;
	
	bool all_the_same_kind = true;

	bool value_set = false;
	bool same_kind = true;
	KIND_TYPE kind;
	for( unsigned int i = 0; i < m_allReferees.size(); ++i)
	{
		KIND_TYPE kind_of_i = m_allReferees[i]->getMyKind();
		if( kind_of_i != Any::FCO_REP && kind_of_i != Any::REF)
		{
			if (!value_set) 
			{
				kind = kind_of_i;
				value_set = true;
			}
			else // value set already
			{
				same_kind = same_kind && ( kind_of_i == kind);
				if (kind_of_i != kind)
				{
					// removed on 2/25/2004
					/*global_vars.err << "CHECK: Reference \"" << getName() << "\" refers to too many kinds: " <<
					Any::KIND_TYPE_STR[kind] << " and " << Any::KIND_TYPE_STR[kind_of_i] << "\n";*/
				}
			}
		}
	}
	if (value_set) return same_kind;
	else return false;
}


std::string ReferenceRep::refGetterTemplate( FCO * fco)
{
#if(LONG_NAMES)
	if (fco)
		return "get" + fco->getValidName() + "Referred";
	else
		return "getReferred";
#else
	if (fco)
	{
		bool same_nmsp = fco->getValidNmspc() == getValidNmspc();
		return "get" + ( same_nmsp ? fco->getValidName() : ( fco->getValidNmspc() + fco->getValidName()));
	}
	else
		return "getReferred";
#endif
}


std::string ReferenceRep::expose( const std::string& repl_container)
{ 
	std::string h_file;
	h_file += FCO::expose( repl_container);

	if (!m_refGetterMethods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// exposed ref getters\n";
	std::vector<Method>::iterator i = m_refGetterMethods.begin();
	for( ; i != m_refGetterMethods.end(); ++i)
	{
		h_file += i->getExposed( repl_container) + "\n";
	}

	return h_file;
}


std::string ReferenceRep::hide() 
{ 
	std::string h_file;
	h_file += FCO::hide();
	
	if (!m_refGetterMethods.empty())
		h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// hidden ref getters\n";
	std::vector<Method>::iterator i = m_refGetterMethods.begin();
	for( ; i != m_refGetterMethods.end(); ++i)
	{
		h_file += i->getHidden() + "\n";
	}

	return h_file;
}



--- NEW FILE: MakeVisitor.h ---
#ifndef MAKEVISITOR_H
#define MAKEVISITOR_H

#include "string"
#include "vector"
#include "Any.h"

#define HOW_MANY_ITEMS 8

class ClassAndNamespace
{
public:
	static ClassAndNamespace makeIt( Any *);

	ClassAndNamespace( const std::string& pName, const std::string& pSpace, const std::string& pStrictSpace);
	std::string name() const;
	std::string space() const;
	std::string strictSpace() const;
	std::string infoName() const; // gives back a NMSPKIND form (informative name)
	std::string exactType() const;// gives back a type NMPS::KIND form (exact C++ type name)
private:
	std::string m_name;
	std::string m_space;
	std::string m_strictSpace;
};

class MakeVisitor
{
public:
	static std::string getVisitorName( const std::string& name) { return name + "Visitor"; }
	MakeVisitor( const std::string& name) { m_className = getVisitorName( name); }
	const std::string& getClassName() { return m_className; }

	void addEntity( Any::KIND_TYPE , const ClassAndNamespace&);
	std::string dumpVisitorHeader();
	std::string dumpVisitorSource();
	std::string dumpSpecificMethods( const ClassAndNamespace& name);
	std::string dumpGenericMethods();
protected:
	std::vector< ClassAndNamespace > m_entities[HOW_MANY_ITEMS];
	std::string m_className;
};

#endif // MAKEVISITOR_H
--- NEW FILE: Sheet.cpp ---
#include "stdafx.h"

#include "myutil.h"
#include "Sheet.h"
#include "logger.h"

#include "globals.h"
extern Globals global_vars;

Sheet * Sheet::m_theOnlyInstance = 0;

Sheet::Sheet()
	: m_projName(""),
	m_validProjName(""),
	m_projNamespace(""),
	m_validProjNamespace(""),
	m_rootFolder(),
	m_fcoRepList(),
	m_atomList(),
	m_modelList(),
	m_connList(),
	m_refList(),
	m_setList(),
	m_folderList(),
	m_attributeList()
{
	for( unsigned int i = 0; i < FCO::INHERITANCE_TYPE::NUMBER_OF_INHERITANCES; ++i)
		m_numberOfCliques[ i ] = 0;
}


Sheet::~Sheet()
{
	for( unsigned int i = 0; i < FCO::INHERITANCE_TYPE::NUMBER_OF_INHERITANCES; ++i)
		m_numberOfCliques[ i ] = 0;
	m_theOnlyInstance = 0;
	
	{
		FcoRep_Iterator it( m_fcoRepList.begin() );
		for( ; it != m_fcoRepList.end(); ++it)
		{
			FcoRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		AtomRep_Iterator it = m_atomList.begin();
		for( ; it != m_atomList.end(); ++it)
		{
			AtomRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		ModelRep_Iterator it = m_modelList.begin();
		for( ; it != m_modelList.end(); ++it)
		{
			ModelRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		ConnectionRep_Iterator it = m_connList.begin();
		for( ; it != m_connList.end(); ++it)
		{
			ConnectionRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		SetRep_Iterator it = m_setList.begin();
		for( ; it != m_setList.end(); ++it)
		{
			SetRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		ReferenceRep_Iterator it = m_refList.begin();
		for( ; it != m_refList.end(); ++it)
		{
			ReferenceRep * act_ptr = * it;
			delete act_ptr;
		}
	}
	{
		FolderRep_Iterator ai = m_folderList.begin();
		for( ; ai != m_folderList.end(); ++ai)
		{
			FolderRep * act_ptr = * ai;
			delete act_ptr;
		}
	}
	{
		AttributeRep_Iterator ai = m_attributeList.begin();
		for( ; ai != m_attributeList.end(); ++ai)
		{
			AttributeRep * act_ptr = * ai;
			delete act_ptr;
		}
	}
	m_fcoRepList.clear();
	m_atomList.clear();
	m_modelList.clear();
	m_connList.clear();
	m_refList.clear();
	m_setList.clear();

	m_folderList.clear();

	m_attributeList.clear();

	m_BON_Project_Root_Folder2 = CComPtr<IMgaFolder>( 0);

	m_setOfParadigmSheets2.erase( m_setOfParadigmSheets2.begin(), m_setOfParadigmSheets2.end());
	m_setOfParadigmSheets2.clear();
}


void Sheet::setProject( CComPtr<IMgaProject> project)
{
	CComBSTR nm;
	COMTHROW( project->get_Name( &nm));
	m_validProjName = m_projName = Util::Copy( nm);
	Any::convertToValidName( m_validProjName);

	CComPtr<IMgaFolder> rf;
	COMTHROW( project->get_RootFolder( &rf));
	m_validProjNamespace = m_projNamespace = Util::getReg( rf, "Namespace");

	// convert the namespace specified (can be empty) to a valid identifier
	Any::convertToValidName( m_validProjNamespace);
}

/*virtual*/ bool Sheet::finalize()
{
	bool ret_val = false;
	if ( doInheritance( FCO::INTERFACE) 
		&& doInheritance( FCO::IMPLEMENTATION))
	{
		init();
		initRoleNames();

		multipleInheritance();
		ret_val = true;
	}
	else 
		global_vars.err << "Error: Inheritance problems\n";

	return ret_val;	
}

void Sheet::init()
{
	{FcoRep_Iterator it0( m_fcoRepList.begin());
	for( ; it0 != m_fcoRepList.end(); ++it0 )
	{
		(*it0)->initNamespace();
		(*it0)->initAttributes();
		if ( isInRootFolder( *it0)) m_rootFolder.addRootElement( *it0);
	}}

	{AtomRep_Iterator it1 = m_atomList.begin();
	for( ; it1 != m_atomList.end(); ++it1 )
	{
		(*it1)->initNamespace();
		(*it1)->initAttributes();
		if ( isInRootFolder( *it1)) m_rootFolder.addRootElement( *it1);
	}}

	{ModelRep_Iterator it2 = m_modelList.begin();
	for( ; it2 != m_modelList.end(); ++it2 )
	{
		(*it2)->initNamespace();
		(*it2)->initAttributes();
		if ( isInRootFolder( *it2)) m_rootFolder.addRootElement( *it2);
	}}

	{ConnectionRep_Iterator it3 = m_connList.begin();
	for( ; it3 != m_connList.end(); ++it3 )
	{
		(*it3)->initNamespace();
		(*it3)->initAttributes();
		if ( isInRootFolder( *it3)) m_rootFolder.addRootElement( *it3);
	}}

	{SetRep_Iterator it4 = m_setList.begin();
	for( ; it4 != m_setList.end(); ++it4 )
	{
		(*it4)->initNamespace();
		(*it4)->initAttributes();
		if ( isInRootFolder( *it4)) m_rootFolder.addRootElement( *it4);
	}}

	{ReferenceRep_Iterator it5 = m_refList.begin();
	for( ; it5 != m_refList.end(); ++it5 )
	{
		(*it5)->initNamespace();
		(*it5)->initAttributes();
		if ( isInRootFolder( *it5)) m_rootFolder.addRootElement( *it5);
	}}
	
	{FolderRep_Iterator it6 = m_folderList.begin();
	for( ; it6 != m_folderList.end(); ++it6 )
	{
		(*it6)->initNamespace();
		(*it6)->initAttributes();
		if ( isInRootFolder( *it6)) m_rootFolder.addSubFolder( *it6);
	}}

	{AttributeRep_Iterator it7 = m_attributeList.begin();
	for( ; it7 != m_attributeList.end(); ++it7 )
	{
		(*it7)->initNamespace();
	}}
}


void Sheet::initRoleNames()
{
	ModelRep_Iterator jt1( m_modelList.begin());
	for( ; jt1 != m_modelList.end(); ++jt1)
	{
		ModelRep * mod_ptr = *jt1;
		mod_ptr->initRoles();
	}
}


FcoRep* Sheet::createFcoRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	FcoRep * ll = new FcoRep( ptr, resp_ptr);
	addFcoRep( ll);
	return ll;
}


AtomRep* Sheet::createAtomRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	AtomRep * ll = new AtomRep( ptr, resp_ptr);
	addAtomRep( ll);
	return ll;
}


ModelRep* Sheet::createModelRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	ModelRep * ll = new ModelRep( ptr, resp_ptr);
	addModelRep( ll);
	return ll;
}


ConnectionRep* Sheet::createConnectionRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	ConnectionRep * ll = new ConnectionRep( ptr, resp_ptr);
	addConnectionRep( ll);
	return ll;
}


SetRep* Sheet::createSetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	SetRep * ll = new SetRep( ptr, resp_ptr);
	addSetRep( ll);
	return ll;
}


ReferenceRep* Sheet::createReferenceRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	ReferenceRep * ll = new ReferenceRep( ptr, resp_ptr);
	addReferenceRep( ll);
	return ll;
}


FolderRep* Sheet::createFolderRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	FolderRep * ll = new FolderRep( ptr, resp_ptr);
	addFolderRep( ll);
	return ll;
}


AttributeRep* Sheet::createBoolAttributeRep( IMgaFCO* ptr)
{
	AttributeRep * ll = new BoolAttributeRep( ptr);
	addAttributeRep( ll);
	return ll;
}


AttributeRep* Sheet::createEnumAttributeRep( IMgaFCO* ptr)
{
	AttributeRep * ll = new EnumAttributeRep( ptr);
	addAttributeRep( ll);
	return ll;
}


AttributeRep* Sheet::createFieldAttributeRep( IMgaFCO* ptr)
{
	AttributeRep * ll = new FieldAttributeRep( ptr);
	addAttributeRep( ll);
	return ll;
}


void Sheet::addFcoRep( FcoRep * ptr)
{
	m_fcoRepList.push_back( ptr);
}


void Sheet::addAtomRep( AtomRep * ptr)
{
	m_atomList.push_back( ptr);
}


void Sheet::addModelRep( ModelRep * ptr)
{
	m_modelList.push_back( ptr);
}


void Sheet::addConnectionRep( ConnectionRep * ptr)
{
	m_connList.push_back( ptr);
}


void Sheet::addReferenceRep( ReferenceRep * ptr)
{
	m_refList.push_back( ptr);
}


void Sheet::addSetRep( SetRep * ptr)
{
	m_setList.push_back( ptr);
}


void Sheet::addFolderRep( FolderRep * ptr)
{
	m_folderList.push_back(ptr);
}


void Sheet::addAttributeRep( AttributeRep * ptr)
{
	m_attributeList.push_back(ptr);
}



/**
 * This method returns a pointer
 * Since the container consists of pointers to FCO
 * the iterator is a pointer to an FCO pointer
 * it has FCO** type
 * *it has FCO* type
 * the same refers to the methods below
 */
FCO* Sheet::findFCO( IMgaFCO* ptr)
{
	FcoRep_Iterator it0( m_fcoRepList.begin());
	for( ; it0 != m_fcoRepList.end(); ++it0 )
	{
		if ((*it0)->getPtr() == ptr) return *it0;
	}

	AtomRep_Iterator it1 = m_atomList.begin();
	for( ; it1 != m_atomList.end(); ++it1 )
	{
		if ((*it1)->getPtr() == ptr) return *it1;
	}

	ModelRep_Iterator it2 = m_modelList.begin();
	for( ; it2 != m_modelList.end(); ++it2 )
	{
		if ((*it2)->getPtr() == ptr) return *it2;
	}

	ConnectionRep_Iterator it3 = m_connList.begin();
	for( ; it3 != m_connList.end(); ++it3 )
	{
		if ((*it3)->getPtr() == ptr) return *it3;
	}

	SetRep_Iterator it4 = m_setList.begin();
	for( ; it4 != m_setList.end(); ++it4 )
	{
		if ((*it4)->getPtr() == ptr) return *it4;
	}

	ReferenceRep_Iterator it5 = m_refList.begin();
	for( ; it5 != m_refList.end(); ++it5 )
	{
		if ((*it5)->getPtr() == ptr) return *it5;
	}
	return 0;
}


ReferenceRep* Sheet::findRef( IMgaFCO* ptr)
{
	ReferenceRep_Iterator it( m_refList.begin());
	for( ; it != m_refList.end(); ++it )
	{
		if ((*it)->getPtr() == ptr) return *it;
	}
	return 0;

}


Any* Sheet::findAny( IMgaFCO* ptr)
{
	FolderRep_Iterator it5 = m_folderList.begin();
	for( ; it5 != m_folderList.end(); ++it5 )
	{
		if ((*it5)->getPtr() == ptr) return *it5;
	}

	AttributeRep_Iterator it4 = m_attributeList.begin();
	for( ; it4 != m_attributeList.end(); ++it4 )
	{
		if ((*it4)->getPtr() == ptr) return *it4;
	}

	return findFCO( ptr);
}


bool Sheet::isInRootFolder( Any * elem)
{
	return elem->isInRootFolder();
}


void Sheet::gatherNodes( NODE_VECTOR & nodes)
{
	nodes.insert( nodes.end(), m_fcoRepList.begin(), m_fcoRepList.end());
	nodes.insert( nodes.end(), m_atomList.begin(), m_atomList.end());
	nodes.insert( nodes.end(), m_modelList.begin(), m_modelList.end());
	nodes.insert( nodes.end(), m_connList.begin(), m_connList.end());
	nodes.insert( nodes.end(), m_setList.begin(), m_setList.end());
	nodes.insert( nodes.end(), m_refList.begin(), m_refList.end());

}


void Sheet::assignCliqueId( CLIQUE_VECTOR & clique_id, const NODE_VECTOR & nodes)
{
	unsigned int cl_id = 0;
	unsigned int len = nodes.size();

	for(unsigned int i = 0 ; i < len; ++i)
		clique_id.push_back(i+1); // assign a clique id to each element (starting from 1)
}


void Sheet::replaceCliqueId( CLIQUE_VECTOR & clique_id, unsigned int id1, unsigned int id2)
{
	unsigned int search_id = id1, replace_id = id2;
	if ( replace_id > search_id) // the replace value should be lower than the replacable
	{
		unsigned int storage = replace_id;
		replace_id = search_id;
		search_id = storage;
	}

	for (unsigned int k = 0; k < clique_id.size(); ++k)
		if ( clique_id[k] == search_id)
			clique_id[k] = replace_id;
}


unsigned int Sheet::howManyCliques( CLIQUE_VECTOR & clique_id)
{
	std::map<unsigned int,unsigned int> t_m;
	for (unsigned int k = 0; k < clique_id.size(); ++k)
	{
		unsigned int curr_id = clique_id[k];
		++t_m[curr_id];
	}
	unsigned int current_clique_id_max = 1;
	unsigned int val = 0;
	std::map<unsigned int,unsigned int>::iterator i = t_m.begin();
	for( ; i != t_m.end(); ++i)
	{
		// to count how many clique id's are used (there we have keys in the map)
		++val;

		// since map is ordered based on the keys ( = clique ids) we can
		// replace the clique ids with as low clique id as we want if
		// we start from the lower keys
		// old clique series may look like: 1, 2, 7, 41
		unsigned int old_id = i->first;
		if ( old_id != current_clique_id_max) // no need to replace the old values with the same value
			for (unsigned int j = 0; j < clique_id.size(); ++j)
				if ( clique_id[j] == old_id)
					clique_id[j] = current_clique_id_max;

		++current_clique_id_max;
	}
	// now the clique_ids will be sequential: 1,2,3,...
	return val;	
}


void Sheet::getChildren( unsigned int base, const NODE_VECTOR & nodes, UI_LIST & children, FCO::INHERITANCE_TYPE inh_type)
{
	for (unsigned int i = 0; i < nodes.size(); ++i)
		if ( edge(i, base, nodes, inh_type)) 
		{
			unsigned int j = 0;
			while( j < children.size() && children[j] != i)
				++j;
			if ( j == children.size()) 
				children.push_back( i);
		}
}

bool Sheet::multipleInheritance()
{
	FcoRep_Iterator it0( m_fcoRepList.begin());
	for( ; it0 != m_fcoRepList.end(); ++it0 )
	{
		(*it0)->multipleInheritanceStep1();
		(*it0)->multipleInheritanceStep2();
	}

	AtomRep_Iterator it1 = m_atomList.begin();
	for( ; it1 != m_atomList.end(); ++it1 )
	{
		(*it1)->multipleInheritanceStep1();
		(*it1)->multipleInheritanceStep2();
	}

	ModelRep_Iterator it2 = m_modelList.begin();
	for( ; it2 != m_modelList.end(); ++it2 )
	{
		(*it2)->multipleInheritanceStep1();
		(*it2)->multipleInheritanceStep2();
	}

	ConnectionRep_Iterator it3 = m_connList.begin();
	for( ; it3 != m_connList.end(); ++it3 )
	{
		(*it3)->multipleInheritanceStep1();
		(*it3)->multipleInheritanceStep2();
	}

	SetRep_Iterator it4 = m_setList.begin();
	for( ; it4 != m_setList.end(); ++it4 )
	{
		(*it4)->multipleInheritanceStep1();
		(*it4)->multipleInheritanceStep2();
	}

	ReferenceRep_Iterator it5 = m_refList.begin();
	for( ; it5 != m_refList.end(); ++it5 )
	{
		(*it5)->multipleInheritanceStep1();
		(*it5)->multipleInheritanceStep2();
	}
	return true;
}


void Sheet::vectorCopy( UI_LIST & target, const UI_LIST & source, UI_LIST & duplicates)
{
	for(unsigned int i = 0; i < source.size(); ++i)
	{
		unsigned int j = 0;
		while( j != target.size() && target[j] != source[i])
			++j;
		if ( j == target.size())
			target.push_back( source[i]);
		else
			duplicates.push_back( source[i]);
	}
}


bool Sheet::edge( unsigned int i, unsigned int j, const NODE_VECTOR & nodes, FCO::INHERITANCE_TYPE inh_type)
{
	return nodes[i]->hasParent( nodes[j], inh_type);
}


bool Sheet::doInheritance( FCO::INHERITANCE_TYPE inh_type)
{
	unsigned int i, j;
	std::map<unsigned int, unsigned int> depends_upon;
	CLIQUE_VECTOR clique_vec;
	NODE_VECTOR node_vec;

	gatherNodes( node_vec);

	assignCliqueId( clique_vec, node_vec);

	for( i = 0; i < node_vec.size(); ++i)
		for ( j = 0; j < node_vec.size(); ++j)
		{
			if ( edge(i,j, node_vec, inh_type))
			{
				++depends_upon[i];
				// replace all clique_id[j] clique ids with clique_id[i]
				if ( clique_vec[j] != clique_vec[i])
					replaceCliqueId( clique_vec, clique_vec[j], clique_vec[i]);
			}
		}
	// initially will contain the roots
	std::list<unsigned int> elements, elements_backup;
	std::vector<int> level( node_vec.size());
	for( int reset_i = 0; reset_i < node_vec.size(); ++reset_i)
		level[reset_i] = -1;

	
	std::vector<unsigned int> dupl_temp;

	m_numberOfCliques[ inh_type] = howManyCliques( clique_vec);

	for( i = 0; i < node_vec.size(); ++i)
		if (depends_upon[i]==0)
		{
			elements.push_back(i);
			level[i] = 0; // the roots are placed on "level 0"
		}

	if (elements.size() < m_numberOfCliques[ inh_type]) // because from each clique there must be at least 1 root
	{
		TO("Circle found in model");
		global_vars.err << "Circle found in model\n";
		//std::cout << "Circle\n";
		// based on that if in a clique there is no node with outgoing degree of 0
		// then that (directed) clique contains a (directed) circle
		return false;
	}

	std::map< unsigned int, std::vector<unsigned int> > ancestors;
	std::map< unsigned int, std::vector<unsigned int> > descendants;

	bool loop = false;
	
	elements_backup = elements;

	while ( !elements.empty() && !loop)
	{
		// taking new descendants of current elements in the list
		unsigned int base = *elements.begin();
		elements.pop_front();

		// children of base
		std::vector<unsigned int> children;
		getChildren( base, node_vec, children, inh_type);
		for( j = 0; j < children.size(); ++j)
		{
			unsigned int child = children[j];
			elements.push_back( child);

			if (ancestors[child].end() == 
					std::find(ancestors[child].begin(), ancestors[child].end(), base))
				ancestors[child].push_back(base); // insert if not present

			vectorCopy( ancestors[child], ancestors[base], dupl_temp);
			for ( unsigned int k = 0; k < ancestors[child].size(); ++k)
				if ( edge( ancestors[child][k], child, node_vec, inh_type))
				{
					FCO * fco1 = node_vec[ancestors[child][k]];
					FCO * fco2 = node_vec[child];
					TO("Loop between " + fco1->getName() + " and " + fco2->getName());
					global_vars.err << "Loop between " << fco1->getName() << " and " << fco2->getName() << "\n";
					//std::cout << "Loop between " << ancestors[child][k] << " and " << child << "\n";
					loop = true;

					return false;
				}
		}
	}

	/*Level calculation*/
	// this cycle will determine the level elements are staying on
	loop = false;
	while ( !elements_backup.empty() && !loop)
	{
		// taking new descendants of current elements in the list
		unsigned int base = *elements_backup.begin(); 
		elements_backup.pop_front();
	
		// children of base
		std::vector<unsigned int> children;
		getChildren( base, node_vec, children, inh_type);
		for( j = 0; j < children.size(); ++j)
		{
			unsigned int child = children[j];
			elements_backup.push_back( child);

			/*if ( level[child] == -1) level[child] = level[base] + 1;
			else*/ if ( level[child] < level[base] + 1) level[child] = level[base] + 1;
		}
	}

	// using the ancestors database build up the m_desc and m_anc fields of each fco
	//for( i = 0; i < elements.size(); ++i)
	std::map< unsigned int, std::vector<unsigned int> >::iterator anc_it = ancestors.begin();
	for( ; anc_it != ancestors.end(); ++anc_it)
	{
		unsigned int id = anc_it->first;
		std::vector<unsigned int> & ancestors_of_id = anc_it->second;
		
		//for ( unsigned int k = 0; k < ancestors[i].size(); ++k)
		for( unsigned int k = 0; k < ancestors_of_id.size(); ++k)
		{
			// ancestor[i][k] is ancestor of i
			//std::string m1 = node_vec[ancestors_of_id[k]]->getName() + " anc of " + node_vec[id]->getName();
			//TO( m1);
			
			/*unsigned int l = 0;
			while( l < descendants[ancestors_of_id[k]].size() && descendants[ancestors_of_id[k]][l] != id)
				++l;
			if ( l == descendants[ancestors_of_id[k]].size())*/
			if ( std::find( descendants[ancestors_of_id[k]].begin(), descendants[ancestors_of_id[k]].end(), id) ==
				descendants[ancestors_of_id[k]].end()) // not found then insert
			{
				descendants[ancestors_of_id[k]].push_back(id);
				//std::string m1 = node_vec[ancestors_of_id[k]]->getName() + " has desc " + node_vec[id]->getName();
			//TO( m1);
			}
		}
	}

	//for( i = 0; i < elements.size(); ++i)
	for( i = 0; i < node_vec.size(); ++i)
	{
		//std::string mmma, mmmd, mmm;
		std::vector< FCO*> anc_list, desc_list;
		for ( unsigned int k = 0; k < ancestors[i].size(); ++k)
		{
			anc_list.push_back( node_vec[ancestors[i][k]]);
			//mmma += node_vec[ancestors[i][k]]->getName() + " ";
		}

		for ( unsigned int l = 0; l < descendants[i].size(); ++l)
		{
			desc_list.push_back( node_vec[descendants[i][l]]);
			//mmmd += node_vec[descendants[i][l]]->getName() + " ";
		}
		//mmm = node_vec[i]->getName() + std::string( (inh_type==FCO::INTERFACE)?" INTERFACE":(inh_type==FCO::IMPLEMENTATION)?" IMPLEMENTATION":" OTHER");
		//TO ( mmm + "\nanc:\n" + mmma + "\ndesc:\n" + mmmd);
		node_vec[i]->setAncestors( inh_type, anc_list);
		node_vec[i]->setDescendants( inh_type, desc_list);
		node_vec[i]->setLevel( inh_type, level[i]);
		node_vec[i]->setCliqueId( inh_type, clique_vec[i]);
	}
	return true;
}

std::vector< FCO *> Sheet::sortBasedOnLevels()
{
	// since the regular inheritance is splitted to interface and implementation inheritance and
	// inheritance loops are possible if these two are combined
	// this ordering process may not be successful
	//FCO::INHERITANCE_TYPE curr_type = INTERFACE;
	std::vector< FCO *> res;
	order( FCO::INTERFACE, res);
	bool good = check( FCO::IMPLEMENTATION, res);
	if (!good)
	{
		res.clear(); // start from the beginning
		order( FCO::IMPLEMENTATION, res);
		good = check( FCO::INTERFACE, res);
		if (!good) global_vars.err << "Cannot establish an order which would be good for both IMPLEMENTATION and INTERFACE hierarchy\n";
	}
	return res;
}


void Sheet::order( FCO::INHERITANCE_TYPE type, std::vector<FCO *>& res)
{
	// ordering of cliques based on how many models they contain
	// the key = clique_id is unique
	// the value = how many models the clique contains
	std::map< unsigned int, unsigned int> how_many_models_in_clique;

	// important init step: there will be cliques with no models, so the following step
	// will overwrite the values for the cliques (the keys) the models are part of
	for( int clique_index0 = 1; clique_index0 <= m_numberOfCliques[ type]; ++clique_index0)
		how_many_models_in_clique[ clique_index0] = 0;

	ModelRep_Iterator itm = m_modelList.begin();
	for( ; itm != m_modelList.end(); ++itm )
		++how_many_models_in_clique[ (*itm)->getCliqueId( type)];

	// a map containing the number of models as a key, and the list of cliqueid-s 
	// containing that amount of models
	std::map<unsigned int, std::list<unsigned int> > how_many_inverse;
	std::map<unsigned int,unsigned int>::iterator hmmic_ind = how_many_models_in_clique.begin();
	for( ; hmmic_ind != how_many_models_in_clique.end(); ++hmmic_ind)
		how_many_inverse[ hmmic_ind->second].push_back( hmmic_ind->first);
	// we have and ascending order of cliques based on the number of models contained

	std::map<unsigned int, std::list<unsigned int> >::reverse_iterator hminv_ind = how_many_inverse.rbegin();
	//for( int clique_index = 1; clique_index <= m_numberOfCliques; ++clique_index)
	for( ; hminv_ind != how_many_inverse.rend(); ++hminv_ind)
	{
		std::list<unsigned int>::iterator cliquelist_ind = hminv_ind->second.begin();
		for( ; cliquelist_ind != hminv_ind->second.end(); ++cliquelist_ind)
		{
			unsigned int clique_index = *cliquelist_ind;
			int curr_level = 0;
			bool more = true;
			while ( more)
			{
				int len_before = res.size();
				{
					ModelRep_Iterator it2 = m_modelList.begin();
					for( ; it2 != m_modelList.end(); ++it2 )
						if ( (*it2)->getCliqueId( type) == clique_index && (*it2)->getLevel( type) == curr_level)
							res.push_back( *it2);
				}
				{
					FcoRep_Iterator it0( m_fcoRepList.begin());
					for( ; it0 != m_fcoRepList.end(); ++it0 )
						if ( (*it0)->getCliqueId( type) == clique_index && (*it0)->getLevel( type) == curr_level)
							res.push_back( *it0);
				}
				{
					AtomRep_Iterator it1 = m_atomList.begin();
					for( ; it1 != m_atomList.end(); ++it1 )
						if ( (*it1)->getCliqueId( type) == clique_index && (*it1)->getLevel( type) == curr_level)
							res.push_back( *it1);
				}
				{
					ReferenceRep_Iterator it5 = m_refList.begin();
					for( ; it5 != m_refList.end(); ++it5 )
						if ( (*it5)->getCliqueId( type) == clique_index && (*it5)->getLevel( type) == curr_level)
							res.push_back( *it5);
				}
				{
					ConnectionRep_Iterator it3 = m_connList.begin();
					for( ; it3 != m_connList.end(); ++it3 )
						if ( (*it3)->getCliqueId( type) == clique_index && (*it3)->getLevel( type) == curr_level)
							res.push_back( *it3);
				}
				{
					SetRep_Iterator it4 = m_setList.begin();
					for( ; it4 != m_setList.end(); ++it4 )
						if ( (*it4)->getCliqueId( type) == clique_index && (*it4)->getLevel( type) == curr_level)
							res.push_back( *it4);
				}

				++curr_level;
				more = ( len_before != res.size());
			}
		}
	}
}


bool Sheet::check( FCO::INHERITANCE_TYPE type, std::vector<FCO*>& res)
{
	// it will store the currently reached maximum level (the lowest level in
	// the inheritance tree) per each clique
	std::map< int, int> m_maxLevelPerClique;

	std::vector<FCO*>::iterator it = res.begin();
	for( ; it != res.end(); ++it)
	{
		int curr_level = (*it)->getLevel( type);
		int curr_clique = (*it)->getCliqueId( type);

		if( m_maxLevelPerClique.find( curr_clique) == m_maxLevelPerClique.end()) // not existing yet
			m_maxLevelPerClique[ curr_clique ] = curr_level;
		else // check if the current max level is less then the level found at *it
		{
			if( curr_level < m_maxLevelPerClique[ curr_clique]) // an ancestor is after a descendant in the ordering
				return false; // not a good ordering from 'type' point of view
		}
	}
	return true;
}

--- NEW FILE: RoleRep.h ---
#ifndef ROLEREP_H
#define ROLEREP_H

class ConnectionRep;
class ConnJoint;
class ModelRep;
class SetRep;
class AtomRep;
class ReferenceRep;
class FCO;

#include "string"
#include "list"
#include "vector"

class StringLex
{
public:
	bool operator()( const std::string& peer1, const std::string& peer2) const;
};


class RoleRep {

public:

	typedef std::vector<RoleRep> RoleRepSeries;
	typedef RoleRepSeries::iterator RoleRepSeries_Iterator;
	typedef RoleRepSeries::const_iterator RoleRepSeries_ConstIterator;

	RoleRep( 
		const std::string &role_name,
		FCO* ptr, 
		ModelRep* model_ptr,
		bool is_port,
		const std::string &cardinality,
		bool inh_role,
		bool long_form);

	RoleRep( const RoleRep & peer) ;
	const RoleRep& operator=( const RoleRep & peer); 
	bool operator==( const RoleRep& peer) const;
	bool operator!=( const RoleRep& peer) const;
	
	friend bool operator<(const RoleRep&, const RoleRep&);
	//bool operator<(const RoleRep& peer) const;

	const std::string& getOnlyRoleName() const;
	std::string getSmartRoleName() const;

	FCO * getFCOPtr() const;
	ModelRep * getModelRepPtr() const;
	bool isPort() const;
	const std::string& getCardinality() const;

	void setInheritedRole( bool val);
	bool isInheritedRole() const;

	void setLongForm( bool val);
	bool isLongForm() const;

private:
	std::string m_roleName;
	FCO* m_ptr;
	ModelRep * m_model;
	bool m_isPort;
	std::string m_cardinality;

	// shows if a role is inherited from an ancestor
	// M<>----r-B
	//          |
	//          D
	bool m_inheritedRole;

	// in the case above for B the short role name form of "r" cannot be used
	// because it can be confusing. It refers to a B or a D?
	// so in such cases the long form is to be used: Br, Dr
	bool m_longForm;

};
#endif //ROLEREP_H

--- NEW FILE: Dumper.h ---
#ifndef DUMPER_H
#define DUMPER_H

#include "list"
#include "vector"
#include "Sheet.h"

class Dumper : public Sheet {
public:
	static const char* m_strBonExtenderOptions;
	static const char* Yes_Str;
	static const char* Only_Str;
	static const char* No_Str;
	static const char* m_strGenVisitor;
	static const char* m_strVisitorSignature;
	static const char* m_strGenInitMethod;
	static const char* m_strGenFiniMethod;
	static const char* m_strGenAcceptWithTraversal;
	static const char* m_strGenAcceptSpecialized;
	static const char* m_strSpecAcceptRetVal;
	static const char* m_strVCVersion6;
	static const char* m_strTemplateGetter;
	static const char* m_strOutputInSeparateFile;
	static const char* m_strTgtNamespace;
protected:
	Dumper();

public:
	static Sheet * getInstance();
	virtual ~Dumper();

	bool build();

	static int selectOutputFiles( const std::string& proj_name, CComPtr<IMgaRegNode> optionsRegnode);
	static int backup( const std::string& file_name);
	static void getGlobalUserParts( std::string& up1, std::string& up2);

	static std::string xmlFilter( const std::string& in);

	static bool m_bParsePrev;
	static bool m_bGenInit;
	static bool m_bGenFinalize;
	static bool m_bGenAcceptTrave;
	static bool m_bGenAcceptSpeci;
	static bool m_bGenTemplates;
	static bool m_bGenTemplVersion6;
	static bool m_bGenRegular;
	static int  m_iVisitSign;
	static int  m_iSpecAcceptRetVal;
	static bool m_bGenVisitor;
	static bool m_bSafetyBackup;

protected:

	void inheritMoReSeCoFolAsp();

	void showMultipleInheritance();

	void selConf( std::vector<FCO*>& s);

	void createMethods();
	void dumpGlobals( std::vector<FCO*>& s);
	void dumpGlobalMOF();
	void dumpMain( std::vector<FCO*>& s);
	void doDump();
	void initOutFiles( std::vector<FCO*>& s, std::string& resu);
	void finiOutFiles( std::vector<FCO*>& s);

	bool checkAll();
	bool checkAllFCOs();
	bool checkOrphanAttributes();
	bool findInFolders( FCO * fco);

	std::string getNamespaceName();

protected:
	void fetchConfigurationNames( std::vector< std::string>& res);

};


#endif //DUMPER_H

--- NEW FILE: Any.cpp ---
#include "stdafx.h"
#include "myutil.h"
#include "Any.h"
#include "CodeGen.h"
#include "Method.h"
#include "Dumper.h"
#include "MakeVisitor.h"

#include <algorithm>
#include <strstream>

#include "globals.h"
extern Globals global_vars;

/*static*/ const std::string Any::m_startUPToken = "///BUP";
/*static*/ const std::string Any::m_endUPToken   = "///EUP";
/*static*/ const std::string Any::NamespaceDispSeparatorBeg_str = "_";
/*static*/ const std::string Any::NamespaceDispSeparatorEnd_str = "_";
/*static*/ const std::string Any::NamespaceDelimiter_str = "::";
/*static*/ const std::string Any::InRootFolder_str = "InRootFolder";
/*static*/ const std::string Any::NameSelectorNode_str = "myNameIs"; 
/*static*/ const std::string Any::MOFException_str = "MOFException";
/*static*/ const std::string Any::MOFOperation_str = "MOFOperation";
/*static*/ const std::string Any::MOFEnumeration_str = "MOFEnumeration";
/*static*/ const std::string Any::MOFStructure_str = "MOFStructure";
/*static*/ const std::string Any::MOFAlias_str = "MOFAlias";

/*static*/ const std::string Any::MOFStart_str = "MOF section begins";
/*static*/ const std::string Any::MOFEnd_str   = "MOF section ends";



bool AnyLexicographicSort::operator()( Any * op1, Any * op2) const
{
	std::string s1 = op1->getName();
	std::string s2 = op2->getName();
	int k = s1.compare(s2);

	return ( k < 0);
}

/*
These names must be valid BON2 class names (with the BON:: tag) so beware when changing it
*/
/*static*/ const std::string Any::KIND_TYPE_STR[] =
{
	"Atom",
	"Model",
	"Connection",
	"Set",
	"Reference",
	"FCO",
	"ASPECT",
	"Folder",
	"CONSTRAINT",
	"CONSTRAINFUNC",
	"ATTRIBUTE"
};


Any::Any( IMgaFCO* ptr)
		: m_ptr( ptr)
		, m_isInRootFolder( false)
		, m_equivs()
		, m_toEx( true)
		, m_globalHeader()
		, m_globalSource()
{
}


Any::~Any()
{ 
	m_equivs.clear();
}

void Any::initNamespace()
{
	// decide which namespace the object belongs to:
	if( Util::islibobj( m_ptr))
	{
		bool all_equivs_in_lib = true;
		for ( EquivSet_ConstIterator it = m_equivs.begin()
			; all_equivs_in_lib && it != m_equivs.end()
			; ++it)
		{
			if ( *it == m_ptr) continue;
			// --applicable to non proxies only--
			if ( Util::isproxy( *it)) continue;//ignore proxies (from m_equivs) when determining namespace
			all_equivs_in_lib = Util::islibobj( *it);
		}

		if( !all_equivs_in_lib) // it has equivs in the host project
			resetNamespace();   // so needs to be in the main namespace
		else
		{
			// find the Namespace value from the namespace holding rootfolder
			// in case of nested libs m_libRootFolder and m_nmspRootFolder are !equal
			std::string nm_val = Util::getReg( m_nmspRootFolder, "Namespace");

			if( nm_val.length() > 0) m_namespace = nm_val;
			else                     m_namespace = ""; // TODO
			//m_respPointer could be in another library then m_ptr, so the namespace could be different
		}
	}
	else // regular object, init its namespace value from the project's value
	{
		resetNamespace();
	}
}

void Any::resetNamespace()
{
	m_namespace = Dumper::getInstance()->getNamespace();
}

// applicable for folders only
void Any::initAttributes()
{
	// for folders the default value (from the meta) true
	// for fcos    the default value (from the meta) false

	m_isInRootFolder = Util::getBoolAttr( m_ptr, InRootFolder_str);
	// try to find one among the equivalent classes which is in the root folder
	EquivSet_ConstIterator it = m_equivs.begin();
	for ( ; !m_isInRootFolder && it != m_equivs.end(); ++it)
	{
		if ( *it == m_ptr) continue;
		// --applicable to non proxies only--
		if ( Util::isproxy( *it)) continue;// folderproxies don't have attributes
		m_isInRootFolder = m_isInRootFolder || Util::getBoolAttr( *it, InRootFolder_str);
	}
}


bool Any::isInRootFolder()
{
	return m_isInRootFolder;
}

bool Any::isToBeEx() const
{
	return m_toEx;
}


void Any::toBeEx( bool t)
{
	m_toEx = t;
}


bool Any::isFCO() const
{
	bool fco = false;
	fco = (getMyKind() == ATOM ||
		getMyKind() == MODEL ||
		getMyKind() == CONN ||
		getMyKind() == SET ||
		getMyKind() == REF ||
		getMyKind() == FCO_REP);
	return fco;
}


std::string Any::getName() const
{
	if ( this->m_ptr)
	{
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return Util::Copy( nm);
	}
	return "NullPtrError";
}


std::string Any::getValidName() const
{
	if ( this->m_ptr)
	{
		std::string nm = getName();
		Any::convertToValidName( nm);
		return nm;
	}
	return "NullPtrError";
}

std::string Any::getStrictNmspc() const
{
	return m_namespace.empty()?"": m_namespace;
}

std::string Any::getLStrictNmspc() const
{
	return m_namespace.empty()?"": (m_namespace + Any::NamespaceDelimiter_str);
}

std::string Any::getNmspc() const
{
	// will return global_vars.m_namespace_name if m_namespace empty
	// i.e. "meta5_BON" or "NSP"
	return m_namespace.empty()?global_vars.m_namespace_name: m_namespace;
}

std::string Any::getLNmspc() const
{
	std::string t = getNmspc();
	Any::convertToValidName( t);
	return t + Any::NamespaceDelimiter_str;
}

std::string Any::getValidNmspc() const
{
	// returns "_meta5_1"  validated form of "1meta5.1"
	std::string t = getNmspc();
	Any::convertToValidName( t);
	return t;
}

std::string Any::getLStrictName() const
{
	return getLStrictNmspc() + getName();
}

std::string Any::getLName() const
{
	return getLNmspc() + getName();
}

std::string Any::getLValidNmspc() const
{
	std::string t = getValidNmspc();
	return t.empty()?"": t + Any::NamespaceDelimiter_str;
}

std::string Any::getLValidName() const
{
	return getLValidNmspc() + getValidName();
}

std::string Any::getValidNameImpl() const
{
	return getValidName() + "Impl";
}

std::string Any::getLValidNameImpl() const
{
	return getLValidNmspc() + getValidNameImpl();
}

std::string Any::getMyKindStr() const
{
	if ( isFCO() || getMyKind() == FOLDER)
		return KIND_TYPE_STR[ getMyKind()];

	throw "Error: inquireing getMyKindStr for non-fco, non-folder";
}


/*static*/ void Any::convertToValidName( std::string & p)
{
	for(int i = 0; i < p.length(); ++i)
		if( (p[i]>='a' && p[i]<='z') ||
				(p[i]>='A' && p[i]<='Z') ||
				(p[i]>='0' && p[i]<='9') ||
				(p[i]=='_'))
		{}
		else
			p[i]= '_';

	if (p[0]>='0' && p[0]<='9')
		p = '_' + p;
}


/*static*/ bool Any::checkIfValidName( const std::string & p)
{
	std::strstream error_msg;

	bool more_than_one = false;
	bool good = true;
	if (( p[0] >='a' && p[0]<='z')
		|| ( p[0] >='A' && p[0]<='Z')
		|| ( p[0] == '_'))
		{} 
	else
	{
		good = false;
		//global_vars.err << "Error in " << p << " at index 0\n";
		error_msg << "0";
		more_than_one = true;
	}
		
	for(int i = 1; i < p.length(); ++i)
	{
		if( (p[i]>='a' && p[i]<='z') ||
				(p[i]>='A' && p[i]<='Z') ||
				(p[i]>='0' && p[i]<='9') ||
				(p[i]=='_'))
		{}
		else
		{
			good = false;
			//global_vars.err << "Error in " << p << " at index " << i << "\n";
			if (more_than_one) error_msg << ", ";
			error_msg << i;

			if (!more_than_one) 
				more_than_one = true;
		}
	}
	error_msg << std::ends;
	std::string error_str ( error_msg.str());
	/*if ( !error_str.empty())
		global_vars.err << "Error in " << p << " at index "<< error_str << ".\n";*/
	return good;
}


std::string Any::getMyPrefix( int which /* = 0*/) const
{
	if ( this->m_ptr)
	{
		std::string kind = Util::kind( m_ptr);
		std::string name = Util::composePath( m_ptr);

		long relid = 0;
		COMTHROW( m_ptr->get_RelID(&relid));
		char t[16];
		sprintf( t, "%x", relid);

		ASSERT( name.length() >= 0);
		std::string tmp = name + '-' + t + '-' + kind;
		
		if( which) // in case when special metainterpreter registry is needed
			return tmp;
		return "BonExtender/" + tmp;
	}
	throw "Error: inquiring prefix for a null object\n";
}


CComPtr<IMgaRegNode> Any::getMyRegistry() const
{
	CComPtr<IMgaRegNode> rn;
	if ( this->m_ptr && this->m_parentFolder)
	{
		COMTHROW( m_parentFolder->get_RegistryNode( Util::Copy( getMyPrefix()), &rn));
		return rn;
	}

	throw 1;
}

CComPtr<IMgaRegNode> Any::getMIRegistry() const // the metainterpreter registry
{
	CComPtr<IMgaRegNode> rn;
	if ( this->m_ptr && this->m_parentFolder)
	{
		COMTHROW( m_parentFolder->get_RegistryNode( Util::Copy( getMyPrefix( 1)), &rn));
		return rn;
	}

	throw 1;
}

void Any::prepareMacros()
{
	std::string h, s, n = getValidNmspc();
	int c = (n.length() < 15) ? 15-n.length():(
	        (n.length() < 30) ? 30-n.length():(
	        (n.length() < 45) ? 45-n.length():(
			0
	)));

	//h = "class " + getValidNameImpl() + ";\n"; removed on 5/6/2004 not needed
	h  = "namespace " + n + " { " + std::string( c, ' ');
	h += "DECLARE_BONEXTENSION( BON::" + getMyKindStr() + ", " + getValidNameImpl() + ", " + getValidName()	+ " ); }\n";
	//h = "DECLARE_BONEXTENSION( BON::" + getMyKindStr() + ", " + getValidNameImpl() + ", " + getValidName()	+ " );\n";

	//s = "IMPLEMENT_BONEXTENSION( " + global_vars.m_namespace_name + "::" + getValidName() + ", \"" + getNmspc() + "::" + getName() + "\" );\n";
	s = "IMPLEMENT_BONEXTENSION( " + getValidNmspc() + Any::NamespaceDelimiter_str + getValidName() + ", \"" + getLStrictNmspc() + getName() + "\" );\n";

	m_globalSource += s;
	m_globalHeader += h;
}


void Any::prepareIniFin()
{
	Method i;

	i.m_container = this;
	i.m_virtual = true;
	i.m_returnValue = "void";
	i.m_signature = "initialize() { }";
	i.m_implementation = "";
	i.m_comment = "";


	if ( Dumper::m_bGenInit)		m_inifinMethods.push_back( i);

	i.m_signature = "finalize() { }";

	if ( Dumper::m_bGenFinalize)	m_inifinMethods.push_back( i);

	// Dumper::m_bGenAcceptTrave: 0 1 0 1 
	// Dumper::m_bGenAcceptSpeci: 0 0 1 1
	// 0, 0: none
	// 1, 0: builtin visitor style with traversal 
	// 0, 1: special visitor style without traversal
	// 1, 1: special visitor style with traversal
	createAcceptMethod( Dumper::m_bGenAcceptTrave, Dumper::m_bGenAcceptSpeci, Dumper::m_iSpecAcceptRetVal == 1);

	//if ( getMyKind() != FCO_REP && Dumper::m_bGenAcceptTrave)
	//{
	//	m_inifinMethods.push_back( this->createAcceptMethod());
	//}
	//if ( Dumper::m_bGenAcceptSpeci)
	//{
	//	m_inifinMethods.push_back( this->createSpecAcceptMethod());
	//}
}

void Any::createAcceptMethod( bool pWithTraversalOfKids, bool pSpecialized, bool pRetValBool)
{
	Method m = CodeGen::acceptMethod( this, pWithTraversalOfKids, pSpecialized, pRetValBool);
	if( pSpecialized || getMyKind() != FCO_REP) // there is no such thing that visitFCO in the built in BON::Visitor
		m_inifinMethods.push_back( m);
}

/*static*/ std::string Any::parseMOFException( const std::string& exc_str)
{
	if( exc_str.empty()) return "";

	std::string ind0 = std::string( 2 - 1, '\t'), ind = std::string( 2, '\t'), more_ind = std::string( 2 + 1, '\t');

	std::string res, ctor_signature, ctor_inilist, ctor_body, class_body, name;
	unsigned int beg = 0, nwl = exc_str.find('\n');
	name = exc_str.substr(0, nwl);

	while( nwl != std::string::npos)
	{
		beg = nwl + 1;
		nwl = exc_str.find('\n', beg);
		
		if( nwl > beg && beg < exc_str.length() - 1)
		{
			std::string par_line = exc_str.substr( beg, nwl - beg);
			int type_end = par_line.find('\t');
			std::string par_type, par_name;
			par_type = par_line.substr(0, type_end);
			par_name = par_line.substr( type_end + 1);

			if( ctor_signature.empty()) ctor_signature = "\n" + more_ind + "( ";
			else ctor_signature += "\n" + more_ind + ", ";
			
			if( ctor_body.empty()) ctor_body = "\n" + more_ind + ": ";
			else ctor_body += "\n" + more_ind + ", ";
			
			ctor_signature += par_type + " p_" + par_name;
			ctor_body += par_name + "( p_" + par_name + ")";
			class_body += "\n" + ind + par_type + " " + par_name + ";";
		}
	}

	if( name == exc_str) //no members
	{
		res = ind0 + "class " + name + "{ };\n";
	}
	else
	{
		ctor_signature = "\n" + ind + "// constructor\n" + ind + name + ctor_signature + "\n" + more_ind + ")";
		ctor_body += "\n" + ind + "{ }";
		class_body = "\n" + ind + "// members\n" + class_body;
		res = ind0 + "class " + name + "\n" + ind0 + "{\n" + ind0 + "public:\n"  + ctor_signature + ctor_body + "\n" + class_body + "\n" + ind0 + "};\n";
	}
	return res;
}


/*static*/ std::string Any::parseMOFOperation( const std::string& exc_str)
{
	if( exc_str.empty()) return "";

	std::string ind0 = std::string( 2 - 1, '\t'), ind = std::string( 2, '\t');

	std::string res, tabulated_exc_str;
	for( unsigned int i = 0; i < exc_str.length(); ++i)
	{
		tabulated_exc_str += exc_str[i];
		if( exc_str[i] == '\n') // covers simple '\n' and '\r\n' case as well
			tabulated_exc_str += ind;
	}
	res = ind0 + tabulated_exc_str;
	if( exc_str.length() > 0 && exc_str[ exc_str.length() - 1 ] != '\n') res += '\n';
	return res;
}


/*static*/ std::string Any::processMOFNode( const CComPtr<IMgaRegNode> rn, int ind_num)
{
	try {
		// put the regnodes into a map, the key will be the node's name, thus ordering is provided
		std::map< std::string, CComPtr<IMgaRegNode>, StringLex> aliases, enums, exceptions, operations, structures;
		std::map< std::string, CComPtr<IMgaRegNode>, StringLex>::iterator iter;
		CComPtr<IMgaRegNodes> rns;
		COMTHROW( rn->get_SubNodes( VARIANT_TRUE, &rns));// inquire all children
		
		long c = 0;
		if( rns) COMTHROW( rns->get_Count( &c));

		for( long i = 1; i <= c; ++i)
		{
			CComPtr<IMgaRegNode> item;
			COMTHROW( rns->get_Item( i, &item));

			CComBSTR bnm;
			COMTHROW( item->get_Name( &bnm));
			std::string nm = Util::Copy( bnm);
			if( Any::MOFAlias_str.compare( nm.substr( 0, Any::MOFAlias_str.length())) == 0 ) aliases[nm] = item;
			else if( Any::MOFEnumeration_str.compare( nm.substr( 0, Any::MOFEnumeration_str.length())) == 0) enums[nm] = item;
			else if( Any::MOFException_str.compare( nm.substr( 0, Any::MOFException_str.length())) == 0) exceptions[nm] = item;
			else if( Any::MOFOperation_str.compare( nm.substr( 0, Any::MOFOperation_str.length())) == 0) operations[nm] = item;
			else if( Any::MOFStructure_str.compare( nm.substr( 0, Any::MOFStructure_str.length())) == 0) structures[nm] = item;
		}

		std::string mof;

		// aliases first
		for( iter = aliases.begin(); iter != aliases.end(); ++iter)
		{
			CComBSTR val;
			COMTHROW( iter->second->get_Value( &val));
			mof += parseMOFOperation( Util::Copy( val)) + "\n";
		}

		// then enums
		for( iter = enums.begin(); iter != enums.end(); ++iter)
		{
			CComBSTR val;
			COMTHROW( iter->second->get_Value( &val));
			mof += parseMOFOperation( Util::Copy( val)) + "\n";
		}

		// structures
		for( iter = structures.begin(); iter != structures.end(); ++iter)
		{
			CComBSTR val;
			COMTHROW( iter->second->get_Value( &val));
			mof += parseMOFOperation( Util::Copy( val)) + "\n";
		}

		// exceptions
		for( iter = exceptions.begin(); iter != exceptions.end(); ++iter)
		{
			CComBSTR val;
			COMTHROW( iter->second->get_Value( &val));
			mof += parseMOFException( Util::Copy( val)) + "\n";
		}

		// operations
		for( iter = operations.begin(); iter != operations.end(); ++iter)
		{
			CComBSTR val;
			COMTHROW( iter->second->get_Value( &val));
			mof += parseMOFOperation( Util::Copy( val)) + "\n";
		}

		return mof;
	} catch( ...) {
		global_vars.err << MSG_ERROR << "Some error occurred during MOF parsing.\n";
		return "";
	}
}


void Any::prepareMOF()
{
	CComPtr<IMgaRegNodes> rns;
	COMTHROW( m_ptr->get_Registry( VARIANT_TRUE, &rns));

	long c = 0;
	if( rns) COMTHROW( rns->get_Count( &c));

	for( long i = 1; i <= c; ++i)
	{
		CComPtr<IMgaRegNode> item;
		COMTHROW( rns->get_Item( i, &item));

		m_sectionMOF += Any::processMOFNode( item);
	}

	EquivSet_ConstIterator it = m_equivs.begin();
	for ( ; it != m_equivs.end(); ++it)
	{
		if( m_ptr == *it) continue;

		//m_sectionMOF += Any::processMOFNode( rn);
		CComPtr<IMgaRegNodes> subnodes;
		COMTHROW( (*it)->get_Registry( VARIANT_TRUE, &subnodes));

		long d = 0;
		if( rns) COMTHROW( subnodes->get_Count( &d));

		for( long i = 1; i <= d; ++i)
		{
			CComPtr<IMgaRegNode> item;
			COMTHROW( subnodes->get_Item( i, &item));

			m_sectionMOF += Any::processMOFNode( item);
		}

	}

	//CComPtr<IMgaRegNode> my_rn	= m_ptr->getRegistry();
	//if( my_rn)
	//	m_sectionMOF = Any::processMOFNode( my_rn);

	//EquivSet_ConstIterator it = m_equivs.begin();
	//for ( ; it != m_equivs.end(); ++it)
	//{
	//	if( m_ptr == *it) continue;

	//	CComPtr<IMgaRegNode> rn = (*it)->getRegistry();
	//	if( rn)
	//		m_sectionMOF += Any::processMOFNode( rn);
	//}
}


void Any::prepare()
{
	prepareMacros();
	prepareIniFin();
#if(DO_MOF)
	prepareMOF();
#endif
}


void Any::dumpGlobals()
{
	DMP_S( m_globalSource);
	DMP_H( m_globalHeader);
}


std::string Any::dumpOrnament( bool is_abstract/* = false*/)
{
	std::string row;
	row = "//   C  L  A  S  S   " + getValidNameImpl() + "\n";//(is_abstract?" abstract":"") + " class\n";

	const std::string orn = "//*******************************************************************\n";
	
	return orn + row + orn;
}


void Any::dumpPre( std::string & h_file, std::string & c_file)
{
	// namespace opened in h and cpp files
	h_file += "namespace " + getValidNmspc() + "\n{\n";
	//c_file += "namespace " + getValidNmspc() + "\n{\n";

	h_file += dumpOrnament();
	h_file += "class " + getValidNameImpl();
	h_file += dumpClassHeader() + "{\npublic:\n";

	for( unsigned int k = 0; k < m_inifinMethods.size(); ++k)
	{
		h_file += m_inifinMethods[k].getHeader() + "\n";
		c_file += m_inifinMethods[k].getSource();
	}
}


void Any::dumpPost( std::string & h_file, std::string & c_file)
{
	h_file += "\n" + CodeGen::indent(1) + m_startUPToken + "\n" + getUserPart() + CodeGen::indent(1) +  m_endUPToken+ "\n";
	
	if( !m_sectionMOF.empty())
	{
		h_file += "\n// " + Any::MOFStart_str + "\n";
		h_file += "public:\n" + m_sectionMOF + "\n";
		h_file += "// " + Any::MOFEnd_str + "\n\n";
	}
	
	//h_file += "};\n\n\n"; 
	// namespace closed in h and cpp file
	h_file += "}; // class\n";
	h_file += "}  // namespace\n";
	h_file += "\n\n";
	//c_file += "}; // nmspc\n";
}


std::string Any::dumpClassHeader()
{
	// the place of ":" plays important role in identifying where class definitions start really
	// to prevent confusing with predefinitions like "class X;"
	// the canonical form is "class X :"
	return " :\n\t  public BON::" + getMyKindStr() + "Impl\n";
	//return " :\n  public /*Ex*/ BON::" + getMyKindStr() + "Impl\n";
}


std::string Any::getUserPart()
{
	std::ifstream old_xmp_file;
	std::string old_f_name;
	old_f_name = global_vars.header_backup_name;
	if ( old_f_name.empty()) // means that no previous version existed or the user selected not to parse the old file
		return CodeGen::indent(1) + "// add your own members here\n";

	old_xmp_file.open( old_f_name.c_str() ,std::ios_base::in);
	if ( !old_xmp_file.is_open())
		return CodeGen::indent(1) + "// ERROR accessing file\n";

	std::string up, line;
	while( !old_xmp_file.eof() && line.find( "class " + getValidNameImpl() + " :") == std::string::npos)
	{
		std::getline( old_xmp_file, line);
	}
	if ( !old_xmp_file.eof()) // found the class
	{
		while( !old_xmp_file.eof() && line.find( m_startUPToken) == std::string::npos) 
		{
			std::getline( old_xmp_file, line);
		}
		if ( !old_xmp_file.eof()) // found the start token
		{
			std::getline( old_xmp_file, line);
			while( !old_xmp_file.eof() && line.find( m_endUPToken) == std::string::npos) 
			{
				up += line + "\n";
				std::getline( old_xmp_file, line);
			}
			if ( !old_xmp_file.eof()) // found the end token
			{
			}
			else
			{
				old_xmp_file.close();
				return CodeGen::indent(1) + "//Class found. Ending token (" + m_endUPToken + ") not found\n";
			}
		}
		else
		{
			old_xmp_file.close();
			return CodeGen::indent(1) + "//Class found. Starting token (" + m_startUPToken + ") not found\n";
		}
	}
	else
	{
		old_xmp_file.close();
		return CodeGen::indent(1) + "//Class not found\n";
	}
	old_xmp_file.close();
	return up;
}

void Any::makeBackup()
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		std::string dirname = getValidNmspc();
		std::string fname   = getName();
		// check dir for namespace
		if( !dirname.empty())
		{
			bool success = directoryExists( dirname.c_str());
			if( !success) success = directoryCreate( dirname.c_str());

			if( success) dirname += "\\";
			else         dirname  = "";
		}

		std::string fn = dirname + fname;// + ".cpp";
		if( !makeFileMove( ( fn + ".h").c_str(), ( fn + ".h.bak").c_str()))
			global_vars.err << MSG_ERROR << "Could not backup " << ( fn + ".h");
		if( !makeFileMove( ( fn + ".cpp").c_str(), ( fn + ".cpp.bak").c_str()))
			global_vars.err << MSG_ERROR << "Could not backup " << ( fn + ".cpp");

		//Dumper::backup( fn_c.c_str()); // makes backup if exists file
	}
}

void Any::initOutS()
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		std::string dirname = getValidNmspc();
		std::string fname   = getName();
		// check dir for namespace
		if( !dirname.empty())
		{
			bool success = directoryExists( dirname.c_str());
			if( !success) success = directoryCreate( dirname.c_str());

			if( success) dirname += "\\";
			else         dirname  = "";
		}

		std::string fn_c = dirname + fname + ".cpp";
		//Dumper::backup( fn_c.c_str()); // makes backup if exists file

		m_sStream.open( fn_c.c_str(), std::ios_base::out | std::ios_base::app); // append old file
		m_sStream.seekp( 0, std::ios::end); // go to end
		int lenf = m_sStream.tellp();
		if( lenf == ( std::fstream::pos_type) 0)
		{
			m_sStream << "#include \"stdafx.h\"" << std::endl;
			m_sStream << "#include \"" << shortFileName( global_vars.header_file_name) << "\"" << std::endl;
			//m_sStream << "#include \"" << fname << ".h\"" << std::endl;
			if( Dumper::m_bGenAcceptSpeci && 0) // if special accept is generated then special visitor header included
				m_sStream << "#include \"" << shortFileName( global_vars.m_visitorHeaderFileName) << "\"" << std::endl;
		}
		else // the file existed, how come it was supposed to be moved to .bak
		{
			// it might happen that we have a 'Package' and 'package' class 
			// which is OK in GME, but not for WINDOS: filenames are similar in such a case
			// we issue a warning and append the new contents
			global_vars.err << MSG_WARNING << "Methods of class \"" << fname << "\" appended to end of file: " << fn_c << " [Hint: filenames are not case-sensitive, thus might clash!]";
		}

		m_sStream << std::endl;
		m_sStream << std::endl;
	}
}

void Any::initOutH( std::string& resu)
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		std::string dirname = getValidNmspc();
		std::string fname   = getName();
		std::string cc      = capitalizeString( dirname + fname);

		// check dir for namespace
		if( !dirname.empty())
		{
			bool success = directoryExists( dirname.c_str());
			if( !success) success = directoryCreate( dirname.c_str());

			if( success) dirname += "\\";
			else         dirname  = "";
		}

		std::string fn_h = dirname + fname + ".h";
		//Dumper::backup( fn_h.c_str()); // makes backup if exists file
		
		m_hStream.open( fn_h.c_str(), std::ios_base::out | std::ios_base::app); // append old file
		m_hStream.seekp( 0, std::ios::end); // go to end
		int lenf = m_hStream.tellp();
		if( lenf == ( std::fstream::pos_type) 0) 
		{
			m_hStream << "#ifndef " << cc << "_H" << std::endl;
			m_hStream << "#define " << cc << "_H" << std::endl;
			m_hStream << std::endl;
			m_hStream << "#include \"" << shortFileName( global_vars.header_file_name) << "\"" << std::endl;
		}
		else // the file existed, how come it was supposed to be moved to .bak
		{
			// it might happen that we have a 'Package' and 'package' class 
			// which is OK in GME, but not for WINDOS: filenames are similar in such a case
			// we issue a warning and append the new contents with some minor tricks like #if 1 // dummy
			global_vars.err << MSG_WARNING << "Declaration for class \"" << fname << "\" appended to end of file: " << fn_h << " [Hint: filenames are not case-sensitive, thus might clash!]";

			m_hStream << "#if 1 // dummy" << std::endl; // just to fool finiOutH
		}

		m_hStream << std::endl;
		m_hStream << std::endl;

		// repl '\' with '/' if dirname is filled
		resu += "#include \"" + ( dirname.empty()?"":dirname.substr(0, dirname.length() - 1) + "/") + fname + ".h\"\n";
	}
}

void Any::finiOutS()
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		m_sStream.close();
	}
}

void Any::finiOutH()
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		m_hStream << "#endif" << std::endl;
		m_hStream.close();
	}
}

void Any::sendOutH( const std::string& content)
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::ALLTOGETHER) // one file policy
	{
		DMP_H( content);
	}
	else if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		m_hStream << content;//dmp( "this->getname", content);
	}
	else if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERNAMESPACE) // 
	{
		//dmp( "this->getnamespace", content);
	}
}

void Any::sendOutS( const std::string& content)
{
	if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::ALLTOGETHER) // one file policy
	{
		DMP_S( content);
	}
	else if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERCLASS) // 
	{
		m_sStream << content;//dmp( "this->getname", content);
	}
	else if( global_vars.m_outputMethod == Globals::OUTPUTMETHOD_ENUM::PERNAMESPACE) // 
	{
		//dmp( "this->getnamespace", content);
	}
}
--- NEW FILE: RootFolder.h ---
#ifndef ROOTFOLDER_H
#define ROOTFOLDER_H

#include "Any.h"
#include "FCO.h"
#include "FolderRep.h"
#include "ModelRep.h"
#include "AtomRep.h"
#include "ConnectionRep.h"
#include "SetRep.h"
#include "ReferenceRep.h"
#include "FcoRep.h"

#include "list"
#include "vector"

class RootFolder 
{
public: // types
	typedef std::vector<FCO*>::iterator FCO_Iterator;
	typedef std::vector<FCO*>::const_iterator FCO_ConstIterator;
	typedef std::vector<FolderRep*>::const_iterator SubFolder_ConstIterator;

public:
	RootFolder() 
	{ 
		m_subFolderList.clear(); 
		m_fcoList.clear(); 
	}

	~RootFolder() 
	{ 
		m_subFolderList.clear(); 
		m_fcoList.clear(); 
	}

	void addRootElement( FCO * ptr);
	bool isInRoot( FCO * ptr) const;

	void addSubFolder( FolderRep * ptr);

protected:
	std::vector<FCO *> m_fcoList;
	std::vector<FolderRep*> m_subFolderList;

private: // forbiding copy
	RootFolder( const RootFolder&);
	operator=( const RootFolder&);

};
#endif //ROOTFOLDER_H
--- NEW FILE: RootFolder.cpp ---
#include "stdafx.h"

#include "RootFolder.h"
#include "Any.h"

#include "algorithm"

extern int ind;

void RootFolder::addRootElement( FCO * ptr)
{
	m_fcoList.push_back( ptr);
}


bool RootFolder::isInRoot( FCO * ptr) const
{
	FCO_ConstIterator fco_it = std::find( m_fcoList.begin(), m_fcoList.end(), ptr);
	return fco_it != m_fcoList.end();
}


void RootFolder::addSubFolder( FolderRep *ptr)
{
	m_subFolderList.push_back( ptr);
}



--- NEW FILE: PointerItem.cpp ---
#include "stdafx.h"
#include "PointerItem.h"

bool PointerItemLex::operator()( const PointerItem& p1, const PointerItem& p2) const
{
	std::string p1_n = p1.name();
	return (p1_n.compare( p2.name()) < 0 );
}


PointerItem::PointerItem( std::string name, FCO * ptr)
 : m_name( name), m_fcoPtr( ptr)
{ }

PointerItem::PointerItem( const PointerItem& peer)
 : m_name( peer.m_name), m_fcoPtr( peer.m_fcoPtr)
{ }

const PointerItem& PointerItem::operator=( const PointerItem& peer)
{
	if (&peer == this) return *this;
	m_name = peer.m_name;
	m_fcoPtr = peer.m_fcoPtr;
	return *this;
}

bool PointerItem::operator==( const PointerItem& peer) const
{
	return m_name == peer.m_name && m_fcoPtr == peer.m_fcoPtr;
}

bool PointerItem::operator!=( const PointerItem& peer) const
{
	return !operator==(peer);
}

const std::string& PointerItem::name() const
{
	return m_name;
}

FCO * PointerItem::fcoPtr() const
{
	return m_fcoPtr;
}
--- NEW FILE: FolderRep.cpp ---
#include "stdafx.h"

#include "FolderRep.h"
#include "Dumper.h"
#include "CodeGen.h"
#include "algorithm"

#include "globals.h"
extern Globals global_vars;


FolderRep::FolderRep( IMgaFCO* ptr, IMgaFCO* resp_ptr) 
	: Any( ptr)
	, m_fcoList()
	, m_fcoCardList()
	, m_subFolderList()
	, m_subCardList()
	, m_respPointer( resp_ptr)
	, m_methods()
{ 
}

FolderRep::~FolderRep() 
{ 
	m_fcoList.clear();
	m_fcoCardList.clear();
	m_subFolderList.clear();
	m_subCardList.clear();
	m_respPointer = CComPtr<IMgaFCO>( 0);
	m_methods.clear();
}

	
std::string FolderRep::getName() const
{
#if(0)
	if (m_respPointer == BON::FCO())
	{
		global_vars.err << "Null pointer error in getFolderName\n";
		return std::string("Null pointer error in getFolderName");
	}
	return m_respPointer->getName();
#else
	if( this->m_respPointer) // there are equivalents
	{
		std::string regname = Util::gvbp( getMIRegistry(), Any::NameSelectorNode_str);
		if( !regname.empty()) return regname;
		else return Util::name( m_respPointer);
	}
	else if ( this->m_ptr)
	{
		return Util::name( m_ptr);
	}
	return "NullPtrError";
#endif
}


void FolderRep::addFCO( FCO * ptr, const std::string& card)
{
	if ( std::find( m_fcoList.begin(), m_fcoList.end(), ptr) == m_fcoList.end()) // not found
	{
		m_fcoList.push_back( ptr);
		m_fcoCardList.push_back( card);
	}
	else
		global_vars.err << "CHECK: "<< ptr->getName() << " contained by folder " << getName() << " twice. Disregarded.\n";
}


bool FolderRep::isFCOContained( FCO * ptr)
{
	return m_fcoList.end() != std::find( m_fcoList.begin(), m_fcoList.end(), ptr);
}


void FolderRep::addSubFolderRep( FolderRep *ptr, const std::string& card)
{
	if ( std::find( m_subFolderList.begin(), m_subFolderList.end(), ptr) 
		== m_subFolderList.end()) // not found
	{
		m_subFolderList.push_back( ptr);
		m_subCardList.push_back( card);
	}
	else
		global_vars.err << "CHECK: Folder " << ptr->getName() << " contained by folder "  << getName() << " twice. Disregarded.\n";
}


void FolderRep::extendMembership()
{
	std::vector<FCO *> temp_list;
	FCO_Iterator fco_it = m_fcoList.begin();
	for( ; fco_it != m_fcoList.end(); ++fco_it)
	{
		FCO * fco_ptr = *fco_it;
		std::vector<FCO*> descendants;
		fco_ptr->getIntDescendants( descendants);
		std::vector<FCO*>::iterator desc_it = descendants.begin();
		for( ; desc_it != descendants.end(); ++desc_it)
		{
			FCO * new_member = *desc_it;
			if ( temp_list.end() == 
				std::find( temp_list.begin(), temp_list.end(), new_member)) // not found
				temp_list.push_back( new_member);
		}
	}
	// append the temp_list to the end of the fco_list
	m_fcoList.insert( m_fcoList.end(), temp_list.begin(), temp_list.end());
}


void FolderRep::createMethods()
{
	std::vector<FCO *>::iterator fco_it = m_fcoList.begin();
	for( ; fco_it != m_fcoList.end(); ++fco_it)
	{
		CodeGen::dumpKindGetter( *fco_it, this);
	}

	std::vector<FolderRep*>::iterator fold_it = m_subFolderList.begin();
	for( ; fold_it != m_subFolderList.end(); ++fold_it)
	{
		CodeGen::dumpFoldGetter( *fold_it, this);
	}
}


std::string FolderRep::doDump()
{
	std::string h_file, c_file;

	dumpPre( h_file, c_file);

	if ( !m_methods.empty())
		h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// kind and subfolder getters\n";

	MethodLexicographicSort lex;
	std::sort( m_methods.begin(), m_methods.end(), lex);
	
	std::vector<Method>::iterator i = m_methods.begin();
	for( ; i != m_methods.end(); ++i)
	{
		h_file += i->getHeader() + "\n";
		c_file += i->getSource() + "";
	}

	dumpPost( h_file, c_file);

	sendOutH( h_file);//DMP_H( h_file);
	sendOutS( c_file);//DMP_S( c_file);

	return "";
}

/*static*/ std::string FolderRep::subFolderGetterMethodName(FolderRep * fold, const std::string& diff_nmsp)
{
#if(LONG_NAMES)
	return "get_Sub_" + fold->getValidName();
#else
	return "get" + diff_nmsp + fold->getValidName();
#endif
}


/*static*/ std::string FolderRep::kindGetterMethodName(FCO * fco, const std::string& diff_nmsp)
{
#if(LONG_NAMES)
	return "get_Kind_" + fco->getValidName();
#else
	return "get" + diff_nmsp + fco->getValidName();
#endif
}



--- NEW FILE: ConnJoint.h ---
#ifndef CONNJOINT_H
#define CONNJOINT_H

#include "Any.h"
#include "RoleRep.h"
#include "PointerItem.h"
#include "FCO.h"
#include "Method.h"

class Sheet;
class ConnectionRep;

#include "list"

class ConnJoint 
{
public: // types
	typedef std::vector< FCO *> SDList;
	typedef std::vector< FCO *>::iterator SDList_Iterator;
	typedef std::vector< FCO *>::const_iterator SDList_ConstIterator;

	typedef std::vector< PointerItem> PointerItemSeries;
	typedef std::vector< PointerItem>::iterator PointerItemSeries_Iterator;
	typedef std::vector< PointerItem>::const_iterator PointerItemSeries_ConstIterator;

	typedef const ModelRep* Key;
	typedef std::map< Key, PointerItemSeries> TargetMap;
	typedef TargetMap::iterator TargetMap_Iterator;

public:
	static std::string m_srcLabel;
	static std::string m_dstLabel;

	ConnJoint( 
		ConnectionRep *, const SDList& op1, const SDList& op2, bool bidirect,
		std::string card1 = "", std::string card2 = ""
		);
	ConnJoint( const ConnJoint& peer);
	const ConnJoint& operator=( const ConnJoint& peer);
	~ConnJoint();

	void setConnectionPtr( ConnectionRep * conn_ptr);

	const SDList& getOp1() const;
	const SDList& getOp2() const;
	bool isBidirect() const;

	void intInherit( ModelRep * mod_ptr);

	// appends new role(s)
	void addTargetItem( int i, const ModelRep * model, const PointerItem& item);
	void addTargetItem( int i, const ModelRep * model, const RoleRep & new_role);
	void addTargetItem( int i, const ModelRep * model, const RoleRep::RoleRepSeries & new_role_series);

	bool checkElements( std::string connection_name);

	bool calcLCD();

	bool createLinkGetters();
	bool createSrcDstGetters();
	bool createEndGetters();

protected:

	// pointer to the container Connection, this ConnJoint is part of
	// beware: when copied during implementation inheritance the owner may change
	ConnectionRep * m_connPtr;

	// initial 
	SDList m_oper1;
	SDList m_oper2; 
	
	// final
	TargetMap m_oper1TargetMap;
	TargetMap m_oper2TargetMap;

	// if label1 == label2
	bool m_bidirect;

	// cardinality
	std::string m_oper1Card;
	std::string m_oper2Card;

	// least common denominators for SRC and DST
	SDList m_srcLCD;
	SDList m_dstLCD;
	//bool  m_same;

	// indicates whether the src or dst might be reference ports or not
	bool m_oper1IsAnyReferencePort;
	bool m_oper2IsAnyReferencePort;
};

#endif //CONNJOINT_H



More information about the GME-commit mailing list