[GME-commit] GMESRC/Paradigms/MetaGME/MetaInterpreter2008/rep Any.cpp, NONE, 1.1 Any.h, NONE, 1.1 AspectRep.cpp, NONE, 1.1 AspectRep.h, NONE, 1.1 AtomRep.cpp, NONE, 1.1 AtomRep.h, NONE, 1.1 AttributeRep.cpp, NONE, 1.1 AttributeRep.h, NONE, 1.1 Broker.cpp, NONE, 1.1 Broker.h, NONE, 1.1 ConnJoint.cpp, NONE, 1.1 ConnJoint.h, NONE, 1.1 ConnectionRep.cpp, NONE, 1.1 ConnectionRep.h, NONE, 1.1 ConstraintFuncRep.cpp, NONE, 1.1 ConstraintFuncRep.h, NONE, 1.1 ConstraintRep.cpp, NONE, 1.1 ConstraintRep.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.h, NONE, 1.1 FolderRep.cpp, NONE, 1.1 FolderRep.h, NONE, 1.1 ModelRep.cpp, NONE, 1.1 ModelRep.h, NONE, 1.1 PartRep.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
Wed Mar 12 12:48:47 CDT 2008


Update of /project/gme-repository/GMESRC/Paradigms/MetaGME/MetaInterpreter2008/rep
In directory escher:/tmp/cvs-serv813/MetaInterpreter2008/rep

Added Files:
	Any.cpp Any.h AspectRep.cpp AspectRep.h AtomRep.cpp AtomRep.h 
	AttributeRep.cpp AttributeRep.h Broker.cpp Broker.h 
	ConnJoint.cpp ConnJoint.h ConnectionRep.cpp ConnectionRep.h 
	ConstraintFuncRep.cpp ConstraintFuncRep.h ConstraintRep.cpp 
	ConstraintRep.h Dumper.cpp Dumper.h FCO.cpp FCO.h FcoRep.h 
	FolderRep.cpp FolderRep.h ModelRep.cpp ModelRep.h PartRep.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:
MetaInterpreter2008 is a RawComponent, a faster alternative to MetaInterprter2004.



CVS User: Zoltan Molnar, ISIS (zolmol)

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

#include "MyUtil.h"
#include "AspectRep.h"
#include "RoleRep.h"
#include "ModelRep.h"
#include "Dumper.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;

/*static*/ const std::string AspectRep::m_aspectRegistryRoot = "AspectRegistry";
/*static*/ const std::string AspectRep::m_aspectMetaRefsRoot = "AspectMetaRefs";
/*static*/ const std::string AspectRep::m_aspectNamesRoot    = "AspectSelNames";

bool PartCompare::operator()( const PartRep& peer1, const PartRep& peer2) const
{
	std::string name1 = peer1.getRoleRepPtr()->getSmartRoleName();
	std::string name2 = peer2.getRoleRepPtr()->getSmartRoleName();

	int k = name1.compare( name2);
	return ( k < 0);
}


bool AspectCompare::operator()( const AspectRep* peer1, const AspectRep* peer2) const
{
	return peer1->lessThan( *peer2);
}


bool AspNamePriorityComp::operator()( const Type& p1, const Type& p2) const
{
	return p1.second != p2.second ? p1.second < p2.second : (p1.first.compare( p2.first) < 0);
}


AspectRep::AspectRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: Any( ptr)
	, m_priority( 0)
	, m_respPointer( resp_ptr)
	, m_fcoInitialList()
	, m_roleInitialList()
	, m_fcoFinalList()
	, m_roleFinalList()
	, m_partsMap()

{ 
#if(0)
	if (m_respPointer == CComPtr<IMgaFCO>(0)) 
	{
		//v0global_vars.err << "Fatal Error during AspectRep constructor: m_respPointer is 0\n";
p		global_vars.err << MSG_WARNING << "Dummy aspect created. You should define aspects for the models.\n";
	}
#endif
}


AspectRep::~AspectRep()
{
	m_fcoInitialList.clear();
	m_roleInitialList.clear();
	m_fcoFinalList.clear();
	m_roleFinalList.clear();
	m_partsMap.clear();
}


std::string AspectRep::doDump() { return ""; }


Any::KIND_TYPE AspectRep::getMyKind() const { return Any::ASPECT; }


std::string AspectRep::getName() const
{
#if(0)
	// using m_respPointer instead of m_ptr
	if (m_respPointer == CComPtr<IMgaFCO>(0))
	{
		global_vars.err << MSG_ERROR << "Null pointer error in getAspectName\n";
		return std::string("Null pointer error in getAspectName");
	}
	else
	{
		return m_respPointer->getName();
	}
#else
#if(0)
	if( m_respPointer != CComPtr<IMgaFCO>(0))
	{
		return m_respPointer->getName();
	}
	else
	{
		return "Aspect";
	}
#else // new way
	if( m_respPointer)
	{
		CComBSTR nm;
		COMTHROW( m_respPointer->get_Name( &nm));
		return Util::Copy( nm);
	}
	else if( m_ptr)
	{
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return Util::Copy( nm);
	}
	else // dummy aspect
	{
		return "Aspect";
	}
#endif
#endif
}

std::string AspectRep::getDispName() const
{
#if(0)
	if (m_respPointer == CComPtr<IMgaFCO>(0)) 
	{
		global_vars.err << MSG_ERROR << "Null pointer error in getDispName for aspect \"" + getName() + "\"\n";
		return std::string("Null pointer error in getDispName for aspect \"") + getName() + "\"";
	}
	else
	{
		return m_ptr->getAttribute( Any::DisplayedName_str)->getStringValue(); //<!> modified from m_respPointer
	}
#else
	//what about a reform such that dispname is allowed only for lonely aspects (which are not equivalent with any other)
	//<!> 

	// or what about deciding using the selected aspect's dispname attribute 
	// (what happens if the user does not know which aspect did he selected from 
	// the aspects with similar name)
#if(0)
	if( m_ptr != CComPtr<IMgaFCO>(0)) 
	{
		return m_ptr->getAttribute( Any::DisplayedName_str)->getStringValue(); //<!> modified from m_respPointer
	}
	else
	{
		return "Aspect";	
	}
#else // new way
	if( m_respPointer) // not a plain fco, it has its resppointer set
	{
		//return "";
		return m_userSelectedDisplayName;
	}
	else if( m_ptr)
	{
		CComBSTR val;
		COMTHROW( m_ptr->get_StrAttrByName( Util::Copy( Any::DisplayedName_str), &val));
		return Util::Copy( val);
	}
	else // dummy aspect
	{
		return "";
	}
#endif
#endif
}


std::string AspectRep::getMyPrefix() const
{
	// any modification in the registry policy should be syched with
	// the Broker::initFromObj method
	return AspectRep::m_aspectRegistryRoot + "/" + AspectRep::m_aspectMetaRefsRoot + "/" + getName();
}


CComPtr<IMgaRegNode> AspectRep::getMyRegistry() const
{
	// any modification in the registry policy should be syched with
	// the Broker::initFromObj method
	//if ( this->m_ptr && this->m_parentFolder)
	//return m_parentFolder->getRegistry()->getChild( getMyPrefix());
	CComPtr<IMgaRegNode> rn;
	COMTHROW( Sheet::m_BON_Project_Root_Folder->get_RegistryNode( Util::Copy( getMyPrefix()), &rn));
	return rn;
}


//
// these two methods are used only for selected name storing
//
/*static*/ std::string AspectRep::getMyPrefix( IMgaFCO* fco, IMgaFolder* f)
{
	ASSERT( fco);
	CComBSTR nm;
	COMTHROW( fco->get_Name( &nm));
	return AspectRep::m_aspectRegistryRoot + "/" + AspectRep::m_aspectNamesRoot + "/" + Util::Copy( nm);
}


/*static*/ CComPtr<IMgaRegNode> AspectRep::getMyRegistry( IMgaFCO* fco, IMgaFolder* f)
{
	ASSERT( fco);
	ASSERT( f);
	CComPtr<IMgaRegNode> rn;
	COMTHROW( Sheet::m_BON_Project_Root_Folder->get_RegistryNode( Util::Copy( AspectRep::getMyPrefix( fco, f)), &rn));
	return rn;
}


void AspectRep::addFCO( FCO* fco) 
{
	m_fcoInitialList.push_back( fco); 
}


void AspectRep::addRRole( RoleRep & role)
{
	m_roleInitialList.push_back( role);
}


bool AspectRep::findFinalFCO( const FCO * fco_ptr) const
{
	return ( m_fcoFinalList.end() != 
		std::find(m_fcoFinalList.begin(), m_fcoFinalList.end(), fco_ptr));
}


bool AspectRep::findFinalRole( const RoleRep& a_role) const
{
	std::vector<RoleRep>::const_iterator it = m_roleFinalList.begin();
	bool found = false;
	while ( it != m_roleFinalList.end() && !found)
	{
		if ( a_role.getFCOPtr() == it->getFCOPtr() &&
			a_role.getModelRepPtr() == it->getModelRepPtr() &&
			a_role.getOnlyRoleName() == it->getOnlyRoleName())
		{
			found = true;
		}
		++it;
	}
	return found;
}


void AspectRep::extendAspectWithDescendants()
{
	// 1st scenario
	// expand aspect membership ( if FCOA is selected to appear in AspA)
	// M1<>---------FCOA -set_member----AspA
	//               |
	//              /^\
	//          FCOB   FCOC
	//
	// if FCOA is member of AspA aspect, then FCOB and FCOC is also a member of AspA
	//  
	//
	// 2nd scenario
	// in case when only a role (of FCOA in a model) is specified as part of an aspect 
	// that role should be extended for FCOB and FCOC as well and for the model
	// descendants inherited from the model. I.e.
	//
	// AspA-----<>M1<>-------FCOA
	//            |
	//           /^\
	//         M2   M3
	//           
	//
	// if the role between M1--FCOA is specified as an aspect member then M2,M3 in AspA should show
	// FCOA and its descendants

	std::vector<FCO*>::iterator init_it = m_fcoInitialList.begin();
	for( ; init_it != m_fcoInitialList.end(); ++init_it)
	{
		FCO* fco_ptr = *init_it;
		std::string fco_nm = fco_ptr->getName();
		std::vector<FCO*> children;
		fco_ptr->getIntDescendants( children);
		children.push_back( fco_ptr);

		for( unsigned int i = 0; i < children.size(); ++i)
			if ( m_fcoFinalList.end() == // not found
				std::find( m_fcoFinalList.begin(), m_fcoFinalList.end(), children[i])) 
				m_fcoFinalList.push_back( children[i]);
	}

	// a task similar to ModelRep::inherit needs to be done
	std::vector< RoleRep>::iterator r_init_it = m_roleInitialList.begin();
	for( ; r_init_it != m_roleInitialList.end(); ++r_init_it)
	{
		FCO* fco_ptr = r_init_it->getFCOPtr();
		std::vector<FCO*> children;
		fco_ptr->getIntDescendants( children);
		children.push_back( fco_ptr);

		ModelRep* model_ptr = r_init_it->getModelRepPtr();
		std::vector<FCO*> model_descendants;
		model_ptr->getImpDescendants( model_descendants);
		model_descendants.push_back( model_ptr);

		for( unsigned int i = 0; i < children.size(); ++i)
		{
			for( unsigned int j = 0; j < model_descendants.size(); ++j)
			{
				ModelRep * model_desc = dynamic_cast<ModelRep *>(model_descendants[j]);
				if (!model_desc) global_vars.err << MSG_ERROR << "Internal error: model descendant badly casted to model\n";

				RoleRep r(
					r_init_it->getOnlyRoleName(),
					children[i],
					model_desc,
					r_init_it->isPort(),
					r_init_it->getCardinality(),
					j + 1 == model_descendants.size(),//r_init_it->isInheritedRole(),
					r_init_it->isLongForm()
					);

				if ( m_roleFinalList.end() == // not found
					std::find( m_roleFinalList.begin(), m_roleFinalList.end(), r)) 
					m_roleFinalList.push_back( r);
			}
		}
	}
}


void AspectRep::sortPartMap()
{
	PartCompare partCompare;
	ModelPartsMap_Iterator it = m_partsMap.begin();
	for( ; it != m_partsMap.end(); ++it)
	{
		PartRepSeries &p = it->second;
		std::sort( p.begin(), p.end(), partCompare);
	}
}


void AspectRep::addPart2Map( ModelRep * mod_ptr, const PartRep & part)
{
	PartRepSeries & series = m_partsMap[mod_ptr];
	if ( series.end() == // not found
		std::find( series.begin(), series.end(), part))
		series.push_back( part);
	else
		global_vars.err << MSG_ERROR << "Part " << part.getRoleRepPtr()->getSmartRoleName() 
		<< " attempted to insert twice into aspect " << m_ptr << "\n";
}


const AspectRep::PartRepSeries& AspectRep::getPartSeries( ModelRep* mod_ptr)
{
	return m_partsMap[ mod_ptr];
}


bool AspectRep::lessThan( const AspectRep& rep) const
{
	if ( m_priority) // non-zero value means the order was overwritten by the user
		return m_priority < rep.m_priority;

	unsigned int x, y;
	unsigned int rep_x, rep_y;
	getXY( &x, &y);
	rep.getXY( &rep_x, &rep_y);
	return ( y < rep_y || (y == rep_y && x < rep_x ));
}


void AspectRep::getXY( unsigned int * x, unsigned int * y) const
{
	if( m_ptr != CComPtr<IMgaFCO>(0))
	{
		std::string val = Util::getReg( m_ptr, "PartRegs/Visualization/Position");
		int v = sscanf( val.c_str(), "%d, %d", x, y);
		ASSERT( v == 2);
	}
	else // created aspect
	{
		*x = *y = 0;
	}
}


void AspectRep::setPriority( int prior)
{
	ASSERT( prior > 0);
	m_priority = prior;
}

int AspectRep::getPriority() const
{
	return m_priority;
}


bool AspectRep::isDummy() const
{
	return m_ptr == CComPtr<IMgaFCO>(0) && m_respPointer == CComPtr<IMgaFCO>(0);
}

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

#include "MyUtil.h"
#include "ConnectionRep.h"
#include "logger.h"
#include "ModelRep.h"

#include "globals.h"
extern Globals global_vars;

/*static*/ const std::string ConnectionRep::Color_str = "Color";
/*static*/ const std::string ConnectionRep::ConnLineEnd_str = "ConnLineEnd";
/*static*/ const std::string ConnectionRep::ConnLineStart_str = "ConnLineStart";
/*static*/ const std::string ConnectionRep::ConnLineType_str = "ConnLineType";
/*static*/ const std::string ConnectionRep::SrcAttrLabel1_str = "SrcAttrLabel1";
/*static*/ const std::string ConnectionRep::SrcAttrLabel2_str = "SrcAttrLabel2";
/*static*/ const std::string ConnectionRep::DstAttrLabel1_str = "DstAttrLabel1";
/*static*/ const std::string ConnectionRep::DstAttrLabel2_str = "DstAttrLabel2";

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


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


/*virtual*/ void ConnectionRep::initAttributes()
{
	//
	// Connections have their namePos attribute ignored! <!>
	//

	m_isInRootFolder = m_isInRootFolder || Util::getBoolAttr( m_ptr, InRootFolder_str);

	// isAbstract: true iff all values (which are set) are true
	//m_isAbstract = m_isAbstract && m_ptr->getAttribute( IsAbstract_str)->getBooleanValue();
	bool isabs = true; // if any of the set values is false it will change
	bool isabs_set = false;
	if( Util::isAttrStatHere( m_ptr, IsAbstract_str))
	{
		isabs = isabs && Util::getBoolAttr( m_ptr, IsAbstract_str);
		isabs_set = true;
	}


	// general pref
	bool isgenpref_set = false;
	if( Util::isAttrStatHere( m_ptr, GeneralPreferences_str))
	{
		m_sAttrGenPref = Util::getStrAttr( m_ptr, GeneralPreferences_str);
		isgenpref_set = true;
	}

	// displayed name
	bool isdispname_set = false;
	if( Util::isAttrStatHere( m_ptr, DisplayedName_str))
	{
		m_sAttrDispName = Util::getStrAttr( m_ptr, DisplayedName_str);
		isdispname_set = true;
	}

	
	bool iscolor_set = false;
	//if( m_ptr->getAttribute( Color_str)->getStatus() >= BON::AS_Here)
	{
		m_sAttrColor = Util::getStrAttr( m_ptr, Color_str);
		iscolor_set = true;
	}
	bool isconnlineend_set = false;
	//if( m_ptr->getAttribute( ConnLineEnd_str)->getStatus() >= BON::AS_Here)
	{
		m_sAttrConnLineEnd = Util::getStrAttr( m_ptr, ConnLineEnd_str);
		isconnlineend_set = true;
	}
	bool isconnlinestart_set = false;
	//if( m_ptr->getAttribute( ConnLineStart_str)->getStatus() >= BON::AS_Here)
	{
		m_sAttrConnLineStart = Util::getStrAttr( m_ptr, ConnLineStart_str);
		isconnlinestart_set = true;
	}
	
	bool isconnlinetype_set = false;
	//if( m_ptr->getAttribute( ConnLineType_str)->getStatus() >= BON::AS_Here)
	{
		m_sAttrConnLineType = Util::getStrAttr( m_ptr, ConnLineType_str);
		isconnlinetype_set = true;
	}

	bool issrclabel1_set = false;
	if( Util::isAttrStatHere( m_ptr, SrcAttrLabel1_str))
	{
		m_sAttrSrcAttrLabel1 = Util::getStrAttr( m_ptr, SrcAttrLabel1_str);
		issrclabel1_set = true;
	}
	bool issrclabel2_set = false;
	if( Util::isAttrStatHere( m_ptr, SrcAttrLabel2_str))
	{
		m_sAttrSrcAttrLabel2 = Util::getStrAttr( m_ptr, SrcAttrLabel2_str);
		issrclabel2_set = true;
	}
	bool isdstlabel1_set = false;
	if( Util::isAttrStatHere( m_ptr, DstAttrLabel1_str))
	{
		m_sAttrDstAttrLabel1 = Util::getStrAttr( m_ptr, DstAttrLabel1_str);
		isdstlabel1_set = true;
	}
	bool isdstlabel2_set = false;
	if( Util::isAttrStatHere( m_ptr, DstAttrLabel2_str))
	{
		m_sAttrDstAttrLabel2 = Util::getStrAttr( m_ptr, DstAttrLabel2_str);
		isdstlabel2_set = true;
	}

	EquivSet_ConstIterator it = m_equivs.begin();
	for ( ; it != m_equivs.end(); ++it)
	{
		if ( *it == m_ptr) continue;

		// --the following 4 attributes are applicable to proxies as well--
		// InRootFolder: true if one is at least true
		m_isInRootFolder = m_isInRootFolder || Util::getBoolAttr( *it, InRootFolder_str);

		// isAbstract: true if all objects are true
		//m_isAbstract = m_isAbstract && (*it)->getAttribute( IsAbstract_str)->getBooleanValue();
		if( Util::isAttrStatHere( *it, IsAbstract_str)) // if set by the user
		{
			isabs = isabs && Util::getBoolAttr( *it, IsAbstract_str);
			isabs_set = true;
		}

#if(1)
		// general pref
		if( !isgenpref_set && Util::isAttrStatHere( *it, GeneralPreferences_str))
		{
			m_sAttrGenPref = Util::getStrAttr( *it, GeneralPreferences_str);
			isgenpref_set = true;
		}
		

		// displayed name
		if( !isdispname_set && Util::isAttrStatHere( *it, DisplayedName_str))
		{
			m_sAttrDispName = Util::getStrAttr( *it, DisplayedName_str);
			isdispname_set = true;
		}
		
		// --applicable to non proxies only--
		if ( Util::isproxy( *it)) continue;

		if( !iscolor_set && Util::isAttrStatHere( *it, Color_str))
		{
			m_sAttrColor = Util::getStrAttr( *it, Color_str);
			iscolor_set = true;
		}

		if( !isconnlineend_set && Util::isAttrStatHere( *it, ConnLineEnd_str))
		{
			m_sAttrConnLineEnd = Util::getStrAttr( *it, ConnLineEnd_str);
			isconnlineend_set = true;
		}
		
		if( !isconnlinestart_set && Util::isAttrStatHere( *it, ConnLineStart_str))
		{
			m_sAttrConnLineStart = Util::getStrAttr( *it, ConnLineStart_str);
			isconnlinestart_set = true;
		}
		if( !isconnlinetype_set && Util::isAttrStatHere( *it, ConnLineType_str))
		{
			m_sAttrConnLineType = Util::getStrAttr( *it, ConnLineType_str);
			isconnlinetype_set = true;
		}

		if( !issrclabel1_set && Util::isAttrStatHere( *it, SrcAttrLabel1_str))
		{
			m_sAttrSrcAttrLabel1 = Util::getStrAttr( *it, SrcAttrLabel1_str);
			issrclabel1_set = true;
		}
		if( !issrclabel2_set && Util::isAttrStatHere( *it, SrcAttrLabel2_str))
		{
			m_sAttrSrcAttrLabel2 = Util::getStrAttr( *it, SrcAttrLabel2_str);
			issrclabel2_set = true;
		}
		if( !isdstlabel1_set && Util::isAttrStatHere( *it, DstAttrLabel1_str))
		{
			m_sAttrDstAttrLabel1 = Util::getStrAttr( *it, DstAttrLabel1_str);
			isdstlabel1_set = true;
		}
		if( !isdstlabel2_set && Util::isAttrStatHere( *it, DstAttrLabel2_str))
		{
			m_sAttrDstAttrLabel2 = Util::getStrAttr( *it, DstAttrLabel2_str);
			isdstlabel2_set = true;
		}
#endif
	}

	if( isabs_set) m_isAbstract = isabs;
}


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


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

	if (m_jointList.empty())
		m_jointList.push_back( a_joint);
	else // with some constraint, but still copying (in error case write a log - like a constraint)
	{
		m_jointList.push_back( a_joint);

		bool desc = false;

		std::list<ConnJoint>::iterator it = m_jointList.begin();
		for( ; !desc && it != m_jointList.end(); ++it)
			desc = desc || it->descendantsOf( a_joint);

		if ( !desc)
			global_vars.err << MSG_ERROR << "Design error at connection \"" << m_ptr << "\". Derived connection is valid only if defined between fcos derived from the fcos connected by the base connection.\n";
	}
}


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
	std::vector<FCO*> conn_descendants;
	this->getImpDescendants( conn_descendants);
	//conn_descendants.push_back( this); nn because the owner will be first filled

	std::vector<FCO*>::iterator conn_it = conn_descendants.begin();
	for( ; conn_it != conn_descendants.end(); ++conn_it)
	{
		std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
		for( ; joint_it != m_jointList.end(); ++joint_it )
		{
			ConnectionRep * conn_rep = 0;
			if ( (*conn_it)->getMyKind() == Any::CONN)
				conn_rep = dynamic_cast<ConnectionRep *>( *conn_it);
			if (conn_rep)
				conn_rep->appendJointElements( *joint_it);
		}
	}
}


std::string ConnectionRep::dumpConnDetails()
{
	std::string mmm;
	//if ( this->m_ptr)
	{
		mmm = indStr() + "<regnode name = \"color\" value =\"" + (m_sAttrColor.empty()?"0x000000":m_sAttrColor) + "\"></regnode>\n";

		if( !m_sAttrConnLineEnd.empty())
			mmm += indStr() + "<regnode name = \"dstStyle\" value =\"" + m_sAttrConnLineEnd + "\"></regnode>\n";

		if( !m_sAttrConnLineStart.empty())
			mmm += indStr() + "<regnode name = \"srcStyle\" value =\"" + m_sAttrConnLineStart + "\"></regnode>\n";
		
		if( !m_sAttrConnLineType.empty())
			mmm += indStr() + "<regnode name = \"lineType\" value =\"" + m_sAttrConnLineType + "\"></regnode>\n";
	
		std::string * which[] = 
		{
			&m_sAttrSrcAttrLabel1,
			&m_sAttrSrcAttrLabel2,
			&m_sAttrDstAttrLabel1,
			&m_sAttrDstAttrLabel2
		};

		std::string reg_label[] =
		{
			"srcLabel1",
			"srcLabel2",
			"dstLabel1",
			"dstLabel2"
		};

		for( int i = 0; i < 4 ; ++ i)
		{
			std::string &label = *which[i];
			if( !label.empty()) {
				// the label may or may not contain the % sign
				// but if we find an attribute with that name, we place the % sign arount it
				// if the attribute is not found it is considered to be an ordinary label
				if ( label.length() > 1 && label[0] == '%' && label[ label.length() - 1] == '%')
				{
					bool attr = findFinalAttributeBasedOnName( label.substr( 1, label.length() - 2));
					if( attr ) 
						mmm += indStr() + "<regnode name= \"" + reg_label[i] + "\" value=\"" + label + "\"/>\n";
					else
						global_vars.err << MSG_ERROR << "Attribute \"" << label.substr( 1, label.length() - 2) << "\" not found for connection \"" << m_ptr << "\". Wrong label specification.\n";
				}
				else
				{
					bool attr = findFinalAttributeBasedOnName( label);
					if( attr ) 
						mmm += indStr() + "<regnode name= \"" + reg_label[i] + "\" value=\"%" + label + "%\"/>\n";
					else
						mmm += indStr() + "<regnode name= \"" + reg_label[i] + "\" value=\"" + label + "\"/>\n";
						// previously: global_vars.err << "Attribute \"" << label << "\" not found for connection \"" << getName() << "\". Wrong label specification.\n";
				}
			}
		}
	}
	return mmm;
}


std::string ConnectionRep::doDump()
{
	std::string m_ref = askMetaRef();

	std::string mmm = indStr() + "<connection name = \"" + getName()  + "\" metaref = \"" + m_ref + "\"";

	mmm += dumpAttributeList();

	mmm +=" >\n";
	++ind;
	mmm += dumpDispName();
	++ind;
	mmm += dumpGeneralPref();
	mmm += dumpConnDetails();

	--ind;
	mmm += dumpConstraints();
	mmm += dumpAttributes();

	ModelRepPtrList models = this->modelsIAmPartOfFinal();

	std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
	for( ; joint_it != m_jointList.end(); ++joint_it )
	{
		std::string nnn = joint_it->dumpElements( models);
		mmm += nnn;
	}
	--ind;
	mmm += indStr() + "</connection>\n";
	
	return mmm;
}


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;
}


void ConnectionRep::createConstraints(Sheet * s)
{
	std::list<ConnJoint>::iterator joint_it = m_jointList.begin();
	for( ; joint_it != m_jointList.end(); ++joint_it )
		joint_it->createConstraints(s, getName());
}


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

#include "MyUtil.h"
#include "ConstraintFuncRep.h"
#include "Regexp.h"

#include "globals.h"
extern Globals global_vars;


ConstraintFuncRep::ConstraintFuncRep( IMgaFCO* ptr)
: Any( ptr),
	m_context(""), m_returntype(""), m_stereotype(""),
	m_definition(""), m_parameterlist("")
{
}

void ConstraintFuncRep::fetch()
{
	CString strWS = "[\t ]*";
	CString strID = "[_a-zA-Z][_a-zA-Z0-9]*";
	CString strT = strID + "(::" + strID + ")*";
	CString strP = strID + strWS + ":" + strWS + strT;

	CComBSTR f_val;
	COMTHROW( m_ptr->get_StrAttrByName( CComBSTR( "CFuncParamList"), &f_val));;
	std::string paramlist = Util::Copy( f_val);
	Regexp rePL( "^(" + strWS + strP + ")?" + "(" + strWS + "," + strWS + strP + ")*$", TRUE );
	if ( ! rePL.CompiledOK() )
		global_vars.err << MSG_ERROR << "Internal Interpreter Error: [REGEXP] " << rePL.GetErrorString() << "\n";
	else
		if ( ! rePL.Match( paramlist.c_str() ) )
			global_vars.err << MSG_ERROR << "Invalid format for parameterlist in Constraint Function: " << m_ptr
			<< "\nCorrect format: <paramname> : <paramtype> [, <paramname> : <paramtype>] ...\n";
	
	m_parameterlist = paramlist;

	CComBSTR c_val;
	COMTHROW( m_ptr->get_StrAttrByName( CComBSTR( "CFuncContext"), &c_val));
	std::string contexttype = Util::Copy( c_val);
	if ( contexttype.empty() ) 
	{
		global_vars.err << MSG_ERROR << "No context found for Constraint Function: " << m_ptr << ". It will be Project implicitly.\n";
		contexttype = "gme::Project";
	}
	m_context = contexttype;
	bool modify = false;// if we modify the context that is just for the ConstraintManager's sake (otherwise it would crash)
	if( modify && Util::islibobj( m_ptr) && !m_namespace.empty())
	{
		if( m_context.substr(0, 6) == "meta::" && m_context.substr( 6).find( "::") == std::string::npos)
		{ // short kind name used
			m_context.insert( 6, Any::NamespaceDelimiter_str);
			m_context.insert( 6, m_namespace); // thus a context like meta::Target becomes meta::NMSP::Target for library constraints
		}
	}

	CComBSTR r_val;
	COMTHROW( m_ptr->get_StrAttrByName( CComBSTR( "CFuncReturnType"), &r_val));
	std::string returntype = Util::Copy( r_val);
	if ( returntype.empty()) 
	{
		global_vars.err << MSG_ERROR << "No return type found for Constraint Function: " << m_ptr << ". It will be bool implicitly.\n";
		returntype = "ocl::Boolean";
	}
	m_returntype = returntype;

	CComBSTR fd_val;
	COMTHROW( m_ptr->get_StrAttrByName( CComBSTR( "CFuncDefinition"), &fd_val));
	std::string definition = Util::Copy( fd_val);
	if ( definition.empty() )
		global_vars.err << MSG_ERROR <<"No definition found for Constraint Function: " << m_ptr << ".\n";
	m_definition = definition;
	
	CComBSTR st_val;
	COMTHROW( m_ptr->get_StrAttrByName( CComBSTR( "CFuncStereotype"), &st_val));
	std::string stereotype = Util::Copy( st_val);
	if ( stereotype == "attribute" && ! paramlist.empty()) 
	{
		global_vars.err << MSG_ERROR << "Attribute cannot have parameters. Parameterlist is ignored for Constraint Function: " << m_ptr << ".\n";
		paramlist.empty();
	}
	m_stereotype = stereotype;

	//m_defdForNamesp = m_ptr->getAttribute("DefinedForNamespace")->getStringValue();
	m_defdForNamesp = m_namespace;
}

/*virtual*/ std::string ConstraintFuncRep::getName() const
{
	ASSERT( m_ptr);
	CComBSTR nm;
	COMTHROW( m_ptr->get_Name( &nm));
	return Util::Copy( nm);
}

std::string ConstraintFuncRep::doDump()
{
	fetch();
	std::string mmm = "";
	
	mmm += indStr() + "<constraint type=\"function\" name=\"" + getName() + "\"";
	///z dump either the m_namespace variable /or/ the specific defdForNamesp variable owned by this
	///z m_namespace or m_defdForNamesp
	///z dump only if the object belongs to main namespace
	if( !m_defdForNamesp.empty() && m_ptr && Util::islibobj( m_ptr)) mmm+= " defdfornamesp = \"" + m_defdForNamesp + "\"";
	mmm += ">\n";
	++ind;
	mmm += indStr() + "<![CDATA[" 
		+ m_stereotype + ";" + m_context + ";" 
		+ m_parameterlist + ";" + m_returntype + ";\n";
	mmm += indStr() + m_definition + "]]>\n";
	--ind;
	mmm += indStr() + "</constraint>\n"; 

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

#include "MyUtil.h"
#include "ReferenceRep.h"
#include "ModelRep.h"
#include "Dumper.h"
#include "Broker.h"

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

#include "globals.h"
extern Globals global_vars;


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


ModelRep::~ModelRep()
{
	m_initialRoleMap.clear();
	m_finalRoleMap.clear();
	m_initialAspectList.clear();
	m_finalAspectList.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 << MSG_ERROR << "Error: Found duplicate role \"" << role.getSmartRoleName() << "\" in model \"" << m_ptr << "\"\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::addAspect( AspectRep * asp_ptr)
{
	std::vector<AspectRep*>::iterator ii = 
		std::find( m_initialAspectList.begin(), m_initialAspectList.end(), asp_ptr);

	if (ii == m_initialAspectList.end()) // not found
		m_initialAspectList.push_back(asp_ptr);
	else
		global_vars.err << MSG_ERROR << "CHECK: Model \"" << m_ptr << "\" has aspect \"" << asp_ptr->getPtr() << "\" associated twice\n";
}


const ModelRep::AspectRepPtrList& ModelRep::getAspectRepPtrList() const
{
	return m_initialAspectList;
}


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


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 << MSG_ERROR << "Error: Found duplicate final role \"" << role.getSmartRoleName() << "\" in model \"" << m_ptr << "\"\n";
}

bool ModelRep::getFinalRoles( const FCO * ptr, RoleMapValue& map_val) const
{
	RoleMap_ConstIterator it = m_finalRoleMap.find( const_cast<FCO *>( 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()
{
	std::vector<FCO*> model_descendants;
	this->getImpDescendants( model_descendants);
	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 << MSG_ERROR << "Error: nonmodel kind " << (*model_it)->getPtr() << " as model descendant\n";
		ModelRep * mod_desc_ptr = dynamic_cast<ModelRep*>(*model_it);
		if (!mod_desc_ptr) global_vars.err << MSG_ERROR << "Error: model descendant badly casted to model\n";
					
		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)
				{
					// the descendants must have a separate role for each initial role
					// this role is inherited and has long form depending on the hierarchy_flag
					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);
				}
			}
		}
	}
}


void ModelRep::sortMyAspects()
{
	// sort my aspects based on lessThan
	AspectCompare asp_less_than;
	std::sort( m_finalAspectList.begin(), m_finalAspectList.end(), asp_less_than);
}


void ModelRep::createPartsInModelAspects()
{
	RoleMap_Iterator role_it = m_finalRoleMap.begin();
	// for all roles in this model
	for( ; role_it != m_finalRoleMap.end(); ++role_it)
	{
		RoleStringLex lex;
		std::sort( role_it->second.begin(), role_it->second.end(), lex);
		std::vector<AspectRep*>::iterator asp_it = m_finalAspectList.begin();
		// for all my aspects 
		for( ; asp_it != m_finalAspectList.end(); ++asp_it)
		{
			// the fco which owns the roles
			RoleMapKey fco_ptr = role_it->first;
			// if part (fco) is intended to be in the aspect
			if ( !fco_ptr->isAbstract())
			{
				if ( (*asp_it)->findFinalFCO( fco_ptr) || (*asp_it)->isDummy())
				{
					// each role of fco is member of aspect
					RoleSeries_Iterator jt = role_it->second.begin();
					for( ; jt != role_it->second.end(); ++jt)
					{
						PartRep pr( *jt, *asp_it);
						(*asp_it)->addPart2Map( this, pr); // add parts to the aspect
					}
				}
				else
				{
					// some roles are going to become part of aspect
					RoleSeries_Iterator jt = role_it->second.begin();
					for( ; jt != role_it->second.end(); ++jt)
					{
						if ( (*asp_it)->findFinalRole( *jt)) // this role is intended to be in the aspect
						{
							PartRep pr( *jt, *asp_it);
							(*asp_it)->addPart2Map( this, pr); // add parts to the aspect
						}
					}
				}
			}
		}
	}
}


const ModelRep::AspectRepPtrList& ModelRep::getFinalAspectRepPtrList() const
{
	return m_finalAspectList;
}


void ModelRep::addFinalAspect( AspectRep * asp_ptr)
{
	std::vector<AspectRep*>::iterator ii = 
		std::find( m_finalAspectList.begin(), m_finalAspectList.end(), asp_ptr);

	if (ii == m_finalAspectList.end()) // not found
		m_finalAspectList.push_back(asp_ptr);
	/*else Not an error because of multiple inheritance
		global_vars.err << getName() << " has aspect " << asp_ptr->getName() << " associated twice\n";*/
}


void ModelRep::addFinalAspectList(const AspectRepPtrList& l)
{
	std::vector<AspectRep*>::const_iterator ii = l.begin();
	for( ; ii != l.end(); ++ii)
		addFinalAspect(*ii);
}


int ModelRep::howManyAspects() const
{
	return m_finalAspectList.size();
}


AspectRep * ModelRep::getFirstAspect() const
{
	unsigned int i;
	unsigned sel_i = -1;
	for( i = 0; i < m_finalAspectList.size(); ++i)
	{
		if (sel_i == -1)
			sel_i = 0;
		else 
		{
			AspectRep * curr_best = m_finalAspectList[sel_i];
			if ( !curr_best->lessThan( *m_finalAspectList[i]))
			sel_i = i;
		}
	}
	if ( sel_i != -1) return m_finalAspectList[sel_i];
	else return 0;
}


bool ModelRep::findAspect( const AspectRep * one_asp) const
{
	std::vector<AspectRep*>::const_iterator ii = 
		std::find( m_finalAspectList.begin(), m_finalAspectList.end(), one_asp);

	return ii != m_finalAspectList.end(); // found
}


/*
The aspect_set contains aspects with exactly the same name!
This method gives back an aspect pointer with the following features:
-the model owns this aspect
-the aspect is in the incoming set

In other words the first aspect from the intersection of the incoming aspect_set and
the m_finalAspectList
*/
AspectRep* ModelRep::getMyFirstAspectFromSet( const std::vector<AspectRep *> & aspect_set) const
{
	bool found = false;
	
	std::vector<AspectRep *>::const_iterator aspects_it = aspect_set.begin();
	while( aspects_it != aspect_set.end() && !found)
	{
		std::vector<AspectRep*>::const_iterator ii = 
			std::find( m_finalAspectList.begin(), m_finalAspectList.end(), *aspects_it);

		found = ii != m_finalAspectList.end();
		if (!found) ++aspects_it;
	}

	if (found)
		return *aspects_it;
	else 
		return 0;
}


/* 
how many of my aspects contain part/FCO as an aspect member
*/
int ModelRep::searchMyAspectsForPart( PartRep& part) const
{
	const FCO * asp_element = part.getFCOPtr();
	unsigned int i = 0;
	int count = 0;
	while ( i < m_finalAspectList.size())
	{
		if ( m_finalAspectList[i]->findFinalFCO( asp_element) ||
			m_finalAspectList[i]->findFinalRole( *part.getRoleRepPtr()) )
			++count;
		++i;
	}
	return count;
}


void ModelRep::getAspectNames(CStringList &list) const
{
	unsigned int i = 0;
	while ( i < m_finalAspectList.size())
	{
		list.AddTail(m_finalAspectList[i]->getName().c_str());
		++i;
	}
}


std::string ModelRep::doDump()
{
	bool error = false;
	std::string m_ref = askMetaRef();

	std::string model_name = getName();
	std::string mmm = indStr() + "<model name = \"" + model_name + "\" metaref = \"" + m_ref + "\"";

	std::string dumped_attr_list = dumpAttributeList();
	mmm += dumped_attr_list;
	mmm +=" >\n";
	dumped_attr_list = dumpAttributeList( true); // check viewable ->for aspects
	++ind;
	mmm += dumpDispName();
	++ind;
	mmm += dumpNamePosition();
	mmm += dumpGeneralPref();

	mmm += dumpIcon();
	mmm += dumpPortIcon();
	mmm += dumpDecorator();
	mmm += dumpHotspotEnabled();
	mmm += dumpTypeShown();
	mmm += dumpSubTypeIcon();
	mmm += dumpInstanceIcon();
	mmm += dumpNameWrap();
	mmm += dumpNameEnabled();
	--ind;
	mmm += dumpConstraints();
	mmm += dumpAttributes();

	std::vector<std::string> role_lines_to_dump;
	std::vector< RoleMapKey> key_list;
	// all roles (final)
	RoleMap_Iterator it = m_finalRoleMap.begin();
	for( ; it != m_finalRoleMap.end(); ++it)
		key_list.push_back( it->first);

	AnyLexicographicSort any_lex;
	std::sort( key_list.begin(), key_list.end(), any_lex);
	
	std::vector< RoleMapKey>::iterator key_it = key_list.begin();
	for( ; key_it != key_list.end(); ++key_it )
	{
		//RoleMapKey ptr = it->first;
		//RoleMapValue &roles = it->second;
		RoleMapKey ptr = *key_it;
		RoleMapValue &roles = m_finalRoleMap[ ptr];
		RoleSeries_Iterator jt = roles.begin();
		for( ; jt != roles.end(); ++jt)
			if (!jt->getFCOPtr()->isAbstract())
			{
				const std::string &role_name = jt->getSmartRoleName();
				const std::string &kind_name = ptr->getName();

				std::string m_ref = jt->getFCOPtr()->askMetaRef("/" + model_name + "/" + role_name);
				//std::string role_line = indStr() + "<role name = \"" + role_name + "\" metaref = \"" + m_ref +"\" kind = \"" + kind_name + "\"><dispname>" + role_name + "</dispname></role>\n";
				std::string role_line = indStr() + "<role name = \"" + role_name + "\" metaref = \"" + m_ref +"\" kind = \"" + kind_name + "\"></role>\n";
				
				if ( std::find(role_lines_to_dump.begin(), 
					role_lines_to_dump.end(), role_line) 
					!= role_lines_to_dump.end()) // found
				{
					RoleRep &r = *jt;
					global_vars.err << MSG_ERROR << "Duplicate role line found: " << role_line << "\n" 
						<< MSG_NORMAL
						<< role_name << " of kind " << kind_name
						<< " in model " << m_ptr << ". Details of the 2nd role following: "
						<< (r.isInheritedRole()?"":"Not ") << "Inherited Role, "
						<< (r.isLongForm()?"":"Not ") << "Long form, "
						<< "Is " << (r.isPort()?"":"Not ") << "Port, "
						<< "Cardinality: " << r.getCardinality() << " Not dumping twice.\n";
					if (!error) 
					{
						TO("Please check the metamodel for duplicate roles.");
						error = true;
					}
				}
				else
					role_lines_to_dump.push_back( role_line);
			}
		++it;
	}
	StringLex lex;
	std::sort( role_lines_to_dump.begin(), role_lines_to_dump.end(), lex);

	std::vector<std::string>::iterator sorted_list_it = role_lines_to_dump.begin();
	for( ; sorted_list_it != role_lines_to_dump.end(); ++sorted_list_it)
		mmm += *sorted_list_it;

	role_lines_to_dump.clear();

	// aspects
	{
		AspectCompare asp_less_than;
		std::sort( m_finalAspectList.begin(), m_finalAspectList.end(), asp_less_than);
		std::vector<AspectRep *>::iterator asp_it = m_finalAspectList.begin();
		for( ; asp_it != m_finalAspectList.end(); ++asp_it)
		{
			AspectRep * asp_ptr = *asp_it;
			std::string asp_name = asp_ptr->getName();
			std::string m_ref = asp_ptr->askMetaRef("/" + model_name);

			mmm += indStr() + "<aspect name = \"" + asp_name + "\" metaref = \"" + m_ref + "\"";
			mmm += dumped_attr_list;
			mmm +=" >\n";

			++ind;

			std::string asp_disp = asp_ptr->getDispName();
			if (!asp_disp.empty() && asp_disp != asp_name) // if not empty and not the same
				mmm += asp_ptr->dumpDispName();

			std::vector< std::string> part_lines_to_dump;

			const AspectRep::PartRepSeries parts = (*asp_it)->getPartSeries( this);
			AspectRep::PartRepSeries_ConstIterator part_it = parts.begin();
			for( ; part_it != parts.end(); ++part_it)
			{
				std::string r_name = part_it->getRoleRepPtr()->getSmartRoleName();

				// get values from the registry
				std::string regPath, regVal1, regVal2;

				// inquiring the registry for the primary asp value
				regPath = "PrimaryAspects/" + model_name + ":" + r_name + "/" + asp_name;
				//BON::FCO bon_ptr = part_it->getFCOPtr()->getPtr();
				//regVal1 = bon_ptr->getRegistry()->getValueByPath(regPath);
				regVal1 = Util::gvbp( part_it->getFCOPtr()->getMyRegistry(), regPath);
				
				std::string m_ref = part_it->getFCOPtr()->askMetaRef( model_name + '/' + r_name + '/' + asp_name);

				//if ( res ) part_it->setPrimary( regVal1 == "yes");
				
				bool is_model = ( part_it->getFCOPtr()->getMyKind() == Any::MODEL);

				bool is_ref_to_model = false;
				if ( part_it->getFCOPtr()->getMyKind() == Any::REF)
				{
					const ReferenceRep * ref_ptr = dynamic_cast<const ReferenceRep *>( part_it->getFCOPtr());
					is_ref_to_model = ref_ptr->pointsToModels();
				}

				std::string is_port_str = part_it->getRoleRepPtr()->isPort()?"yes":"no";
				std::string primary_str = (!regVal1.empty() && regVal1=="no")?"no":"yes";
				std::string kind_aspect_name = "";

				if ( is_model || is_ref_to_model)
				{
					// inquiring the registry for the kind asp value
					regPath = "KindAspects/" + model_name + ":" + r_name + "/" + asp_name;
					//regVal2 = bon_ptr->getRegistry()->getValueByPath(regPath);
					regVal2 = Util::gvbp( part_it->getFCOPtr()->getMyRegistry(), regPath);
					
					if ( regVal2 != "__GME_default_mechanism" && !regVal2.empty() && regVal2.find_first_not_of(' ') != std::string::npos) // trim it
						kind_aspect_name = std::string("\" kindaspect = \"") + regVal2;
#if( _DEBUG)
					else
						global_vars.err << "Empty kindaspect value left out. Model: " << model_name << " Aspect: " << asp_name << " Role: " << r_name << "\n";
#endif
				}
				std::string part_line = "<part metaref = \"" + m_ref + "\" role = \"" + r_name + "\" primary = \"" + primary_str + kind_aspect_name +"\" linked = \"" + is_port_str + "\"></part>";
				
				if ( std::find( part_lines_to_dump.begin(), part_lines_to_dump.end(), part_line) !=
					part_lines_to_dump.end()) // found
				{
					global_vars.err << MSG_ERROR << "Duplicate part found. Not dumping twice: " << part_line << "\n";
					if (!error) 
					{
						TO("Please check the metamodel for duplicate parts.");
						error = true;
					}
				}
				else
					part_lines_to_dump.push_back( part_line);
			}
			
			PartStringLex lex;
			std::sort( part_lines_to_dump.begin(), part_lines_to_dump.end(), lex);
			std::vector<std::string>::iterator part_lines_it = part_lines_to_dump.begin();
			for( ; part_lines_it != part_lines_to_dump.end(); ++part_lines_it)
				mmm += indStr() + *part_lines_it + "\n";

			part_lines_to_dump.clear();
			--ind;
			mmm += indStr() + "</aspect>\n";
		}
	}

	--ind;
	mmm += indStr() + "</model>\n";
	return mmm;
}


bool ModelRep::checkMyAspects( Sheet * s)
{
	bool no = (howManyAspects() >= 1);
	if (!no) 
	{
		global_vars.err << MSG_WARNING << "Warning: Model \"" << m_ptr << "\" has no aspect defined.\n";
		AspectRep * asp = s->createAspectRep( 0, 0);
		this->addFinalAspect( asp);
		no = true;
	}
	return no;
}


void ModelRep::createConstraints( Sheet * s)
{
	RoleMap_ConstIterator it = m_initialRoleMap.begin();
	for ( ; it != m_initialRoleMap.end(); ++it)
	{
		FCO * const ptr = it->first;
		
		std::vector<FCO*> descendants;
		ptr->getIntDescendants( descendants);
		
		RoleSeries_ConstIterator jt = it->second.begin();
		for( ; jt != it->second.end(); ++jt)
		//if (!jt->getFCOPtr()->isAbstract())
		{
			const RoleRep & r = *jt;
			std::string card = jt->getCardinality();
			{
				std::string str_expr_end;
				std::string str_card_context;
				str_card_context = "[containment] In model: " + r.getModelRepPtr()->getName() + ", Role: " + r.getSmartRoleName();
				bool valid_constr = ! Dumper::doParseCardinality( card, "partCount", str_card_context, str_expr_end);
				if ( ! valid_constr )
				{
					global_vars.err << MSG_ERROR << "Ignoring invalid cardinality string in role: " << r.getSmartRoleName() << ". String: " << card << ".\n";
				}

				//CBuilderConnection* pContainment = pRole->conn;

				// Build the Beginning of the Expression

				std::string str_expr_begin = 
					"let partCount = self.parts( \"" + r.getSmartRoleName() + "\" ) -> size ";

				std::vector<FCO*>::iterator desc_it = descendants.begin();
				for( ; desc_it != descendants.end(); ++desc_it)
					if ( !(*desc_it)->isAbstract())
						str_expr_begin += "+ self.parts( \"" + (*desc_it)->getName() + r.getOnlyRoleName() + "\" ) -> size ";

				str_expr_begin += "in\n                     ";

				// If Cardinality was appropriate

				if ( valid_constr && ! str_expr_end.empty() ) {

					// Build Name, EventMask, Description

					int id = Broker::getNextConstraintId();
					char str_id[64];
					sprintf( str_id, "%d", id);

					std::string str_cons_name;
					str_cons_name = "Valid" + getName() + "PartCardinality" + std::string(str_id);
					int pos = str_cons_name.find( "::");
					if( pos != std::string::npos) 
						str_cons_name.replace( pos, 2, 2, '_');

					int iEventMask = 0;
					char chMask[64];
					sprintf( chMask, "%x", iEventMask );

					std::string str_desc;
					str_desc = "Multiplicity of parts, which are contained by " 
						+ getName() +	", has to match "+ card + ".";

					ConstraintRep * cr = s->createConstraintRep( 0);
					std::string s_b = str_expr_begin + str_expr_end;
					cr->init( str_cons_name, /*mask:*/global_vars.genConstr.reg_cont_mask, "1", global_vars.genConstr.priority, s_b, str_desc);

					this->addInitialConstraintRep( cr); // <!> to be dec'd whether initial or final
					cr->attachedTo();
				}
			}
		}
	}
}

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

#include "MyUtil.h"
#include "ConstraintRep.h"

#include "globals.h"
extern Globals global_vars;


ConstraintRep::ConstraintRep( IMgaFCO* ptr)
: Any( ptr),
	m_attached( false), m_name(""), m_description(""),
	m_defaultParams(""), m_equation(""), 
	m_priority(0), m_depth(), m_eventMask(0)
{
	if (m_ptr) 
	{
		fetch();
		//m_name = Any::getName();
		m_name = getName();
	}
}

void ConstraintRep::attachedTo()
{
	m_attached = true;
}

bool ConstraintRep::isAttached() const
{
	return m_attached;
}

void ConstraintRep::fetch()
{
	std::string desc = Util::getStrAttr( m_ptr, "ConstraintDescription");

	if(desc.empty()) global_vars.err << MSG_ERROR << "No description found for constraint " << m_ptr << "\n";
	m_description = desc;

	std::string expr = Util::getStrAttr( m_ptr, "ConstraintEqn");
	if(expr.empty()) global_vars.err << MSG_ERROR << "No equation found for constraint " << m_ptr << "\n";
	m_equation = expr;

	std::string priority_str = Util::getStrAttr( m_ptr, "ConstraintPriority");
	if(sscanf(priority_str.c_str(),"%d",&m_priority) != 1)
		m_priority = 2;
	m_priority = max(0,min(5,m_priority));

	m_depth = Util::getStrAttr( m_ptr, "Depth");

	//m_defdForNamesp = m_ptr->getAttribute("DefinedForNamespace")->getStringValue();
	//m_defdForNamesp = m_namespace;


	m_eventMask = 0;
	fetchEventAttribute("CloseEvent",OBJEVENT_CLOSEMODEL);
	fetchEventAttribute("NewChildEvent",OBJEVENT_NEWCHILD);
	fetchEventAttribute("LostChildEvent",OBJEVENT_LOSTCHILD);
	fetchEventAttribute("CreateEvent",OBJEVENT_CREATED);
	fetchEventAttribute("DeleteEvent",OBJEVENT_DESTROYED);
	fetchEventAttribute("ConnectEvent",OBJEVENT_CONNECTED);
	fetchEventAttribute("DisconnectEvent",OBJEVENT_DISCONNECTED);
	fetchEventAttribute("ReferenceEvent",OBJEVENT_REFERENCED);
	fetchEventAttribute("UnReferenceEvent",OBJEVENT_REFRELEASED);
	fetchEventAttribute("AddSetEvent",OBJEVENT_SETINCLUDED);
	fetchEventAttribute("RemoveSetEvent",OBJEVENT_SETEXCLUDED);
	fetchEventAttribute("ChangeRelationEvent",OBJEVENT_RELATION);
	fetchEventAttribute("ChangeAttributeEvent",OBJEVENT_ATTR);
	fetchEventAttribute("ChangePropertyEvent",OBJEVENT_PROPERTIES);
	fetchEventAttribute("DeriveEvent",OBJEVENT_SUBT_INST);
	fetchEventAttribute("MoveEvent",OBJEVENT_PARENT);
}

void ConstraintRep::fetchEventAttribute( const std::string& event_name, unsigned int event_flag)
{
	bool flag;
	VARIANT_BOOL vb = VARIANT_FALSE;
	COMTHROW( m_ptr->get_BoolAttrByName( Util::Copy( event_name), &vb));
	flag = vb == VARIANT_TRUE;
	if ( flag)
		m_eventMask |= event_flag;
}

/*virtual*/ std::string ConstraintRep::getName() const
{
#if(0)
	// if real object (existing in the BON) the constructor has initialized m_name
	// if artificial object then the init() did it
	return m_name;
#else
	// if real object we can inquire its name
	// if artificial object then we use the value init() has set
	if( m_ptr) {
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return Util::Copy( nm);
	}
	else       return m_name;
#endif
}

/*virtual*/ std::string ConstraintRep::getDispName() const
{
	return m_description;
}

void ConstraintRep::init( const std::string& name, 
												 int mask, const std::string& depth, int priority, 
												 const std::string& equation, const std::string& disp_name)
{
	m_name = name;
	m_description = disp_name;
	//m_defaultParams = ...
	m_equation = equation;
	m_priority = priority;
	m_depth = depth;
	m_eventMask = mask;
}

std::string ConstraintRep::doDump()
{
	m_defdForNamesp = m_namespace;
	std::string mmm = "";

	char mask[64]; sprintf(mask,"%x", m_eventMask);
	//char depth_str[10]; sprintf( depth_str, "%d", m_depth);
	char priority_str[2]; sprintf( priority_str, "%d", m_priority);
	mmm += indStr() + "<constraint name=\"" + m_name + "\" eventmask = \"0x" + std::string(mask) + 
		"\" depth = \"" + m_depth;
	///z dump either the m_namespace variable /or/ the specific defdForNamesp variable owned by this
	///z m_namespace or m_defdForNamesp
	///z dump only if the object belongs to main namespace
	if( !m_defdForNamesp.empty() && m_ptr && Util::islibobj( m_ptr)) mmm+= "\" defdfornamesp = \"" + m_defdForNamesp;
	mmm += "\" priority = \"" + std::string(priority_str) + "\">\n";

	++ind;
	mmm += indStr() + "<![CDATA[" + m_equation + "]]>\n";
	mmm += dumpDispName();
	--ind;
	mmm += indStr() + "</constraint>\n";

	return mmm;
}

--- NEW FILE: AspectRep.h ---
#ifndef ASPECTREP_H
#define ASPECTREP_H

#include "Any.h"
#include "PartRep.h"

#include "map"
#include "vector"
#include "FCO.h"

class PartRep;
class RoleRep;
class AspectRep;
class ModelRep;

class PartCompare
{
public:
	bool operator()( const PartRep& peer1, const PartRep& peer2) const;
};

class AspectCompare
{
public:
	bool operator()( const AspectRep* peer1, const AspectRep* peer2) const;
};

class AspNamePriorityComp
{
public:
	typedef std::pair< std::string, int> Type;
	bool operator() ( const Type& p1, const Type& p2) const;
};

class AspectRep : public Any 
{
public: // types
	typedef std::vector< PartRep > PartRepSeries;
	typedef PartRepSeries::iterator PartRepSeries_Iterator;
	typedef PartRepSeries::const_iterator PartRepSeries_ConstIterator;
	typedef ModelRep* Key;
	typedef std::map< Key, PartRepSeries> ModelPartsMap;
	typedef ModelPartsMap::iterator ModelPartsMap_Iterator;
public:
	AspectRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~AspectRep();
	/*virtual*/ std::string doDump();
	/*virtual*/ Any::KIND_TYPE getMyKind() const;
	/*virtual*/ std::string getName() const;
	/*virtual*/ std::string getDispName() const;

	/*virtual*/ std::string getMyPrefix() const;
	/*virtual*/ CComPtr<IMgaRegNode> getMyRegistry() const;
	static std::string getMyPrefix( IMgaFCO* fco, IMgaFolder* f);
	static CComPtr<IMgaRegNode> getMyRegistry( IMgaFCO* fco, IMgaFolder* f);

	void addPart2Map( ModelRep * mptr, const PartRep & part);

	void addFCO( FCO* fco); // to the initial list
	void addRRole( RoleRep & role);
	bool findFinalFCO( const FCO * fco) const; // in the final list
	bool findFinalRole( const RoleRep&) const;

	void extendAspectWithDescendants();
	void sortPartMap();

	const PartRepSeries& getPartSeries( ModelRep* mod_ptr);
	bool lessThan( const AspectRep& rep) const;
	void getXY( unsigned int * x, unsigned int *y) const;

	void setPriority( int pr);
	int getPriority() const;

	bool isDummy() const;
	
	static const std::string m_aspectRegistryRoot;
	static const std::string m_aspectMetaRefsRoot;
	static const std::string m_aspectNamesRoot;
protected:
	// this int is set if contains non-zero value
	// and if one of the aspects contains non-zero value it means that the aspects are
	// sorted based on this
	int		m_priority;
	
	/**
	 * inital and final list of FCO-s intended to be part of the Aspect
	 *
	 */
	std::vector<FCO*>		m_fcoInitialList;
	std::vector<RoleRep>	m_roleInitialList;
	std::vector<FCO*>		m_fcoFinalList;
	std::vector<RoleRep>	m_roleFinalList;

	ModelPartsMap			m_partsMap;

	/**
	 * This pointer is in charge of the aspect name, 
	 * NOTE: it may be an Aspect or SameAspect BON object
	 */
	CComPtr<IMgaFCO> m_respPointer;

private: // forbiding copy
	AspectRep(const AspectRep&);
	const AspectRep& operator=(const AspectRep&);
};
#endif //ASPECTREP_H

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

#include "MyUtil.h"
#include "AttributeRep.h"
#include "FCO.h"
#include <algorithm>
#include "globals.h"
#include "Dumper.h"
extern Globals global_vars;
extern int ind;


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


AttributeRep::~AttributeRep()
{
}

/*virtual*/ std::string AttributeRep::getName() const
{
	if ( this->m_ptr)
	{
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return Util::Copy( nm);
	}
	return "NullPtrError";
}

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::dumpHelp()
{
	std::string mmm;
	std::string help = Dumper::xmlFilter( Util::getStrAttr( m_ptr, "Help"));
	if( !help.empty())
		mmm += indStr() + "<regnode name=\"help\" value = \"" + help + "\"></regnode>\n";

	return mmm;
}


std::string AttributeRep::getMetaRef(const std::string & owner)
{
	std::string m_ref;
	std::string token = "";
	if ( !owner.empty()) token = "/" + owner;
	m_ref = askMetaRef(token);

	return m_ref;
}


void AttributeRep::getXY( unsigned int * x, unsigned int * y) const
{
	std::string val = Util::getReg( m_ptr, "PartRegs/Attributes/Position");
	if( !val.empty())
	{
		int v = sscanf( val.c_str(), "%d, %d", x, y);
		ASSERT( v == 2);
	}
}


bool AttributeRep::lessThan( const AttributeRep * rep) const
{
	std::string m = getName();
	unsigned int x, y;
	unsigned int rep_x, rep_y;
	getXY( &x, &y);
	rep->getXY( &rep_x, &rep_y);
	return ( y < rep_y || (y == rep_y && x < rep_x ));
}


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 << MSG_ERROR << m_ptr << " attribute owned by " << owner->getPtr() << " 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;
}


std::string EnumAttributeRep::doDumpAttr(const std::string& owner)
{
	if (m_noOfItems == 0) getMenuItems();
	std::string mmm = "";

	std::string m_ref = getMetaRef( owner);
	std::string viewable = isViewable()?"": " viewable = \"no\"";
	mmm += indStr() + "<attrdef name=\"" + getName() + "\" metaref = \"" + m_ref + "\"" + viewable + " valuetype = \"enum\" defvalue = \"";
	if( m_noOfDefault < m_itemsVal.size())
		mmm += m_itemsVal[m_noOfDefault];
	else
		global_vars.err << MSG_ERROR << "Error: Default enumitem not found in vector of enumerated items. Please check: " << getPtr() << ".\n";
	
	mmm += "\">\n";
	
	++ind;

	std::string prompt = getPrompt();
	if ( !prompt.empty())
		mmm += indStr() + "<dispname>" + prompt + "</dispname>\n";

	for(int i = 0; i < m_noOfItems; ++i)
	{
		mmm+= indStr() + "<enumitem dispname = \"" + m_items[i] + "\" value = \"" + m_itemsVal[i] + "\"></enumitem>\n";
	}

	mmm += dumpHelp();

	--ind;
	mmm += indStr() + "</attrdef>\n";
	return mmm;
}


std::string BoolAttributeRep::doDumpAttr(const std::string& owner)
{
	std::string mmm = "";
	bool on;
	on = Util::getBoolAttr( m_ptr, "BooleanDefault");

	std::string m_ref = getMetaRef( owner);
	std::string viewable = isViewable()?"": " viewable = \"no\"";


	mmm += indStr() + "<attrdef name=\"" + getName() + "\" metaref = \"" + m_ref + "\"" + viewable + " valuetype = \"boolean\" defvalue = \"";
	if (on) mmm += "true";
	else mmm +="false";
	mmm += "\">\n";
	
	++ind;

	std::string prompt = getPrompt();
	if ( !prompt.empty())
		mmm += indStr() + "<dispname>" + prompt + "</dispname>\n";

	mmm += dumpHelp();

	--ind;
	mmm += indStr() + "</attrdef>\n";
	return mmm;
}


std::string FieldAttributeRep::doDumpAttr(const std::string& owner)
{
	std::string mmm = "";
	std::string val_type = Util::getStrAttr( m_ptr, "DataType");
	std::string def_val = Dumper::xmlFilter( Util::getStrAttr( m_ptr, "FieldDefault"));
	std::string content_type = Dumper::xmlFilter( Util::getStrAttr( m_ptr, "ContentType"));

	int multiline, sc;
	std::string multiline_st = Util::getStrAttr( m_ptr, "Multiline");
	sc = sscanf( multiline_st.c_str(), "%u", &multiline);//int multiline = Util::getLongAttr( m_ptr, "Multiline");
	if( !multiline_st.empty()) 
		ASSERT( sc == 1);

	std::string m_ref = getMetaRef( owner);
	std::string viewable = isViewable()?"": " viewable = \"no\"";


	mmm += indStr() + "<attrdef name=\"" + getName() + "\" metaref = \"" + m_ref + "\"" + viewable + " valuetype = \"" + val_type + "\" defvalue = \"" + def_val + "\">\n";
	
	++ind;

	std::string prompt = getPrompt();
	if ( !prompt.empty())
		mmm += indStr() + "<dispname>" + prompt + "</dispname>\n";

	if( multiline > 1)
	{
		char mul[10];
		sprintf(mul, "%i", multiline);
		mmm += indStr() + "<regnode name=\"multiLine\" value = \"" + mul + "\"></regnode>\n";
	}

	if( !content_type.empty())
		mmm += indStr() + "<regnode name=\"content-type\" value = \"" + content_type + "\"></regnode>\n";

	mmm += dumpHelp();

	--ind;
	mmm += indStr() + "</attrdef>\n";
	return mmm;
}

--- 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);

	/*virtual*/ std::string doDump();

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


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

};
#endif //ATOMREP_H

--- NEW FILE: Broker.h ---
#ifndef BROKER_H
#define BROKER_H

#include "MyUtil.h"
#include "Common.h"
#include <list>
#include <string>


class Broker
{
public:
	static const int INVALID_METAREF;
	static const int INITIAL_METAREF;
	static const std::string ROOTFOLDER_METAREF_STR;

	class MetaRefNode {
	public:
		MetaRefNode( IMgaObject* o = 0, IMgaFolder* f = 0, const std::string &p = std::string(""), int m = INVALID_METAREF) : obj(o), folder(f), path(p), metaref(m) {};
		CComPtr<IMgaObject> obj;
		CComPtr<IMgaFolder> folder;
		std::string	path;
		int metaref;
	};

	static void reset();
	static void init();
	static int getNextConstraintId();
	static int getNextMetaRefId();

	static std::string getRegistryTokenName( IMgaObject* obj);
	static void initFromObj( IMgaObject* obj, IMgaFolder* folder, const std::string& kind);
	static void initFromAspectObj( IMgaObject* obj, const std::string& name, IMgaFolder* folder);
	static void initFromRegistry( IMgaObject* obj, IMgaFolder* folder, IMgaRegNode* regNode);

	static void checkDuplicates();


private:
	typedef std::list<MetaRefNode> MetaRefDB;
	typedef std::list<MetaRefNode>::iterator MetaRefDB_Iterator;
	static MetaRefDB m_metaRefDB;
	static int m_firstFree;

	static int m_constraintId;
	static int m_metaRefId;
};

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

#include "Any.h"
#include "PartRep.h"
#include "FCO.h"
#include "ConstraintFuncRep.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<FCO*>::const_iterator FCO_ConstIterator;
	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, getDispName operations
*/
	FolderRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~FolderRep();

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

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

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

	void extendMembership();
	void createConstraints( Sheet * s);
	
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;

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

};
#endif //FOLDERREP_H

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

#include "MyUtil.h"
#include "Any.h"
#include <string>
#include <vector>
#include <set>
#include "logger.h"

/** This class is the abstract base of all kinds of parts/FCOs that can occur during a modeling process. */
class Any;
class ConstraintRep;

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

class Any 
{
public: // constant strings
	static const std::string NamespaceDelimiter_str;//"::"
	static const std::string InRootFolder_str;//"InRootFolder"
	static const std::string DisplayedName_str;//"DisplayedName"

	static const std::string NameSelectorNode_str;
	static const std::string DisplayedNameSelectorNode_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::vector< ConstraintRep* > ConstraintRepPtrList;
	typedef std::vector< ConstraintRep* >::const_iterator ConstraintRepPtrList_ConstIterator;

	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();
	std::string getNamespace() const;

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

	std::string dumpConstraints();

	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; }
	void setDisplayedName( const std::string& dispnm) { m_userSelectedDisplayName = dispnm; }

	virtual std::string getMyPrefix() const;
	virtual CComPtr<IMgaRegNode> getMyRegistry() const;
	CComPtr<IMgaRegNode> getMyRegistryOld() const;

	static std::string getMyPrefix( IMgaFCO* fco, IMgaFolder* f);
	static CComPtr<IMgaRegNode> getMyRegistry( IMgaFCO* fco, IMgaFolder* f);

	bool isFCO() const;
	std::string askMetaRef(const std::string & tok = "") const;

	// constraints
	void addInitialConstraintRep( ConstraintRep * );
	const ConstraintRepPtrList& getInitialConstraintRepPtrList() const;
	void addFinalConstraint( ConstraintRep * constraint);
	void addFinalConstraintList( const ConstraintRepPtrList & list);

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

	// pointer of the parent folder
	// this must be writable because
	// the registry write operations
	// work through this ptr
	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;

	// displayed name (if name selection dialog used) 
	std::string m_userSelectedDisplayName;

	// initial and final constraints
	ConstraintRepPtrList m_initialConstraintList;
	ConstraintRepPtrList m_finalConstraintList;

	// 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 "logger.h"
#include "Token.h"
#include <list>
#include <algorithm>

#include "globals.h"
extern Globals global_vars;


/*static*/ const std::string FCO::IsAbstract_str = "IsAbstract";
/*static*/ const std::string FCO::Icon_str = "Icon";
/*static*/ const std::string FCO::PortIcon_str = "PortIcon";
/*static*/ const std::string FCO::Decorator_str = "Decorator";
/*static*/ const std::string FCO::IsHotspotEnabled_str = "IsHotspotEnabled";
/*static*/ const std::string FCO::IsTypeShown_str = "IsTypeShown";
/*static*/ const std::string FCO::GeneralPreferences_str = "GeneralPreferences";
/*static*/ const std::string FCO::NamePosition_str = "NamePosition";
/*static*/ const std::string FCO::SubTypeIcon_str = "SubTypeIcon";
/*static*/ const std::string FCO::InstanceIcon_str = "InstanceIcon";
/*static*/ const std::string FCO::NameWrapNum_str = "NameWrapNum";
/*static*/ const std::string FCO::IsNameEnabled_str = "IsNameEnabled";


FCO::FCO( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: Any( ptr)
	, m_respPointer( resp_ptr)
	, m_isAbstract( false)
	, m_bAttrIsHotspotEnabled( true)
	, m_bAttrIsTypeShown( false)
	, m_bAttrIsNameEnabled( true)
	, m_iAttrNamePosition( 0)
	, m_iAttrNameWrapNum( 0)
	, m_references()
	, m_partOf()
	, m_partOfFinal()
	, m_initialAttributeList()
	, m_finalAttributeList()
{ 
	for ( int i = 0; i < NUMBER_OF_INHERITANCES; ++i)
	{
		m_childList[i].clear();
		m_parentList[i].clear();
		m_ancestors[i].clear();
		m_descendants[i].clear();
	}
}


FCO::~FCO() 
{ 
	m_references.clear();
	m_partOf.clear();
	m_partOfFinal.clear();
	m_initialAttributeList.clear();
	m_finalAttributeList.clear();

	for ( int i = 0; i < NUMBER_OF_INHERITANCES; ++i)
	{
		m_childList[i].clear();
		m_parentList[i].clear();
		m_ancestors[i].clear();
		m_descendants[i].clear();
	}
}


std::string FCO::getName() const
{
	if( m_respPointer)
	{
		CComBSTR nm;
		COMTHROW( m_respPointer->get_Name( &nm));
		return m_namespace + (m_namespace.empty()?"":Any::NamespaceDelimiter_str) + Util::Copy( nm);
	}
	else
	{
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return m_namespace + (m_namespace.empty()?"":Any::NamespaceDelimiter_str) + Util::Copy( nm);
	}
}


std::string FCO::getDispName() const
{
	if( m_respPointer) // not a plain fco, it has its resppointer set
	{
		// previously return "";
		return m_userSelectedDisplayName;
	}
	else
	{
		return m_sAttrDispName;
	}
}


void FCO::initAttributes()
{
	m_isInRootFolder = m_isInRootFolder || Util::getBoolAttr( m_ptr, InRootFolder_str);

	// isAbstract: true iff all values (which are set) are true
	bool isabs = true; // if any of the set values is false it will change
	bool isabs_set = false;
	//m_isAbstract = m_isAbstract && m_ptr->getAttribute( IsAbstract_str)->getBooleanValue();
	if( Util::isAttrStatHere( m_ptr, IsAbstract_str))
	{
		isabs = isabs && Util::getBoolAttr( m_ptr, IsAbstract_str);
		isabs_set = true;
	}

	// general pref
	bool isgenpref_set = false;
	if( Util::isAttrStatHere( m_ptr, GeneralPreferences_str))
	{
		m_sAttrGenPref = Util::getStrAttr( m_ptr, GeneralPreferences_str);
		isgenpref_set = true;
	}

	// displayed name
	bool isdispname_set = false;
	if( Util::isAttrStatHere( m_ptr, DisplayedName_str))
	{
		m_sAttrDispName = Util::getStrAttr( m_ptr, DisplayedName_str);
		isdispname_set = true;
	}

	// --applicable to non proxies only--

	bool ishotspotenabled_set = false;
	if( Util::isAttrStatHere( m_ptr, IsHotspotEnabled_str))
	{
		m_bAttrIsHotspotEnabled	= Util::getBoolAttr( m_ptr, IsHotspotEnabled_str);// def val: TRUE (dumped if FALSE)
		ishotspotenabled_set = true;

	}
	
	bool istypeshown_set = false;
	if( Util::isAttrStatHere( m_ptr, IsTypeShown_str))
	{
		m_bAttrIsTypeShown		= Util::getBoolAttr( m_ptr, IsTypeShown_str);		// def val: FALSE (dumped if TRUE)
		istypeshown_set = true;
	}
	
	bool isnameenabled_set = false;
	if( Util::isAttrStatHere( m_ptr, IsNameEnabled_str))
	{
		m_bAttrIsNameEnabled	= Util::getBoolAttr( m_ptr, IsNameEnabled_str);	// def val: TRUE (dumped if FALSE)
		isnameenabled_set = true;
	}

	bool isnamepos_set = false;
	//if( Util::isAttrStatHere( m_ptr, NamePosition_str))
	{
		m_iAttrNamePosition	= Util::getLongAttr( m_ptr, NamePosition_str);// dumped anyway
		isnamepos_set = true;
	}

	bool isnamewrapnum_set = false;
	if( Util::isAttrStatHere( m_ptr, NameWrapNum_str))
	{
		m_iAttrNameWrapNum	= Util::getLongAttr( m_ptr, NameWrapNum_str); // dumped if not 0
		isnamewrapnum_set = true;
	}

	bool icon_set = false;
	if( Util::isAttrStatHere( m_ptr, Icon_str))
	{
		m_sAttrIcon = Util::getStrAttr( m_ptr, Icon_str); // dumped if not empty
		icon_set = true;
	}

	bool porticon_set = false;
	if( Util::isAttrStatHere( m_ptr, PortIcon_str))
	{
		m_sAttrPortIcon = Util::getStrAttr( m_ptr, PortIcon_str);
		porticon_set = true;
	}

	bool subtypeicon_set = false;
	if( Util::isAttrStatHere( m_ptr, SubTypeIcon_str))
	{
		m_sAttrSubTypeIcon = Util::getStrAttr( m_ptr, SubTypeIcon_str);
		subtypeicon_set = true;
	}

	bool instanceicon_set = false;
	if( Util::isAttrStatHere( m_ptr, InstanceIcon_str))
	{
		m_sAttrInstanceIcon = Util::getStrAttr( m_ptr, InstanceIcon_str);
		instanceicon_set = true;
	}

	bool decorator_set = false;
	if( Util::isAttrStatHere( m_ptr, Decorator_str))
	{
		m_sAttrDecorator = Util::getStrAttr( m_ptr, Decorator_str);
		decorator_set = true;
	}

	// proxies have only the following attributes: abstract, inrootfolder, displayedname, generalpref
	// real objects have beside these other attributes

	// abstract iff all equivalent classes are abstract
	EquivSet_ConstIterator it = m_equivs.begin();
	for ( ; it != m_equivs.end(); ++it)
	{
		if ( *it == m_ptr) continue;
		
		// --the following 4 attributes are applicable to proxies as well--
		// InRootFolder: true if one is at least true
		m_isInRootFolder = m_isInRootFolder || Util::getBoolAttr( (*it), InRootFolder_str);

		// isAbstract: true if all objects are true
		//m_isAbstract = m_isAbstract && (*it)->getAttribute( IsAbstract_str)->getBooleanValue();
		if( Util::isAttrStatHere( *it, IsAbstract_str)) // if set by the user
		{
			isabs = isabs && Util::getBoolAttr( (*it), IsAbstract_str);
			isabs_set = true;
		}
#if(1)
		// general pref
		if ( !isgenpref_set && Util::isAttrStatHere( *it, GeneralPreferences_str))
		{
			m_sAttrGenPref = Util::getStrAttr( (*it), GeneralPreferences_str);
			isgenpref_set = true;
		}

		// displayed name
		if ( !isdispname_set && Util::isAttrStatHere( *it, DisplayedName_str))
		{
			m_sAttrDispName = Util::getStrAttr( (*it), DisplayedName_str);
			isdispname_set = true;
		}

		// --applicable to non proxies only--
		if ( Util::isproxy( *it)) continue;

		if( !ishotspotenabled_set && Util::isAttrStatHere( *it, IsHotspotEnabled_str))
		{
			m_bAttrIsHotspotEnabled	= m_bAttrIsHotspotEnabled || Util::getBoolAttr( (*it), IsHotspotEnabled_str);
			ishotspotenabled_set = true;
		}
		
		if( !istypeshown_set && Util::isAttrStatHere( *it, IsTypeShown_str))
		{
			m_bAttrIsTypeShown		= m_bAttrIsTypeShown || Util::getBoolAttr( (*it), IsTypeShown_str);
			istypeshown_set = true;
		}
		
		if( !isnameenabled_set && Util::isAttrStatHere( *it, IsNameEnabled_str))
		{
			m_bAttrIsNameEnabled	= m_bAttrIsNameEnabled || Util::getBoolAttr( (*it), IsNameEnabled_str);
			isnameenabled_set = true;
		}


		if ( !isnamepos_set && Util::isAttrStatHere( *it, NamePosition_str))
		{
			m_iAttrNamePosition	= Util::getLongAttr( (*it), NamePosition_str);
			isnamepos_set = true;
		}
		if ( !isnamewrapnum_set && Util::isAttrStatHere( *it, NameWrapNum_str))
		{
			m_iAttrNameWrapNum	= Util::getLongAttr( (*it), NameWrapNum_str);
			isnamewrapnum_set = true;
		}


		if ( !icon_set && Util::isAttrStatHere( *it, Icon_str))
		{
			m_sAttrIcon = Util::getStrAttr( (*it), Icon_str);
			icon_set = true;
		}
		if ( !porticon_set && Util::isAttrStatHere( *it, PortIcon_str))
		{
			m_sAttrPortIcon = Util::getStrAttr( (*it), PortIcon_str);
			porticon_set = true;
		}
		if( !subtypeicon_set && Util::isAttrStatHere( *it, SubTypeIcon_str))
		{
			m_sAttrSubTypeIcon = Util::getStrAttr( (*it), SubTypeIcon_str);
			subtypeicon_set = true;
		}
		if ( !instanceicon_set && Util::isAttrStatHere( *it, InstanceIcon_str))
		{
			m_sAttrInstanceIcon = Util::getStrAttr( (*it), InstanceIcon_str);
			instanceicon_set = true;
		}
		if ( !decorator_set && Util::isAttrStatHere( *it, Decorator_str))
		{
			m_sAttrDecorator = Util::getStrAttr( (*it), Decorator_str);
			decorator_set = true;
		}
#endif
	}
	
	if( isabs_set) m_isAbstract = isabs;

}


bool FCO::isAbstract() const
{
	return m_isAbstract;
}


void FCO::abstract( bool is)
{
	m_isAbstract = is;
}


void FCO::iAmPartOf( ModelRep * mod_ptr)
{
	std::vector<ModelRep *>::iterator jt = 
		std::find( m_partOf.begin(), m_partOf.end(), mod_ptr);

	// not inserting two times
	if (jt == m_partOf.end())
		m_partOf.push_back( mod_ptr);
	else { }
}


void FCO::iAmPartOfFinal( ModelRep * mod_ptr)
{
	std::vector<ModelRep *>::iterator jt = 
		std::find( m_partOfFinal.begin(), m_partOfFinal.end(), mod_ptr);

	// not inserting two times
	if (jt == m_partOfFinal.end() )
		m_partOfFinal.push_back( mod_ptr);
	else { }
}


const FCO::ModelRepPtrList& FCO::modelsIAmPartOf()
{
	return m_partOf;
}


const FCO::ModelRepPtrList& FCO::modelsIAmPartOfFinal()
{
	return m_partOfFinal;
}


bool FCO::amIPartOf(const ModelRep * mod_ptr) const
{
	ModelRepPtrList_ConstIterator it = 
		std::find( m_partOf.begin(), m_partOf.end(), mod_ptr);
	return ( it != m_partOf.end());
}


bool FCO::amIPartOfFinal(const ModelRep * mod_ptr) const
{
	ModelRepPtrList_ConstIterator it = 
		std::find( m_partOfFinal.begin(), m_partOfFinal.end(), mod_ptr);
	
	return ( it != m_partOfFinal.end());
}


// returns if this is not part of any model
bool FCO::checkIsPartOf()
{
	return !m_partOf.empty();
}


bool FCO::checkIsPartOfFinal()
{
	return !m_partOfFinal.empty();
}


bool FCO::checkInheritance()
{
	bool same_kind = true;
	KIND_TYPE kind_type = getMyKind();

	INHERITANCE_TYPE type[ NUMBER_OF_INHERITANCES ] ={ REGULAR, INTERFACE, IMPLEMENTATION};
	for(int i = 0; i < NUMBER_OF_INHERITANCES && same_kind; ++i)
	{
		INHERITANCE_TYPE inh_type = type[i];
		std::vector<FCO*> * vectors[] = {
			&m_childList[inh_type], 
			&m_parentList[inh_type], 
			&m_ancestors[inh_type], 
			&m_descendants[inh_type] 
		};
		for(int k = 0; k < 4 && same_kind; ++k)
		{
			std::vector<FCO*>::iterator it = vectors[k]->begin();
			for( ; it != vectors[k]->end() && same_kind; ++it)
				if ((*it)->getMyKind() != FCO_REP)
					same_kind = same_kind && kind_type == (*it)->getMyKind();
		}
	}
	if (!same_kind) 
		global_vars.err << MSG_ERROR << m_ptr << " fco has another kind of ancestor or descendant.\n";
	return same_kind;
}


// initial reference list
void FCO::addRefersToMe( ReferenceRep * ref_obj)
{
	m_references.push_back( ref_obj);
}


const FCO::ReferenceRepList& FCO::getReferences() const
{
	return m_references;
}

// final reference list
void FCO::addFinalRefersToMe( ReferenceRep * ref_obj)
{
	if( std::find( m_finalReferences.begin(), m_finalReferences.end(), ref_obj) == m_finalReferences.end())
		m_finalReferences.push_back( ref_obj);
}


const FCO::ReferenceRepList& FCO::getFinalReferences() const
{
	return m_finalReferences;
}


/*
Dealing with the case when R1->R2->R3->M. 
They all have similar aspects, and connecting is allowed through these.
Previously named getAllMyReferences
*/
FCO::ReferenceRepList FCO::getTransitiveReferencesToMe() const
{
	ReferenceRepList multiple_refs = this->getFinalReferences();
	std::list< ReferenceRep * > ref_list;
	ref_list.insert( ref_list.end(), multiple_refs.begin(), multiple_refs.end());

	while ( !ref_list.empty())
	{
		ReferenceRep * r = *ref_list.begin(); // take a ref from the final references to me
		ref_list.pop_front();
		std::vector< ReferenceRep *> temp = r->getFinalReferences(); // take its references

		std::vector<ReferenceRep *>::iterator temp_it = temp.begin();
		for( ; temp_it != temp.end(); ++temp_it)
		{
			if( std::find( multiple_refs.begin(), multiple_refs.end(), *temp_it) == multiple_refs.end()) // not found a ref in the current transitive ref list
			{
				multiple_refs.push_back( *temp_it); // multiple_refs is growing
				ref_list.push_back( *temp_it); // ref_list contains the new elements
			}
		}
	}
	return multiple_refs;
}


//
// inheritance related methods
//
void FCO::addParent( INHERITANCE_TYPE type, FCO * ptr) 
{ 

	//checking for multiple instances of the same base class
	std::vector<FCO *>::iterator jt = 
		std::find( m_parentList[type].begin(), m_parentList[type].end(), ptr);

	// not inserting two times
	if (jt == m_parentList[type].end())
		m_parentList[type].push_back( ptr);
	else 
	{
		global_vars.err << MSG_WARNING << "CHECK: " << (*jt)->getPtr() <<
			" base class is two times in direct inheritance " <<
			" relation with the derived class " <<
			m_ptr << "\n";
	}
}


void FCO::addChild( INHERITANCE_TYPE type,  FCO * ptr) 
{ 
	std::vector<FCO *>::iterator jt = 
		std::find( m_childList[type].begin(), m_childList[type].end(), ptr);
	
	// not inserting two times
	if (jt == m_childList[type].end())
		m_childList[type].push_back( ptr);
	else 
	{ }	// error already noticed by addParent
}


const std::vector<FCO *>&  FCO::getParents( INHERITANCE_TYPE type)
{
	return m_parentList[type];
}


const std::vector<FCO *>& FCO::getChildren( INHERITANCE_TYPE type)
{
	return m_childList[type];
}


bool FCO::hasParent( const FCO * par, INHERITANCE_TYPE type) const
{
	bool has = false;
	if ( type != REGULAR)
	{
		std::vector<FCO*>::const_iterator it = 
			std::find( m_parentList[REGULAR].begin(), m_parentList[REGULAR].end(), par);

		if ( it != m_parentList[REGULAR].end()) // found
			has = has || true;
	}
	if (has) return has;

	std::vector<FCO*>::const_iterator it = 
		std::find( m_parentList[type].begin(), m_parentList[type].end(), par);

	if ( it != m_parentList[type].end()) // found
		has = has || true;

	return has;
}


void FCO::setAncestors( INHERITANCE_TYPE type, const std::vector<FCO*> &anc_list)
{
	ASSERT( type != REGULAR);
	//global_vars.err << getName() << " . # of ancest: " << anc_list.size() << " with type: "<< type << "\n";

	m_ancestors[type].clear();
	m_ancestors[type].insert( m_ancestors[type].end(), anc_list.begin(), anc_list.end());
}


void FCO::setDescendants( INHERITANCE_TYPE type, const std::vector<FCO*> &desc_list)
{
	ASSERT( type != REGULAR);
	//global_vars.err << getName() << " . # of desc: " << desc_list.size() << " with type: "<< type << "\n";

	m_descendants[type].clear();
	m_descendants[type].insert( m_descendants[type].end(), desc_list.begin(), desc_list.end());
}


void FCO::getIntAncestors( std::vector<FCO*> & ancestors) const
{
	ancestors.insert( ancestors.end(), m_ancestors[INTERFACE].begin(), m_ancestors[INTERFACE].end());	
}


void FCO::getIntDescendants( std::vector<FCO*> & descendants) const
{
	descendants.insert( descendants.end(), m_descendants[INTERFACE].begin(), m_descendants[INTERFACE].end());	
}


void FCO::getImpAncestors( std::vector<FCO*> & ancestors) const
{
	ancestors.insert( ancestors.end(), m_ancestors[IMPLEMENTATION].begin(), m_ancestors[IMPLEMENTATION].end());	
}


void FCO::getImpDescendants( std::vector<FCO*> & descendants) const
{
	descendants.insert( descendants.end(), m_descendants[IMPLEMENTATION].begin(), m_descendants[IMPLEMENTATION].end());	
}


const FCO::AttributeRepPtrList& FCO::getInitialAttributeRepPtrList() const
{
	return m_initialAttributeList;
}


void FCO::addInitialAttribute( AttributeRep * attr)
{
	AttributeRepPtrList_ConstIterator it = 
		std::find( m_initialAttributeList.begin(), m_initialAttributeList.end(), attr);

	if ( it == m_initialAttributeList.end()) // not found so insert
		m_initialAttributeList.push_back( attr);
	else 
		global_vars.err << MSG_ERROR << attr->getPtr() << " attribute owned by " << m_ptr << " twice\n";
}


void FCO::addFinalAttribute( AttributeRep * attr)
{
	AttributeRepPtrList_ConstIterator it = 
		std::find( m_finalAttributeList.begin(), m_finalAttributeList.end(), attr);

	if ( it == m_finalAttributeList.end()) // not found so insert
		m_finalAttributeList.push_back( attr);
	/*else not an error because of multiple inheritance
		global_vars.err << attr->getName() << " attribute owned by " << getName() << " twice\n";*/
}


void FCO::addFinalAttributeList(const AttributeRepPtrList& t_list)
{
	AttributeRepPtrList_ConstIterator it_pos = t_list.begin();
	for( ; it_pos != t_list.end(); ++it_pos)
		addFinalAttribute( *it_pos);
}

bool FCO::findFinalAttributeBasedOnName( const std::string & name)
{
	AttributeRepPtrList_Iterator it;
	it = m_finalAttributeList.begin();
	while( it != m_finalAttributeList.end() && !((*it)->getName() == name /*&& (*it)->isViewable()*/))
		++it;
	return ( it != m_finalAttributeList.end()); // if found
}


// dumps out all owned (non-global) attributes
std::string FCO::dumpAttributes()
{
	std::string mmm = "";
	AttributeRepPtrList_Iterator it;
	
	AnyLexicographicSort lex;
	std::string last_name = "";
	std::sort( m_finalAttributeList.begin(), m_finalAttributeList.end(), lex );

	it = m_finalAttributeList.begin();
	for( ; it != m_finalAttributeList.end(); ++it)
		if ( !(*it)->isGlobal())
		{
			//if ( (*it)->isViewable())
			mmm += (*it)->doDumpAttr( getName());
			if ( last_name != "" && last_name == (*it)->getName())
				global_vars.err << MSG_ERROR << "Duplicate attribute name " << (*it)->getPtr() << " found for " << m_ptr << "\n";
			last_name = (*it)->getName();
		}

	return mmm;
}


// dumps out sorted attribute name list 
std::string FCO::dumpAttributeList( bool check_viewable /* = false */ )
{
	std::list<AttributeRep*> temp_list;
	std::list<AttributeRep*>::iterator t_it;
	std::string mmm = "";

	AttributeRepPtrList_Iterator it;
	
	it = m_finalAttributeList.begin();
	for( ; it != m_finalAttributeList.end(); ++it)
		if ( !check_viewable || (*it)->isViewable())
		{
			t_it = temp_list.begin();
			while( t_it != temp_list.end() && (*t_it)->lessThan(*it))
				++t_it;
			temp_list.insert( t_it, *it);
		}

	if ( !temp_list.empty())
	{
		mmm = " attributes = \"";
		for( t_it = temp_list.begin(); t_it != temp_list.end(); ++t_it)
		{
			if (t_it != temp_list.begin()) mmm += " ";
			mmm += (*t_it)->getName();
		}
		mmm += "\"";
	}
	return mmm;
}


std::string FCO::dumpIcon()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpIcon();
	}

	//if ( this->m_ptr)
	{
		std::string &icon = m_sAttrIcon;//m_ptr->getAttribute( Icon_str)->getStringValue();

		if( !icon.empty())
			mmm += indStr() + "<regnode name = \"icon\" value =\"" + icon + "\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpPortIcon()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpPortIcon();
	}

	//if ( this->m_ptr)
	{
		std::string &icon = m_sAttrPortIcon;//m_ptr->getAttribute( PortIcon_str)->getStringValue();

		if( !icon.empty())
			mmm += indStr() + "<regnode name = \"porticon\" value =\"" + icon + "\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpDecorator()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpDecorator();
	}

	//if ( this->m_ptr)
	{
		std::string &icon = m_sAttrDecorator;//m_ptr->getAttribute( Decorator_str)->getStringValue();

		if( !icon.empty())
			mmm += indStr() + "<regnode name = \"decorator\" value =\"" + icon + "\"></regnode>\n";
	}
	return mmm;

}


std::string FCO::dumpHotspotEnabled()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpHotspotEnabled();
	}

	//if ( this->m_ptr)
	{
		bool &icon = m_bAttrIsHotspotEnabled;//m_ptr->getAttribute( IsHotspotEnabled_str)->getBooleanValue();

		if( !icon)
			mmm += indStr() + "<regnode name = \"isHotspotEnabled\" value =\"false\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpTypeShown()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpTypeShown();
	}

	//if ( this->m_ptr)
	{
		bool &icon = m_bAttrIsTypeShown;//m_ptr->getAttribute( IsTypeShown_str)->getBooleanValue();

		if( icon)
			mmm += indStr() + "<regnode name = \"isTypeShown\" value =\"true\"></regnode>\n";
	}
	return mmm;
}

std::string FCO::dumpGeneralPref()
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpGeneralPref();
	}
	
	//if ( this->m_ptr)
	{
		std::string &prefs_1 = m_sAttrGenPref;//m_ptr->getAttribute( GeneralPreferences_str)->getStringValue();

		if (prefs_1.empty()) return mmm;

		bool berr = false;
		//CString prefs = prefs_1.c_str();
		std::string prefs = prefs_1;
		//CStringArray prefArr;
		std::vector< std::string > prefArr;
		//CTokenEx	 tok;
		Tokenizer tok;
		//tok.Split(prefs, _T("\n"), prefArr);
		tok.split( prefs, _T("\n"), prefArr);
		//for (int i = 0; i < prefArr.GetSize(); i++) {
		for (int i = 0; i < prefArr.size(); i++) {
			//CStringArray prefPair;
			std::vector< std::string > prefPair;
			//tok.Split(prefArr[i], _T("="), prefPair);
			tok.split( prefArr[i], _T("="), prefPair);
			// Compatibility with the older format
			//if (prefPair.GetSize() != 2) {
			if (prefPair.size() != 2) {
				//prefPair.RemoveAll();
				prefPair.clear();
				//tok.Split(prefArr[i], _T(","), prefPair);
				tok.split( prefArr[i], _T(","), prefPair);
				//if (prefPair.GetSize() == 2) {
				if (prefPair.size() == 2) {
					global_vars.err << MSG_WARNING << "Warning: Deprecated general preferences format for " << m_ptr << ".\n" << MSG_NORMAL << "Valid format:\n\t<prefname1> = <value1>\n\t<prefname2> = <value2>\n\t...\n";
				}
			}
			//if (prefPair.GetSize() == 2) {
			if (prefPair.size() == 2) {
				//prefPair[0].TrimLeft();
				tok.trimLeft( prefPair[0]);
				//prefPair[0].TrimRight();
				tok.trimRight( prefPair[0]);
				//prefPair[1].TrimLeft();
				tok.trimLeft( prefPair[1]);
				//prefPair[1].TrimRight();
				tok.trimRight( prefPair[1]);
				//mmm += indStr() + "<regnode name = \"" + (LPCTSTR)prefPair[0] + "\" value =\"" + (LPCTSTR)prefPair[1] + "\"></regnode>\n";
				if( prefPair[0].empty())
					global_vars.err << MSG_ERROR << "Empty General Preference token found at " << m_ptr << " with \"" << prefPair[1] << "\" as value.\n";
				else
					mmm += indStr() + "<regnode name = \"" + prefPair[0] + "\" value =\"" + prefPair[1] + "\"></regnode>\n";
			}
			else {
				berr = true;
				break;
			}
		}
		if(berr) {
			global_vars.err << MSG_ERROR << "Invalid general preferences specification for " << m_ptr << ".\n"
				<< MSG_NORMAL << "Valid format:\n\t<prefname1> = <value1>\n\t<prefname2> = <value2>\n\t...\n";
		}
	}
	return mmm;
}
 

std::string FCO::dumpNamePosition() const
{
	std::string mmm;
	//if ( this->m_ptr)
	{
		int name_pos = min(8,max(0,m_iAttrNamePosition));//m_ptr->getAttribute( NamePosition_str)->getIntegerValue();
		char p[2];
		sprintf(p, "%d", name_pos);
		mmm = std::string( p);
	}
	//else mmm = "NullPtrError";
	return indStr() + "<regnode name = \"namePosition\" value =\"" + mmm +"\">" + "</regnode>\n";
}


std::string FCO::dumpSubTypeIcon() const
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpSubTypeIcon();
	}

	//if ( this->m_ptr)
	{
		const std::string &icon = m_sAttrSubTypeIcon;//m_ptr->getAttribute( SubTypeIcon_str)->getStringValue();

		if( !icon.empty())
			mmm += indStr() + "<regnode name = \"subTypeIcon\" value =\"" + icon + "\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpInstanceIcon() const
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpInstanceIcon();
	}

	//if ( this->m_ptr)
	{
		const std::string &icon = m_sAttrInstanceIcon;//m_ptr->getAttribute( InstanceIcon_str)->getStringValue();

		if( !icon.empty())
			mmm += indStr() + "<regnode name = \"instanceIcon\" value =\"" + icon + "\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpNameWrap() const
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpNameWrap();
	}

	//if ( this->m_ptr)
	{
		const int &icon = m_iAttrNameWrapNum;//m_ptr->getAttribute( NameWrapNum_str)->getIntegerValue();
		char p[64];
		sprintf(p, "%d", icon);
		std::string icon_str( (const char *) p);// = m_ptr->getAttribute( NameWrapNum_str)->getStringValue();
		if( icon != 0)
			mmm += indStr() + "<regnode name = \"nameWrap\" value =\"" + icon_str + "\"></regnode>\n";
	}
	return mmm;
}


std::string FCO::dumpNameEnabled() const
{
	std::string mmm;
	std::vector<FCO*> ancestors;
	getImpAncestors( ancestors);
	std::vector<FCO*>::iterator it = ancestors.begin();
	for( ; it != ancestors.end(); ++it)
	{
		mmm += (*it)->dumpNameEnabled();
	}

	//if ( this->m_ptr)
	{
		const bool &icon = m_bAttrIsNameEnabled;//m_ptr->getAttribute( IsNameEnabled_str)->getBooleanValue();

		if( !icon)
			mmm += indStr() + "<regnode name = \"isNameEnabled\" value =\"false\"></regnode>\n";
	}
	return mmm;
}

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

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

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

	/*virtual*/ std::string doDump() { return ""; }
	inline Any::KIND_TYPE getMyKind() const { return Any::FCO_REP; }

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"
#include "AspectRep.h"

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*/ std::string doDump();

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

	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 as well
	std::vector<const ModelRep *> getModelRefVector() const;

	bool checkNotEmpty() const;

	// aspect related
	int howManyAspectsAmongModelRefs() const;
	std::vector<AspectRep *> getAspectsIntersection() const;
	AspectRep * getFirstAspectFromIntersection() const;

protected:
	// 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)
	// this reference may look like all of m_allReferees 
	// i.e. ( ref1 -> ref2 -> model) ref1 looks like model
	// plays role at connection dump
	// it should be named m_transitiveReferences
	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 "logger.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;

SetRep::SetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
	: FCO( ptr, resp_ptr)
{ 
	m_memberList.clear();
	m_memberMap.clear();
}


SetRep::~SetRep()
{ 
	m_memberList.clear();
	m_memberMap.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 << MSG_ERROR << "Set member " << member->getPtr() << " is twice in set " << m_ptr << "\n";
} 


// adds new role to the potential lists of set elements in model!!!
void SetRep::addSetMemberRole( const ModelRep * model, const RoleRep& role)
{ 
	PointerItemSeries & series = m_memberMap[model];
	PointerItem item = role.getSmartRoleName();
	
	PointerItemSeries_Iterator it = std::find( series.begin(), series.end() ,item);

	//global_vars.err << "Role \"" << role.getSmartRoleName() << "\" in set \"" << getName() << ":" << model->getName() <<"\"\n";
	if ( it == series.end() ) // not found
		series.push_back( item);
	else 
		{ /*global_vars.err << "Notice: found duplicate role \"" << role.getSmartRoleName() << "\" in set \"" << getName() << ":" << model->getName() << "\"\n";*/ }
}


// adds new roles to the potential lists of set elements in model!!!
void SetRep::addSetMemberRole( const ModelRep * model, const RoleRep::RoleRepSeries & role_series)
{ 
	RoleRep::RoleRepSeries_ConstIterator role_it = role_series.begin();
	for( ; role_it != role_series.end(); ++role_it)
		addSetMemberRole( model, *role_it);
}


//
// SetRep::createElements
//
// expands the set and connection targets with roleNames like below as (elementNames)
//
// i.e.:      S
//          / | \
//        /   |   \
//      /    < >    \
//    M1-r1---A---r2-M2
//    M1-R1--/ \--R2-M2
//
// in this case S has at first A as a member, but after the completion of this task
// S will have elements like r1, R1 (in M1), r2, R2 ( in M2)
void SetRep::inherit()
{
	std::vector<FCO*> set_descendants;
	this->getImpDescendants( set_descendants);
	set_descendants.push_back( this);
	//global_vars.err << "Inheriting from set: "<< getName() << "\n";

	// this set is contained by the following models
	ModelRepPtrList models = this->modelsIAmPartOfFinal();
	ModelRepPtrList_Iterator mod_it = models.begin();
	// for all models that contain this set
	for( ; mod_it != models.end(); ++mod_it )
	{
		ModelRep* mod_ptr = *mod_it; 
		// we don't have to care with the impl inh between models since all model related
		// inheritances are taken into account
		//global_vars.err << "In model " << mod_ptr->getName() << "\n";

		// for all members of the set
		SetMemberList_ConstIterator member_it = m_memberList.begin();
		for( ; member_it != m_memberList.end(); ++member_it)
		{
			FCO * member_ptr = *member_it;
			std::vector<FCO*> children;
		
			//global_vars.err << "For all desc's of " << member_ptr->getName() << "\n";

			member_ptr->getIntDescendants( children);
			children.push_back( member_ptr);

			// for all int desc of current set member
			std::vector<FCO*>::reverse_iterator child_it = children.rbegin();
			for( ; child_it != children.rend(); ++child_it)
			{
				FCO * child_member_ptr = * child_it;
				if ( !child_member_ptr->isAbstract())
				{
					RoleRep::RoleRepSeries series;
					bool has_some = mod_ptr->getFinalRoles( child_member_ptr, series);

					if ( has_some && !series.empty())
					{
						std::vector<FCO*>::reverse_iterator sets_iterator = set_descendants.rbegin();
						for( ; sets_iterator != set_descendants.rend(); ++sets_iterator )
						{
							if ( (*sets_iterator)->getMyKind() != Any::SET) 
								global_vars.err << MSG_ERROR << "Non-set descendant: " << (*sets_iterator)->getPtr() <<" of set: " << m_ptr <<"\n";
							else
							{
								SetRep* one_set = dynamic_cast<SetRep *>(*sets_iterator);
								std::string set_nm = one_set->getName();
								// add the roles to the member list of the set ( in that model) 
								one_set->addSetMemberRole( mod_ptr, series);
							}
						}
					}
				}
			}
		}
	}
}


std::string SetRep::doDump()
{
	std::string m_ref = askMetaRef();

	std::string mmm = indStr() + "<set name = \"" + getName()  + "\" metaref = \"" + m_ref + "\"";

	mmm += dumpAttributeList();

	mmm +=" >\n";
	++ind;
	mmm += dumpDispName();
	++ind;
	mmm += dumpNamePosition();
	mmm += dumpGeneralPref();

	mmm += dumpIcon();
	mmm += dumpPortIcon();
	mmm += dumpDecorator();
	mmm += dumpHotspotEnabled();
	mmm += dumpTypeShown();
	mmm += dumpSubTypeIcon();
	mmm += dumpInstanceIcon();
	mmm += dumpNameWrap();
	mmm += dumpNameEnabled();

	--ind;
	mmm += dumpConstraints();
	mmm += dumpAttributes();
	mmm += indStr() + "<pointerspec name = \"set\">\n";
	++ind;
	
	
	PointerItemSeries dumper_list;
	
	ModelRepPtrList models = this->modelsIAmPartOfFinal();
	ModelRepPtrList_ConstIterator mod_it = models.begin();

	// for all models that contain this set
	for( ; mod_it != models.end(); ++mod_it )
	{
		ModelRep * mod_ptr = *mod_it;

		// for all members in this model
		PointerItemSeries_Iterator part_it = m_memberMap[ mod_ptr].begin();
		for( ; part_it != m_memberMap[ mod_ptr].end(); ++part_it)
		{
			// insert into dumper_list if not present already
			if ( std::find( dumper_list.begin(), dumper_list.end(), *part_it) ==
				dumper_list.end()) // not found
				dumper_list.push_back( *part_it);
			else
			{	/*global_vars.err << "Warning: set element \"" << part_it->name() << "\" present twice in set \"" << getName() << "\"\n";*/ }
		}
	}	// end for

	PointerItemLex lex;
	std::sort( dumper_list.begin(), dumper_list.end(), lex);
	PointerItemSeries_Iterator dump_it = dumper_list.begin();
	for( ; dump_it != dumper_list.end(); ++dump_it)
		mmm += indStr() + "<pointeritem desc = \"" + dump_it->name() + "\"></pointeritem>\n";

	--ind;
	mmm += indStr() + "</pointerspec>\n";
	--ind;
	mmm += indStr() + "</set>\n";
	
	return mmm;
}


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 << MSG_ERROR << "CHECK: set member " << member_ptr->getPtr() << " in set \"" << m_ptr << "\" is not contained by any model.\n";
				res = false;
			}
		}
	}
	return res;
}


--- NEW FILE: AttributeRep.h ---
#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H

#include "Any.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 getName() const;
	/*virtual*/ std::string doDump() { return ""; }

	virtual std::string doDumpAttr(const std::string& mm = "") = 0;
	virtual ATTR_TYPE getType() = 0;

	bool isGlobal();
	bool isViewable();
	std::string getPrompt();
	std::string getMetaRef(const std::string & owner);
	std::string dumpHelp();
	void getXY( unsigned int * x, unsigned int *y) const;
	bool lessThan( const AttributeRep * rep) const;

	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 doDumpAttr(const std::string& mm = "");

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 doDumpAttr(const std::string& mm = "");
};

class FieldAttributeRep : public AttributeRep
{
public:
	FieldAttributeRep( IMgaFCO* ptr): AttributeRep( ptr) { }
	virtual ~FieldAttributeRep() { }
	ATTR_TYPE getType() { return FIELD; }
	/*virtual*/ std::string doDumpAttr(const std::string& mm = "");
};

#endif // ATTRIBUTE_H


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

#include "string"
class PointerItem;

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


class PointerItem
{
private:
	std::string m_name;
public:
	PointerItem( std::string name);
	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;
};

#endif //POINTERITEM_H

--- 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 "Broker.h"
#include "ConstraintRep.h"
#include "Dumper.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;


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)
{
}


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)
{ 
}


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;

	return *this;
}


ConnJoint::~ConnJoint() 
{
	m_connPtr = 0;
	
	m_oper1.clear();
	m_oper2.clear();

	m_oper1TargetMap.clear();
	m_oper2TargetMap.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();
	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);
}


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;
	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(); //if you allow conns for transitive references //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);
											}
											/*PointerItem item = (*ref_it)->getName() + " " + sub_role.getSmartRoleName();
											this->addTargetItem( i, mod_ptr, item);*/
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}


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 << MSG_WARNING << "CHECK: \"" << member_ptr->getName() << "\" fco in connection \"" << connection_name << "\" is not contained by any model.\n";
				res = false;
			}
		}
	}
	return res;
}


std::string ConnJoint::dumpElements( FCO::ModelRepPtrList & model_list)
{
	std::string mmm;
	std::string mmm_src = "";
	std::string mmm_dst = "";

	PointerItemSeries src_dumper_list, dst_dumper_list;

	FCO::ModelRepPtrList_ConstIterator mod_it = model_list.begin();
	// for all models i am part of
	for( ; mod_it != model_list.end(); ++mod_it )
	{
		ModelRep * mod_ptr = *mod_it;
		PointerItemSeries_Iterator item_it = m_oper1TargetMap[ mod_ptr].begin();
		for( ; item_it != m_oper1TargetMap[ mod_ptr].end(); ++item_it)
		{
			if ( std::find( src_dumper_list.begin(), src_dumper_list.end(), *item_it) == 
				src_dumper_list.end()) // not found
				src_dumper_list.push_back( *item_it);
			else 
			{ /* <!> too many warnings global_vars.err << "Warning: \"" << item_it->name() << "\" present twice in connnection \"" << m_connPtr->getName() << "\" as src.\n";*/ }
		}
		
		item_it = m_oper2TargetMap[ mod_ptr].begin();
		for( ; item_it != m_oper2TargetMap[ mod_ptr].end(); ++item_it)
		{
			if ( std::find( dst_dumper_list.begin(), dst_dumper_list.end(), *item_it) ==
				dst_dumper_list.end()) // not found
				dst_dumper_list.push_back( *item_it);
			else 
			{ /* <!> too many warnings global_vars.err << "Warning: \"" << item_it->name() << "\" present twice in connnection \"" << m_connPtr->getName() << "\" as dst.\n";*/ }
		}
	}

	mmm += indStr() + "<connjoint>\n";
	++ind;

	mmm += indStr() + "<pointerspec name = \"src\">\n";
	++ind;

	PointerItemLex lex;
	std::sort( src_dumper_list.begin(), src_dumper_list.end(), lex);
	std::sort( dst_dumper_list.begin(), dst_dumper_list.end(), lex);

	PointerItemSeries_Iterator item_it = src_dumper_list.begin();
	for( ; item_it != src_dumper_list.end(); ++item_it)
		mmm_src += indStr() + "<pointeritem desc = \"" + item_it->name() + "\"></pointeritem>\n";

	--ind;
	mmm += mmm_src + indStr() + "</pointerspec>\n";
	mmm += indStr() + "<pointerspec name = \"dst\">\n";
	++ind;

	item_it = dst_dumper_list.begin();
	for( ; item_it != dst_dumper_list.end(); ++item_it)
		mmm_dst += indStr() + "<pointeritem desc = \"" + item_it->name() + "\"></pointeritem>\n";

	--ind;
	mmm += mmm_dst + indStr() + "</pointerspec>\n";

	--ind;
	mmm += indStr() + "</connjoint>\n";
	
	// if bidirect dump the other direction also
	if (m_bidirect) 
	{
		mmm += indStr() + "<connjoint>\n";
		++ind;

		mmm += indStr() + "<pointerspec name = \"src\">\n";

		mmm += mmm_dst + indStr() + "</pointerspec>\n";

		mmm += indStr() + "<pointerspec name = \"dst\">\n";

		mmm += mmm_src + indStr() + "</pointerspec>\n";

		--ind;
		mmm += indStr() + "</connjoint>\n";
	}
	return mmm;
}


void ConnJoint::createConstraints( Sheet* s, const std::string& conn_name)
{
	int cons_id1 = Broker::getNextConstraintId();
	int cons_id2 = Broker::getNextConstraintId();

	char cons_id1_str[64], cons_id2_str[64];

	sprintf( cons_id1_str, "%d", cons_id1);
	sprintf( cons_id2_str, "%d", cons_id2);

	std::string src_cons_name, dst_cons_name;
	src_cons_name = "Valid" + conn_name + m_srcLabel + "Cardinality" + cons_id1_str;
	dst_cons_name = "Valid" + conn_name + m_dstLabel + "Cardinality" + cons_id2_str;
	int pos = 0;
	pos = src_cons_name.find( "::");
	if( pos != std::string::npos) 
		src_cons_name.replace( pos, 2, 2, '_');
	pos = dst_cons_name.find( "::");
	if( pos != std::string::npos)
		dst_cons_name.replace( pos, 2, 2, '_');

	int iEventMask = 0;
	char chMask[64];
	sprintf( chMask, "%x", iEventMask );
	std::string mask = chMask;

	// Parse Cardinality, build Expression

	std::string src_expr_begin, dst_expr_begin;
	src_expr_begin = "let srcCount = self.attachingConnections( \"" + m_dstLabel + "\", meta::" + conn_name + " ) -> size in\n                     ";
	dst_expr_begin = "let dstCount = self.attachingConnections( \"" + m_srcLabel + "\", meta::" + conn_name + " ) -> size in\n                     "; 
	
	std::string src_expr_end, dst_expr_end;
	std::string src_card_context, dst_card_context;

	src_card_context = "[connection] Connection: " + conn_name + ", Conn.Role: " + m_srcLabel;
	dst_card_context = "[connection] Connection: " + conn_name + ", Conn.Role: " + m_dstLabel;
	
	if ( Dumper::doParseCardinality( this->m_oper1Card, "srcCount", src_card_context, src_expr_end))
	{
		global_vars.err << MSG_WARNING << "Ignoring invalid cardinality string in connection: " << m_connPtr->getPtr() << ". String: " << this->m_oper1Card << "\n";
	}
	if ( ! src_expr_end.empty() ) 
	{
		// assign the source cardinality constraints to DST-s
		SDList_Iterator it = m_oper2.begin();
		while ( it != m_oper2.end())
		{
			std::string src_desc;
			src_desc = "Multiplicity of objects, which are associated to " + (*it)->getName() + 
			" as \"" + m_srcLabel + "\" over " + conn_name + ", has to match " + m_oper1Card + ".";

			ConstraintRep * cr = s->createConstraintRep( 0);
			std::string s_b = src_expr_begin + src_expr_end;
			cr->init( src_cons_name, /*mask:*/ global_vars.genConstr.connect_mask, "1", global_vars.genConstr.priority, s_b, src_desc);

			(*it)->addInitialConstraintRep( cr);
			cr->attachedTo();
			++it;
		}
	}
	if ( Dumper::doParseCardinality( this->m_oper2Card, "dstCount", dst_card_context, dst_expr_end))
	{
		global_vars.err << MSG_WARNING << "Ignoring invalid cardinality string in connection: " << m_connPtr->getPtr() << ". String: " << this->m_oper2Card << "\n";
	}
	if ( ! dst_expr_end.empty() ) 
	{
		// assign the dst cardinality constraints to SRC-s
		SDList_Iterator it = m_oper1.begin();
		while ( it != m_oper1.end())
		{
			std::string dst_desc;
			dst_desc = "Multiplicity of objects, which are associated to " + (*it)->getName() + 
			" as \"" + m_dstLabel + "\" over " + conn_name + ", has to match " + m_oper2Card + ".";

			ConstraintRep * cr = s->createConstraintRep( 0);
			std::string d_b = dst_expr_begin + dst_expr_end;
			cr->init( dst_cons_name, /*mask:*/ global_vars.genConstr.connect_mask, "1", global_vars.genConstr.priority, d_b, dst_desc);

			(*it)->addInitialConstraintRep( cr);
			cr->attachedTo();
			++it;
		}
		//mm.push_back(cr);
	}
}


/*
the added connjoint (since it comes from above) is supposed to have an m_oper1 and m_oper2 
values that are ancestors of the m_oper1 and m_oper2 lists of *this 
*/
bool ConnJoint::descendantsOf( const ConnJoint& peer) const
{
	bool res = true;
	
	const SDList* mylists[] = { &m_oper1, &m_oper2 };
	const SDList* peerlists[] = { &peer.m_oper1, &peer.m_oper2 };

	for( int i = 0; res && i < 2; ++i)
	{
		SDList_ConstIterator it = mylists[i]->begin();
		for( ; res && it != mylists[i]->end(); ++it)
		{
			bool current_found = false;
			
			SDList_ConstIterator itp = peerlists[i]->begin();
			for( ; !current_found && itp != peerlists[i]->end(); ++itp)
			{
				std::vector<FCO*> descs;
				(*itp)->getIntDescendants( descs);

				if ( std::find( descs.begin(), descs.end(), *it) != descs.end()) // found
					current_found = true;
			}
			res = res && current_found;
		}
	}
	return res;
}


/*    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
*/



--- NEW FILE: PartRep.h ---
#ifndef PARTREP_H
#define PARTREP_H

#include "string"

#include "AspectRep.h"
#include "RoleRep.h"
class ModelRep;
class AspectRep;
class RoleRep;
class FCO;

/** The element which represent an aspect member. */
class PartRep 
{
public:
	PartRep( const RoleRep & role, 
		AspectRep * aspect_ptr)
		//AspectRep * kind_aspect_ptr = 0,
		//bool primary = true)
	:	m_rolePtr( &role),
		m_containerAspect( aspect_ptr),
		m_kindAspectPtr( 0), //m_kindAspectPtr( kind_aspect_ptr),
		m_primary( true) //m_primary( primary)
	{	}

	PartRep( const PartRep& peer): 
		m_rolePtr( peer.m_rolePtr), 
		m_containerAspect( peer.m_containerAspect),
		m_kindAspectPtr( peer.m_kindAspectPtr),
		m_primary( peer.m_primary)
	{ }

	const PartRep& operator=( const PartRep& peer)
	{
		if ( this == &peer) return *this;
		m_rolePtr = peer.m_rolePtr;
		m_containerAspect = peer.m_containerAspect;
		m_kindAspectPtr = peer.m_kindAspectPtr;
		m_primary = peer.m_primary;
		return *this;
	}

	bool operator!=( const PartRep& peer) const
	{
		return 
		( m_rolePtr != peer.m_rolePtr ||
		m_containerAspect != peer.m_containerAspect ||
		m_kindAspectPtr != peer.m_kindAspectPtr ||
		m_primary != peer.m_primary );
	}

	bool operator==( const PartRep& peer) const
	{ 
		return !this->operator!=(peer);
	}

public:
	inline const ModelRep* getParentPtr() const { return m_rolePtr->getModelRepPtr(); }
	inline const FCO* getFCOPtr() const { return m_rolePtr->getFCOPtr(); }

	inline const RoleRep* getRoleRepPtr() const { return m_rolePtr; }
	inline const AspectRep* getContainerAspectPtr() const { return m_containerAspect; }

	inline void setKindAspectPtr( const AspectRep* a_rep) { m_kindAspectPtr = a_rep; }
	inline const AspectRep* getKindAspectPtr() const { return m_kindAspectPtr; }

	inline void setPrimary( bool is_primary) { m_primary = is_primary; }
	inline bool isPrimary() const { return m_primary; }

protected:
	const RoleRep	* m_rolePtr;			// role the part belongs to
  const AspectRep * m_containerAspect;	// aspect the part belongs to
	const AspectRep * m_kindAspectPtr; // the selected aspect in case of mOdel part
  bool m_primary;
};
#endif //PARTREP_H
--- NEW FILE: AtomRep.cpp ---
#include "stdafx.h"

#include "MyUtil.h"
#include "AtomRep.h"
#include "logger.h"
#include "ConstraintRep.h"
#include "ConstraintFuncRep.h"

extern int ind;

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


std::string AtomRep::doDump()
{
	std::string m_ref = askMetaRef();

	std::string mmm = indStr() + "<atom name = \"" + getName() + "\" metaref = \"" + m_ref + "\" ";

	mmm += dumpAttributeList();
	mmm += ">\n";
	++ind;
	mmm += dumpDispName();
	++ind;
	mmm += dumpNamePosition();
	mmm += dumpGeneralPref();
	--ind;
	mmm += dumpConstraints();
	mmm += dumpAttributes();
	++ind;
	mmm += dumpIcon();
	mmm += dumpPortIcon();
	mmm += dumpDecorator();
	mmm += dumpHotspotEnabled();
	mmm += dumpTypeShown();
	mmm += dumpSubTypeIcon();
	mmm += dumpInstanceIcon();
	mmm += dumpNameWrap();
	mmm += dumpNameEnabled();

	--ind;
	--ind;
	mmm += indStr() + "</atom>\n";
	return mmm;
}

--- 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:
	SetRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	~SetRep();

	/*virtual*/ std::string doDump();

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

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

	// adds new elements to the m_extMemberList vector
	void inherit();

	void addSetMemberRole( const ModelRep * model, const RoleRep& member);
	
	void addSetMemberRole( const ModelRep * model, const RoleRep::RoleRepSeries & role_series);


	bool checkSetElements();

protected:
	// stores those FCO-s which are in SET_MEMBER relationship with (*this)
	// coresponds to "initial"
	SetMemberList m_memberList;

	// stores all rolenames for the members above and their intInherited desc's
	// coresponds to "final"
	SetMembersMap m_memberMap;

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 "AspectRep.h"
#include "RoleRep.h"
#include "FCO.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;
	// aspects
	typedef std::vector<AspectRep*> AspectRepPtrList;

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

	/*virtual*/ std::string doDump();

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

	// 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;

	// aspects
	void addAspect( AspectRep * asp);
	const AspectRepPtrList& getAspectRepPtrList() const;
	// final
	const AspectRepPtrList& getFinalAspectRepPtrList() const;
	void addFinalAspect( AspectRep *);
	void addFinalAspectList(const AspectRepPtrList& l);

	void getAspectNames( CStringList &list) const;

	AspectRep * getFirstAspect() const;
	AspectRep * getMyFirstAspectFromSet( const std::vector<AspectRep *> & aspect_set) const;
	bool findAspect( const AspectRep * one_asp) const;

	// search
public:
	int searchMyAspectsForPart( PartRep& part) const; // how many of my aspects contain part as an aspect member
	int howManyAspects() const; // how many aspects has this model
	
	void createConstraints( Sheet *);
	bool checkMyAspects( Sheet *);
	void inherit();
	
	void sortMyAspects();
	void createPartsInModelAspects();

protected:
	RoleMap m_initialRoleMap;
	RoleMap m_finalRoleMap;

	AspectRepPtrList m_initialAspectList;
	AspectRepPtrList m_finalAspectList;

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: // constant strings
	static const std::string Color_str;//"IsAbstract"
	static const std::string ConnLineEnd_str;//"Icon"
	static const std::string ConnLineStart_str;//"PortIcon"
	static const std::string ConnLineType_str;//"Decorator"
	static const std::string SrcAttrLabel1_str;//"SrcAttrLabel1"
	static const std::string SrcAttrLabel2_str;//"SrcAttrLabel2"
	static const std::string DstAttrLabel1_str;//"DstAttrLabel1"
	static const std::string DstAttrLabel2_str;//"DstAttrLabel2"

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

	/*virtual*/ std::string doDump();

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

public:
	/*virtual*/ void initAttributes();
	void addJoint( ConnJoint & joint);
	void appendJointElements( const ConnJoint & joint);
	void inherit();
	bool checkConnectionTargets();
	void createConstraints( Sheet*);

	std::string dumpConnDetails();

protected:
	std::list<ConnJoint> m_jointList;

	std::string m_sAttrColor;
	std::string m_sAttrConnLineEnd;
	std::string m_sAttrConnLineStart;
	std::string m_sAttrConnLineType;
	std::string m_sAttrSrcAttrLabel1;
	std::string m_sAttrSrcAttrLabel2;
	std::string m_sAttrDstAttrLabel1;
	std::string m_sAttrDstAttrLabel2;

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"

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

class FCO : public Any
{
public: // constant strings
	static const std::string IsAbstract_str;//"IsAbstract"
	static const std::string Icon_str;//"Icon"
	static const std::string PortIcon_str;//"PortIcon"
	static const std::string Decorator_str;//"Decorator"
	static const std::string IsHotspotEnabled_str;//"IsHotspotEnabled"
	static const std::string IsTypeShown_str;//"IsTypeShown"
	static const std::string GeneralPreferences_str;//"GeneralPreferences"
	static const std::string NamePosition_str;//"NamePosition"
	static const std::string SubTypeIcon_str;//"SubTypeIcon"
	static const std::string InstanceIcon_str;//"InstanceIcon"
	static const std::string NameWrapNum_str;//"NameWrapNum"
	static const std::string IsNameEnabled_str;//"IsNameEnabled"

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 InhType
	{
		REGULAR = 0,
		INTERFACE = 1,
		IMPLEMENTATION = 2,
		NUMBER_OF_INHERITANCES // = 3
	} INHERITANCE_TYPE;

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

	//static IMgaAttribute* getAttrib( IMgaFCO* p_fco, const std::string& p_attrName);
	//static std::string getSAttrVal( IMgaFCO* p_fco, const std::string& p_attrName);
	//static bool        getBAttrVal( IMgaFCO* p_fco, const std::string& p_attrName);
	//static long        getLAttrVal( IMgaFCO* p_fco, const std::string& p_attrName);
	//static double      getFAttrVal( IMgaFCO* p_fco, const std::string& p_attrName);
	//static bool        isAttrStatHere( IMgaFCO* p_fco, const std::string& p_attrName);

	/*virtual*/ void initAttributes();
	/*virtual*/ std::string getName() const;
	/*virtual*/ std::string getDispName() const;

	// 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);
	// get all children
	const std::vector<FCO *>& getChildren( INHERITANCE_TYPE type);

	// 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;

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

	void addFinalAttribute( AttributeRep * attr);
	void addFinalAttributeList(const AttributeRepPtrList& t_list);
	bool findFinalAttributeBasedOnName( const std::string & name);

	std::string dumpAttributes();
	std::string dumpAttributeList( bool check_viewable = false);
	std::string dumpIcon();
	std::string dumpPortIcon();
	std::string dumpDecorator();
	std::string dumpHotspotEnabled();
	std::string dumpTypeShown();
	std::string dumpGeneralPref();
	std::string dumpNamePosition() const;
	std::string dumpSubTypeIcon() const;
	std::string dumpInstanceIcon() const;
	std::string dumpNameWrap() const;
	std::string dumpNameEnabled() const;


protected:
	/**
	 * This pointer is in charge of the name, 
	 * may point to an FCO or an Equivalence operator
	 */
	CComPtr<IMgaFCO> m_respPointer;
	
	// the IsAbstract attribute value
	bool m_isAbstract;

	bool m_bAttrIsHotspotEnabled;
	bool m_bAttrIsTypeShown;
	bool m_bAttrIsNameEnabled;

	int m_iAttrNamePosition;
	int m_iAttrNameWrapNum;

	std::string m_sAttrDispName;
	std::string m_sAttrGenPref;
	std::string m_sAttrIcon;
	std::string m_sAttrPortIcon;
	std::string m_sAttrSubTypeIcon;
	std::string m_sAttrInstanceIcon;
	std::string m_sAttrDecorator;

	// 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;
	AttributeRepPtrList m_finalAttributeList;

	// 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 ];

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 "AspectSpecDlg.h"
#include "GlobalAspOrder.h"
#include "Options.h"
#include "Broker.h"
#include "Token.h"
#include "algorithm"
#include <afxdlgs.h>

#include "globals.h"
extern Globals global_vars;

int ind = 0;
CAspectSpecDlg *theAspectDlg = 0;

// keep in sync with AspectSpecDlg.cpp's DUMPER_NOT_SPECIFIED_STR
#define DUMPER_NOT_SPECIFIED_STR      "Not specified"
[...1763 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: RoleRep.cpp ---
#include "stdafx.h"

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

#include <fstream>




// finds and returns the value after the "token" token
std::string get_name( const std::string& line, const std::string & token = "name")
{
	int start_of_token = line.find(token);
	if (start_of_token == std::string::npos) return "";
	
	int first_quote = line.substr( start_of_token).find( "\"");
	if (first_quote == std::string::npos) return "";
	// find the second '"'
	int len_of_name = line.substr(start_of_token + first_quote + 1).find("\"");
	if ( len_of_name == std::string::npos) return "";

	std::string pp = line.substr( start_of_token + first_quote + 1, len_of_name);
	return line.substr( start_of_token + first_quote + 1, len_of_name);
}


bool PartStringLex::operator()( const std::string& peer1, const std::string& peer2) const
{ 
	std::string part1_name = ::get_name( peer1, "role");
	std::string part2_name = ::get_name( peer2, "role");
	int k = part1_name.compare( part2_name);

	return (k < 0);
}


bool StringLex::operator()( const std::string& peer1, const std::string& peer2) const
{ 
	int k = peer1.compare(peer2);

	return (k < 0);
}


bool RoleStringLex::operator()( const RoleRep& peer1, const RoleRep& peer2) const
{
	std::string n1 = peer1.getSmartRoleName();
	std::string n2 = peer2.getSmartRoleName();
	int k = n1.compare( n2);

	return ( k < 0);
}


RoleRep::RoleRep( 
	const std::string &role_name,
	FCO* ptr, 
	ModelRep * 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_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_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_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_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_ptr->getNamespace().empty() ? "" : ( m_ptr->getNamespace() + Any::NamespaceDelimiter_str)) + m_roleName;
	else return m_ptr->getName();
}


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


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


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 "PartRep.h"
#include "FCO.h"
#include "ConstraintFuncRep.h"
#include "ConstraintRep.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( IMgaProject* project );

	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);

	AspectRep* createAspectRep( IMgaFCO* ptr, IMgaFCO* resp_ptr);
	ConstraintRep* createConstraintRep( IMgaFCO* ptr);
	ConstraintFuncRep* createConstraintFuncRep( IMgaFCO* 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; }

	static CComPtr<IMgaFolder> m_BON_Project_Root_Folder;
	static bool makeValidParadigmName( const std::string& pInName, std::string& result);
	static bool makeValidNamespace( const std::string& pInName, std::string& result);

protected:
	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<AspectRep*>::iterator AspectRep_Iterator;
	typedef std::vector<ConstraintRep*>::iterator ConstraintRep_Iterator;
	typedef std::vector<ConstraintFuncRep*>::iterator ConstraintFuncRep_Iterator;
	typedef std::vector<AttributeRep*>::iterator AttributeRep_Iterator;

	typedef std::vector<FCO*>::const_iterator FCO_ConstIterator;
	typedef std::vector<FolderRep*>::const_iterator FolderRep_ConstIterator;

	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 addAspectRep( AspectRep * ptr);
	void addConstraintFuncRep( ConstraintFuncRep *ptr);
	void addConstraintRep( ConstraintRep *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<AspectRep*> m_aspectList;
	std::vector<ConstraintRep*> m_constraintList;
	std::vector<ConstraintFuncRep*> m_constraintFuncList;
	std::vector<AttributeRep*> m_attributeList;

	std::string m_projName;
	std::string m_projVersion;
	std::string m_projGUID;
	std::string m_projCreated;
	std::string m_projModified;
	std::string m_projAuthor;
	std::string m_projComment;
	std::string m_projNamespace;

	RootFolder m_rootFolder;

private:
	void init();
	bool isInRootFolder( Any * elem);
	void initRoleNames();
	bool doInheritance( FCO::INHERITANCE_TYPE inh_type);

	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 <algorithm>

#include "globals.h"
extern Globals global_vars;


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 << MSG_WARNING << "Warning: Reference \"" << m_ptr << "\" referring twice to fco: \"" << refd->getPtr() << "\". 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;
}

/**
 * Returns true if the reference refers to a Model (a non abstract model) beside all other kinds like Atom, FCO, Reference, Set
 * The permissive version
 */
bool ReferenceRep::pointsToModels() const
{
	bool to_models = false;

	for( unsigned int i = 0; !to_models && i < m_allReferees.size(); ++i)
	{
		// consider the non-abstracts models only (if a reference points to an abstract model, that doesn't mean too much)
		if ( !m_allReferees[i]->isAbstract())
		{
			to_models = to_models || (m_allReferees[i]->getMyKind() == Any::MODEL);
		}
	}

	return to_models;
}

/*****    deprecated version, see Emre's bug, non-homogeneous references  ************
// The strict version
//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;//t
	std::string which_models;//t
	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)//t
				{
					how_many_models += 1;
					which_models += m_allReferees[i]->getName() + " ";
				}
			}
		}
	}

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



/*
Should return vector<ModelRep *> if pointsToModels is true
Returns non abstract models only !!! (see ESML paradigm)
*/
std::vector<const ModelRep *> ReferenceRep::getModelRefVector() const
{
	std::vector<const ModelRep *> models;
	
	for( unsigned int i = 0; i < m_allReferees.size(); ++i) 
	{
		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);
		}
	}

	return models;
}


/* -- obsolete
Should return a ModelRep * if pointsToModels is true
Returns non abstract models only !!! (see ESML paradigm)
*/
// see getModelRefVector() too
/*const ModelRep * ReferenceRep::getModelRef() const
{
	unsigned int i = 0;
	bool conti = true;
	while( i < m_allReferees.size() && conti) 
	{
		if ( m_allReferees[i]->getMyKind() == Any::MODEL && !m_allReferees[i]->isAbstract())
			conti = false;
		else
			++i;
	}

	if ( i == m_allReferees.size()) // not found any model, how come?
		return 0;
	else 
	{
		unsigned int j = i+1; // look for other models 
		while( j < m_allReferees.size() && m_allReferees[j]->getMyKind() != Any::MODEL)
			++j;
		if ( j != m_allReferees.size()) // found another one
		{
			//global_vars.err << "Notice: reference \"" << getName() << "\" referring to many models. Considering only the first: " << m_allReferees[i]->getName() << "\n";
			//<!> this would have strange effects in case of aspect mapping -> gathered all
			// aspects of the different models ...
		}

		return dynamic_cast<const ModelRep*>( m_allReferees[i]);
	}
}*/


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);
	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)->getPtr() <<" of reference: " << m_ptr <<"\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;
}


std::string ReferenceRep::doDump() 
{ 
	std::string m_ref = askMetaRef();	

	std::string mmm = indStr() + "<reference name = \"" + getName()  + "\" metaref = \"" + m_ref + "\"";

	mmm += dumpAttributeList();
	mmm +=">\n";
	++ind;
	mmm += dumpDispName();
	++ind;
	mmm += dumpNamePosition();
	mmm += dumpGeneralPref();
	--ind;
	mmm += dumpConstraints();
	mmm += dumpAttributes();


	mmm += dumpIcon();
	mmm += dumpPortIcon();
	mmm += dumpDecorator();
	mmm += dumpHotspotEnabled();
	mmm += dumpTypeShown(); // previously didn't needed, but let's try <!>
	mmm += dumpSubTypeIcon();
	mmm += dumpInstanceIcon();
	mmm += dumpNameWrap();
	mmm += dumpNameEnabled();
	// 	mmm += dumpTypeDisplayed() == dumpTypeShown() not needed

	mmm += indStr() + "<pointerspec name = \"ref\">\n";
	++ind;
	
	// sort them lexicographically
	AnyLexicographicSort lex;
	std::sort( m_finalReferees.begin(), m_finalReferees.end(), lex);
	RefereeList_Iterator it = m_finalReferees.begin();
	for( ; it != m_finalReferees.end(); ++it )
	{
		if (!(*it)->isAbstract())
			mmm += indStr() + "<pointeritem desc = \"" + (*it)->getName() + "\"></pointeritem>\n";
	}

	// end for
	--ind;
	mmm += indStr() + "</pointerspec>\n";
	--ind;
	mmm += indStr() + "</reference>\n";
	
	return mmm;
}

/*
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();
}

/*
// obsolete // removed upon user request 2/25/2004
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 upon user request 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;
}*/


int ReferenceRep::howManyAspectsAmongModelRefs() const
{
	ModelRep::AspectRepPtrList intersection_of_asps = getAspectsIntersection();
	return (int) intersection_of_asps.size(); 
}


AspectRep * ReferenceRep::getFirstAspectFromIntersection() const
{
	ModelRep::AspectRepPtrList intersection_of_asps = getAspectsIntersection();

	AspectRep * lowest_asp = 0;

	ModelRep::AspectRepPtrList::iterator asp_it = intersection_of_asps.begin();
	for( ; asp_it != intersection_of_asps.end(); ++asp_it)
	{
		if ( !lowest_asp) // is lowest_asp set?
			lowest_asp = *asp_it;
		else if ( !lowest_asp->lessThan( **asp_it)) // compare
			lowest_asp = *asp_it;
	}

	return lowest_asp;
}


std::vector<AspectRep *> ReferenceRep::getAspectsIntersection() const
{
	ModelRep::AspectRepPtrList intersection_of_asps;
	bool inited = false;
	std::vector<const ModelRep *> models = getModelRefVector();
	std::vector<const ModelRep *>::iterator it = models.begin();
	for( ; it != models.end(); ++it)
	{
		const ModelRep::AspectRepPtrList &asplist = (*it)->getFinalAspectRepPtrList();
		if ( !inited)
		{
			intersection_of_asps = asplist; // set the first vector as an initial value of the union
			inited = true;
		}
		else
		{
			ModelRep::AspectRepPtrList::iterator isect_it = intersection_of_asps.begin();
			while( isect_it != intersection_of_asps.end())
			{
				if ( std::find( asplist.begin(), asplist.end(), *isect_it) == asplist.end()) // element of union not found in asp set, so it should be deleted from the union
					isect_it = intersection_of_asps.erase( isect_it); // this moves the iterator ahead
				else
				 ++isect_it;
			}
		}
	}
	return intersection_of_asps;
}




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

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

#include "globals.h"
extern Globals global_vars;

Sheet * Sheet::m_theOnlyInstance = 0;
/*static*/ CComPtr<IMgaFolder> Sheet::m_BON_Project_Root_Folder = CComPtr<IMgaFolder>( 0); // important: clear its content upon destruction
Sheet::Sheet()
: m_projName(""),
	m_projVersion(),
	m_projGUID(),
	m_projCreated(),
	m_projModified(),
	m_projAuthor(),
	m_projComment(),
	m_projNamespace(),
	m_rootFolder(),
	m_fcoRepList(),
	m_atomList(),
	m_modelList(),
	m_connList(),
	m_refList(),
	m_setList(),
	m_folderList(),
	m_aspectList(),
	m_constraintList(),
	m_constraintFuncList(),
	m_attributeList()
{
}


Sheet::~Sheet()
{
	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;
		}
	}
	{
		AspectRep_Iterator ai = m_aspectList.begin();
		for( ; ai != m_aspectList.end(); ++ai)
		{
			AspectRep * act_ptr = * ai;
			delete act_ptr;
		}
	}
	{
		ConstraintRep_Iterator ai = m_constraintList.begin();
		for( ; ai != m_constraintList.end(); ++ai)
		{
			ConstraintRep * act_ptr = * ai;
			delete act_ptr;
		}
	}
	{
		ConstraintFuncRep_Iterator ai = m_constraintFuncList.begin();
		for( ; ai != m_constraintFuncList.end(); ++ai)
		{
			ConstraintFuncRep * 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_aspectList.clear();
	m_constraintList.clear();
	m_constraintFuncList.clear();

	m_attributeList.clear();
	Sheet::m_BON_Project_Root_Folder = CComPtr<IMgaFolder>(0);
}


void Sheet::setProject( IMgaProject* project)
{
	CComBSTR str;
	COMTHROW( project->get_Name( &str));
	m_projName = Util::Copy( str);
	str.Empty();

	COMTHROW( project->get_Version( &str));
	m_projVersion = Util::Copy( str);
	str.Empty();

	CComVariant v; // TODO
	COMTHROW( project->get_GUID( &v));
	m_projGUID = Util::CopyV( v);
	str.Empty();

	COMTHROW( project->get_CreateTime( &str));
	m_projCreated = Util::Copy( str);
	str.Empty();

	COMTHROW( project->get_ChangeTime( &str));
	m_projModified = Util::Copy( str);
	str.Empty();

	COMTHROW( project->get_Author( &str));
	m_projAuthor = Util::Copy( str);
	str.Empty();
	COMTHROW( project->get_Comment( &str));
	m_projComment = Util::Copy( str);
	str.Empty();
	
	CComPtr<IMgaFolder> rf;
	COMTHROW( project->get_RootFolder( &rf));
	std::string nm_val = Util::getReg( rf, "Namespace");
	//BON::RegistryNode rn = project->getRootFolder()->getRegistry()->getChild( "Namespace");
	//if( rn) m_projNamespace = rn->getValue();
	//else    m_projNamespace = "";
	if( nm_val.length() > 0) m_projNamespace = nm_val;
	else                     m_projNamespace = ""; // TODO

	// check the paradigm's name, containing spaces, other special chars, excluding '.' and '_'
	std::string new_name;
	if( !Sheet::makeValidParadigmName( m_projName, new_name))
	{
		global_vars.err << MSG_ERROR << "Error: Incorrect paradigm name: \"" << m_projName << "\". Use only alphanumerics, '.' and '_'. No spaces please. Using modified name: \"" << new_name << "\".\n";
		m_projName = new_name;
	}

	// check the namespace specified (can be empty)
	new_name = "";
	if( !Sheet::makeValidNamespace( m_projNamespace, new_name))
	{
		global_vars.err << MSG_ERROR << "Error: Incorrect namespace specified: \"" << m_projNamespace << "\". Use only alphanumerics and '_'. Using modified name: \"" << new_name << "\".\n";
		m_projNamespace = new_name;
	}
}

/*virtual*/ bool Sheet::finalize()
{
	bool ret_val = false;
	if ( doInheritance( FCO::INTERFACE) 
		&& doInheritance( FCO::IMPLEMENTATION))
	{
		init();
		initRoleNames();
		ret_val = true;
	}
	else 
		global_vars.err << MSG_ERROR << "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();
	}}

	{ConstraintFuncRep_Iterator it8 = m_constraintFuncList.begin();
	for( ; it8 != m_constraintFuncList.end(); ++it8 )
	{
		(*it8)->initNamespace();
	}}

	{ConstraintRep_Iterator it9 = m_constraintList.begin();
	for( ; it9 != m_constraintList.end(); ++it9 )
	{
		(*it9)->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;
}


AspectRep* Sheet::createAspectRep( IMgaFCO* ptr, IMgaFCO* resp_ptr)
{
	AspectRep * ll = new AspectRep( ptr, resp_ptr);
	addAspectRep( ll);
	return ll;
}


ConstraintRep* Sheet::createConstraintRep( IMgaFCO* ptr)
{
	ConstraintRep * ll = new ConstraintRep( ptr);
	addConstraintRep( ll);
	return ll;
}


ConstraintFuncRep* Sheet::createConstraintFuncRep( IMgaFCO* ptr)
{
	ConstraintFuncRep * ll = new ConstraintFuncRep( ptr);
	addConstraintFuncRep( 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::addAspectRep( AspectRep * ptr)
{
	m_aspectList.push_back( ptr);
}


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


void Sheet::addConstraintRep( ConstraintRep * ptr)
{
	m_constraintList.push_back( ptr);
}


void Sheet::addConstraintFuncRep( ConstraintFuncRep * ptr)
{
	m_constraintFuncList.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;
	}

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

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

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

	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);

}


void Sheet::replaceCliqueId( CLIQUE_VECTOR & clique_id, unsigned int id1, unsigned int id2)
{
	unsigned int search_id = id1, replace_id = id2;

	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 val = 0;
	std::map<unsigned int,unsigned int>::iterator i = t_m.begin();
	for( ; i != t_m.end(); ++i)
	{
		++val;
	}
	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);
		}
}


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;
	std::vector<unsigned int> dupl_temp;

	unsigned int no_of_cliques = howManyCliques( clique_vec);

	for( i = 0; i < node_vec.size(); ++i)
		if (depends_upon[i]==0)
			elements.push_back(i);

	if (elements.size() < no_of_cliques) // because from each clique there must be at least 1 root
	{
		TO("Inheritance loop found in model!!! Please correct it!\n");
		global_vars.err << MSG_ERROR << "Inheritance loop found in model!!! Please correct it!\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;
	
	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 << MSG_ERROR << "Loop between " << fco1 << " and " << fco2 << "\n";
					//std::cout << "Loop between " << ancestors[child][k] << " and " << child << "\n";
					loop = true;

					return false;
				}
		}
	}
	
	// using the ancestors database build up the m_desc and m_anc fields of each fco
	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_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);
			
			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 < 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);
	}
	return true;
}

/*static*/ bool Sheet::makeValidParadigmName( const std::string& pInName, std::string& res)
{
	res = pInName;
	bool inv(res.length() == 0); // invalid name?, (if empty then invalid)
	// check the paradigm's name, containing spaces, other special chars, except '.', '_'
	for( unsigned int i = 0; i < res.length(); ++i)
	{
		bool v = res[i] >= 'a' && res[i] <= 'z' ||
			res[i] >= 'A' && res[i] <= 'Z' ||
			res[i] >= '0' && res[i] <= '9' ||
			res[i] == '.' || 
			res[i] >= '_';

		if( !v)
		{
			res[i] = '_';
			inv = true;
		}
	}
	return !inv;
}

/*static*/ bool Sheet::makeValidNamespace( const std::string& pInName, std::string& res)
{
	res = pInName;
	bool inv = false;
	for( unsigned int i = 0; i < res.length(); ++i)
	{
		bool v = res[i] >= 'a' && res[i] <= 'z'
			||   res[i] >= 'A' && res[i] <= 'Z'
			||   res[i] >= '0' && res[i] <= '9' && i >= 1 // first char can't be a digit
			||   res[i] == '_';

		if( !v)
		{
			res[i] = '_';
			inv = true;
		}
	}
	return !inv;
}
--- NEW FILE: RoleRep.h ---
#ifndef ROLEREP_H
#define ROLEREP_H

class ConnectionRep;
class ConnJoint;
class ModelRep;
class SetRep;
class AtomRep;
class ReferenceRep;
class RoleRep;
class PartRep;
class FCO;

#include "string"
#include "list"
#include "vector"

class StringLex
{
public:
	bool operator()( const std::string& peer1, const std::string& peer2) const;
};

class PartStringLex
{
public:
	bool operator()( const std::string& peer1, const std::string& peer2) const;
};

class RoleStringLex
{
public:
	bool operator()( const RoleRep& peer1, const RoleRep& 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: FolderRep.cpp ---
#include "stdafx.h"

#include "FolderRep.h"
#include "Dumper.h"
#include "Broker.h"

#include "algorithm"
#include "fstream"

#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)
{ 
}


FolderRep::~FolderRep() 
{ 
	m_fcoList.clear();
	m_fcoCardList.clear();
	m_subFolderList.clear();
	m_subCardList.clear();
	m_respPointer = CComPtr<IMgaFCO>(0);
}

	
std::string FolderRep::getName() const
{
#if(0)
	if (m_respPointer == BON::FCO())
	{
		global_vars.err << MSG_ERROR << "Null pointer error in getFolderName\n";
		return std::string("Null pointer error in getFolderName");
	}
	return m_respPointer->getName();
#else // new way
	if( m_respPointer)
	{
		CComBSTR nm;
		COMTHROW( m_respPointer->get_Name( &nm));
		return m_namespace + (m_namespace.empty()?"":Any::NamespaceDelimiter_str) + Util::Copy( nm);
	}
	else
	{
		CComBSTR nm;
		COMTHROW( m_ptr->get_Name( &nm));
		return m_namespace + (m_namespace.empty()?"":Any::NamespaceDelimiter_str) + Util::Copy( nm);
	}
#endif
}

std::string FolderRep::getDispName() const
{
#if(0)
	//what about a reform such that dispname is allowed only for lonely aspects (which are not equivalent with any other)
	//<!> 
	if (m_respPointer == BON::FCO())
	{
		global_vars.err << MSG_ERROR << "Null pointer error in getDispName for aspect \"" + getName() + "\"\n";
		return std::string("Null pointer error in getDispName for folder \"") + getName() + "\"";
	}
	else
	{
		return m_ptr->getAttribute( Any::DisplayedName_str)->getStringValue();//<!> modified from m_respPointer
	}
#else // new way
	if( m_respPointer) // not a plain folder, it has its resppointer set
	{
		//return "";
		return m_userSelectedDisplayName;
	}
	else
	{
		CComBSTR val;
		COMTHROW( m_ptr->get_StrAttrByName( Util::Copy( Any::DisplayedName_str), &val));
		return Util::Copy( val);
	}
#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 << MSG_ERROR << "CHECK: "<< ptr->getPtr() << " contained by folder " << m_ptr << " twice. Disregarded.\n";
}


bool FolderRep::isFCOContained( FCO * ptr)
{
	return m_fcoList.end() != std::find( m_fcoList.begin(), m_fcoList.end(), ptr);
}


bool FolderRep::isEmpty() const
{
	//return m_fcoList.isEmpty();
	bool fco_list_empty = true;
	FCO_ConstIterator it = m_fcoList.begin();
	while ( it != m_fcoList.end())
	{
		if (!(*it)->isAbstract())
			fco_list_empty = false;
		++it;
	}
	return m_subFolderList.empty() && fco_list_empty;
}


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 << MSG_ERROR << "CHECK: Folder " << ptr->getPtr() << " contained by folder "  << m_ptr << " 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());
}


std::string FolderRep::doDump() 
{ 
	std::string m_ref = askMetaRef();

	// header
	std::string mmm = indStr() + "<folder name = \"" + getName() + "\" metaref = \"" + m_ref + "\" ";

	AnyLexicographicSort lex;
	std::sort( m_subFolderList.begin(), m_subFolderList.end(), lex);

	SubFolder_ConstIterator it_f = m_subFolderList.begin();
	if  ( it_f != m_subFolderList.end())
	{
		mmm += " subfolders = \"" + (*it_f)->getName();
		for( ++it_f; it_f != m_subFolderList.end(); ++it_f)
		{
			mmm += " " + (*it_f)->getName();
		}
		mmm += "\"";
	}

	std::sort( m_fcoList.begin(), m_fcoList.end(), lex);

	if ( !m_fcoList.empty())
	{
		std::string nnn = "";
		bool first = true;
		FCO_Iterator it = m_fcoList.begin();
		while ( it != m_fcoList.end())
		{
			if (!(*it)->isAbstract()) // check for abstract
			{
				if ( !first) nnn += " ";
				nnn += (*it)->getName();
				first = false;
			}
			++it;
		}
		if ( !nnn.empty())
			mmm += " rootobjects = \"" + nnn + "\"";
	}
	mmm += " >\n";
	
	++ind;

	// properties
	std::string f_disp = getDispName();
	if (!f_disp.empty() && f_disp != getName()) // if not empty and not the same
		mmm += dumpDispName();

	mmm += dumpConstraints();
	--ind;
	// footer
	mmm += indStr() + "</folder>\n";

	return mmm;
}


/*
This function must be called before the extend(), because the cardinalities 
are consistent till that point

Presumption: m_fcoList[i] has m_fcoCardList[i] cardinality
*/
void FolderRep::createConstraints( Sheet * s)
{
	std::vector<FCO *>::iterator fco_it = m_fcoList.begin();
	SubFolder_Iterator sub_it = m_subFolderList.begin();

	for ( unsigned int i = 0; i < m_fcoList.size(); ++i)
	{
		FCO * ptr = m_fcoList[i];
		std::string card = "";
		if (i < m_fcoCardList.size())
			card = m_fcoCardList[i];
		else
			global_vars.err << MSG_ERROR << "Error in folder \"" << m_ptr << "\" element constraint generation: not enough cardList members\n";

		std::string str_expr_end;
		std::string str_card_context;
		str_card_context = "[containment] In folder: " + getName() + ", FCO " + ptr->getName();
		bool valid_constr = ! Dumper::doParseCardinality( card, "rootObjCount", str_card_context, str_expr_end);
		if ( ! valid_constr )
		{
			global_vars.err << MSG_ERROR << "Ignoring invalid cardinality string in folder part: " << ptr->getPtr() << ". String: " << card << "\n";
		}

		std::string str_expr_begin = 
			"let rootObjCount = rootChildren()->select( child | child.oclIsTypeOf( " + ptr->getName() + " )";

		std::vector<FCO*> descendants;
		ptr->getIntDescendants( descendants);
		std::vector<FCO*>::iterator desc_it = descendants.begin();
		for( ; desc_it != descendants.end(); ++desc_it)
			str_expr_begin += " or child.oclIsTypeOf( " + (*desc_it)->getName() + ")";

		str_expr_begin += " )->size in\n                     ";
		// If Cardinality was appropriate

		if ( valid_constr && ! str_expr_end.empty() ) {

			// Build Name, EventMask, Description

			int id = Broker::getNextConstraintId();
			char str_id[64];
			sprintf( str_id, "%d", id);

			std::string str_cons_name;
			str_cons_name = "Valid" + getName() + "PartCardinality" + std::string(str_id);
			int pos = str_cons_name.find( "::");
			if( pos != std::string::npos) 
				str_cons_name.replace( pos, 2, 2, '_');

			int iEventMask = 0;
			char chMask[64];
			sprintf( chMask, "%x", iEventMask );

			std::string str_desc;
			str_desc = "Multiplicity of parts, which are contained by folder " 
				+ getName() +	", has to match "+ card + ".";

			ConstraintRep * cr = s->createConstraintRep( 0);
			std::string s_b = str_expr_begin + str_expr_end;
			cr->init( str_cons_name, /*mask:*/global_vars.genConstr.fol_cont_mask, "1", global_vars.genConstr.priority, s_b, str_desc);

			this->addInitialConstraintRep( cr); // <!> to be decided whether initial or final
			cr->attachedTo();
		}
	}
}
--- NEW FILE: Any.cpp ---
#include "stdafx.h"

#include "MyUtil.h"
#include "Any.h"
#include "ConstraintRep.h"
#include "Broker.h"
#include "Dumper.h"

#include <algorithm>

#include "globals.h"
extern Globals global_vars;

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);
}

/*static*/ const std::string Any::NamespaceDelimiter_str = "::";
/*static*/ const std::string Any::InRootFolder_str = "InRootFolder";
/*static*/ const std::string Any::DisplayedName_str = "DisplayedName";
/*static*/ const std::string Any::NameSelectorNode_str = "myNameIs";
/*static*/ const std::string Any::DisplayedNameSelectorNode_str = "myDisplayedNameIs";

/*static*/ const std::string Any::KIND_TYPE_STR[] =
{
	"ATOM",
	"MODEL",
	"CONN",
	"SET",
	"REF",
	"FCO",
	"ASPECT",
	"FOLDER",
	"CONSTRAINT",
	"CONSTRAINFUNC",
	"ATTRIBUTE"
};


Any::Any( IMgaFCO* ptr)
	: m_ptr( ptr)
	, m_isInRootFolder( false)
	, m_equivs()
	, m_initialConstraintList()
	, m_finalConstraintList()
{ 
}


Any::~Any() 
{ 
	m_equivs.clear();
	m_initialConstraintList.clear();
	m_finalConstraintList.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();
}

std::string Any::getNamespace() const
{
	return m_namespace;
}

// 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::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 m_namespace + (m_namespace.empty()?"":Any::NamespaceDelimiter_str) + Util::Copy( nm);
	}
	return "NullPtrError";
}


std::string Any::getDispName() const
{
	if ( this->m_ptr)
	{
		CComBSTR val;
		COMTHROW( m_ptr->get_StrAttrByName( Util::Copy( Any::DisplayedName_str), &val));
		return Util::Copy( val);
	}
	return "NullPtrError";
}


std::string Any::dumpDispName() const
{
	std::string mmm;
	std::string disp = getDispName();
	if ( !disp.empty())
		mmm += indStr() + "<dispname>" + Dumper::xmlFilter(disp) +"</dispname>\n";
	return mmm;
}


std::string Any::getMyKindStr() const
{
	return KIND_TYPE_STR[ getMyKind()];
}


std::string Any::getMyPrefix() const
{
	// any modification in the registry policy should be syched with
	// the Broker::initFromObj method
	if ( this->m_ptr)
		return Broker::getRegistryTokenName( m_ptr);

	throw "Error: inquiring prefix for a null object\n";
}


CComPtr<IMgaRegNode> Any::getMyRegistry() const
{
	// any modification in the registry policy should be synched with
	// the Broker::initFromObj method
	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::getMyRegistryOld() const
{
	if ( this->m_ptr && this->m_parentFolder)
	{
		CComPtr<IMgaMetaFCO> meta_fco;
		COMTHROW( m_ptr->get_Meta( &meta_fco));
		CComBSTR ster;
		if( meta_fco) COMTHROW( meta_fco->get_Name( &ster));
		std::string kind = Util::Copy( ster);
		//ASSERT( 0); 
		// not impl: getPath
		CComBSTR abs_path;
		COMTHROW( m_ptr->get_AbsPath( &abs_path));
		std::string name = Util::Copy( abs_path);

		long relid = 0;
		COMTHROW( m_ptr->get_RelID(&relid));
		char t[16];
		sprintf( t, "%x", relid);

		std::string child_name = kind + "s" + name + t;
		CComPtr<IMgaRegNode> rn;
		COMTHROW( m_parentFolder->get_RegistryNode( Util::Copy( child_name), &rn));
		return rn;
	}

	throw 1;
}

/*static*/ std::string Any::getMyPrefix( IMgaFCO* fco, IMgaFolder* f)
{
	ASSERT( fco);
	ASSERT( f);
	return Broker::getRegistryTokenName( fco);
}


/*static*/ CComPtr<IMgaRegNode> Any::getMyRegistry( IMgaFCO* fco, IMgaFolder* f)
{
	ASSERT( fco);
	ASSERT( f);
	CComPtr<IMgaRegNode> rn;
	COMTHROW( f->get_RegistryNode( Util::Copy( Any::getMyPrefix(fco, f)), &rn));
	return rn;
}


std::string Any::askMetaRef(const std::string& in_token /* = "" */) const
{
	// if called with non empty in_token, this has to have a leading slash

	// getValueByPath needs leading '/'
	// getChild doesn't need leading '/'
	// in_token may look like: "", "/Role"
	std::string token = "MetaRef" + in_token;
	std::string meta_ref = "";
	if ( this->m_ptr && this->m_parentFolder)
	{
		//meta_ref = m_ptr->getRegistry()->getValueByPath(token);
		meta_ref = Util::gvbp( getMyRegistry(), token);
			
		if (meta_ref == "") 
		{ 
			int meta_ref_int = Broker::getNextMetaRefId();
			char n_meta_ref[64];
			sprintf( n_meta_ref, "%d", meta_ref_int);
			//m_ptr->getRegistry()->setValueByPath( token, n_meta_ref);
			Util::svbp( getMyRegistry(), token, n_meta_ref);
			meta_ref = n_meta_ref;
		}
		return meta_ref;
	}
	else // added for dummy aspects
	{
		int meta_ref_int = Broker::getNextMetaRefId();
		char n_meta_ref[64];
		sprintf( n_meta_ref, "%d", meta_ref_int);
		//Util::svbp( getMyRegistry(), token, n_meta_ref);
		meta_ref = n_meta_ref;
		return meta_ref;
	}
	return "NullPtrError";
}


void Any::addInitialConstraintRep( ConstraintRep * constraint)
{
	ConstraintRepPtrList_ConstIterator it = 
		std::find( m_initialConstraintList.begin(), m_initialConstraintList.end(), constraint);

	if ( it == m_initialConstraintList.end())
		m_initialConstraintList.push_back( constraint);
	else
		global_vars.err << MSG_ERROR << constraint->getName() << " constraint owned by " << m_ptr << " twice\n";
}


const Any::ConstraintRepPtrList& Any::getInitialConstraintRepPtrList() const
{
	return m_initialConstraintList;
}


void Any::addFinalConstraint( ConstraintRep * constraint)
{
	ConstraintRepPtrList_ConstIterator c_it = 
		std::find( m_finalConstraintList.begin(), m_finalConstraintList.end(), constraint);

	if ( c_it == m_finalConstraintList.end())
		m_finalConstraintList.push_back( constraint);
	/*else - because of multiple inheritance this can happen easily
		global_vars.err << constraint->getName() << " inherited constraint owned by " << getName() << " twice\n";*/
}


void Any::addFinalConstraintList( const ConstraintRepPtrList & list)
{
	ConstraintRepPtrList_ConstIterator it = list.begin();
	for( ; it != list.end(); ++it)
		addFinalConstraint( *it);
}


std::string Any::dumpConstraints()
{
	std::string mmm = "";

	AnyLexicographicSort lex;
	std::string last_name = "";
	std::sort( m_finalConstraintList.begin(), m_finalConstraintList.end(), lex );

	ConstraintRepPtrList_ConstIterator c_i = m_finalConstraintList.begin();
	for( ; c_i != m_finalConstraintList.end(); ++c_i)
	{
		mmm += ( *c_i)->doDump();
		if ( last_name != "" && last_name == (*c_i)->getName())
			global_vars.err << MSG_ERROR << "Duplicate constraint name " << (*c_i)->getName() << " found for " << m_ptr << "\n";
		last_name = (*c_i)->getName();
	}
	return mmm;
}



--- NEW FILE: ConstraintFuncRep.h ---
#ifndef CONSTRAINTFUNC_H
#define CONSTRAINTFUNC_H

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

class ConstraintFuncRep : public Any
{
public:
	ConstraintFuncRep( IMgaFCO* ptr);
	std::string doDump();
	/*virtual*/ std::string getName() const;
	Any::KIND_TYPE getMyKind() const { return Any::CONSTRAINTFUNC; }

protected:
	void fetch();
	std::string m_context;
	std::string m_returntype;
	std::string m_stereotype;
	std::string m_definition;
	std::string m_parameterlist;
	std::string m_defdForNamesp;

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

};
#endif //CONSTRAINTFUNC_H

--- NEW FILE: RootFolder.h ---
#ifndef ROOTFOLDER_H
#define ROOTFOLDER_H

#include "Any.h"
#include "PartRep.h"
#include "FCO.h"
#include "ConstraintFuncRep.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;
	bool isEmpty() const;

	void addSubFolder( FolderRep * ptr);

	std::string headDump();
	std::string tailDump();


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 "Broker.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();
}


bool RootFolder::isEmpty() const
{
	return m_fcoList.empty() && m_subFolderList.empty();
}


void RootFolder::addSubFolder( FolderRep *ptr)
{
	m_subFolderList.push_back( ptr);
}


std::string RootFolder::headDump() 
{ 
	++ind;
	std::string mmm = indStr() + "<folder name = \"RootFolder\" metaref = \"" + Broker::ROOTFOLDER_METAREF_STR + "\" ";

	AnyLexicographicSort lex;
	std::sort( m_subFolderList.begin(), m_subFolderList.end(), lex);
	SubFolder_ConstIterator it_f = m_subFolderList.begin();
	if  ( it_f != m_subFolderList.end())
	{
		mmm +=" subfolders = \"";
		bool first = true;
		while( it_f != m_subFolderList.end())
		{
			if (!first) mmm += " ";
			mmm += (*it_f)->getName();
			first = false;
			++it_f;
		}
		mmm +="\"";
	}

	std::sort( m_fcoList.begin(), m_fcoList.end(), lex);

	if ( !m_fcoList.empty())
	{
		std::string nnn;
		bool first = true;
		FCO_ConstIterator it = m_fcoList.begin();
		while ( it != m_fcoList.end())
		{
			if ((*it)->isFCO() && !(*it)->isAbstract())
			{
				if ( !first) nnn += " ";
				nnn += (*it)->getName();
				first = false;
			}
			++it;
		}
		
		if ( !nnn.empty()) 
			mmm += " rootobjects = \"" + nnn + "\"";
	}
	mmm += " >\n";
	return mmm;
}


std::string RootFolder::tailDump() 
{ 
	--ind;
	std::string mmm;
	mmm = indStr() + "</folder>\n";

	return mmm;
}

--- 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();
	std::string p2_n = p2.name();
	int k = p1_n.compare( p2_n);

	return (k < 0 );
}


PointerItem::PointerItem( std::string name): m_name( name)
{ }

PointerItem::PointerItem( const PointerItem& peer): m_name( peer.m_name)
{ }

const PointerItem& PointerItem::operator=( const PointerItem& peer)
{
	if (&peer == this) return *this;
	m_name = peer.m_name;
	return *this;
}

bool PointerItem::operator==( const PointerItem& peer) const
{
	return m_name == peer.m_name;
}

bool PointerItem::operator!=( const PointerItem& peer) const
{
	return !operator==(peer);
}

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

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

#include "logger.h"
#include "Broker.h"
#include "AspectRep.h"
#include "map"

/* static vars to be initialized */
int	Broker::m_constraintId = 1;
const int Broker::INVALID_METAREF = -1;
const int Broker::INITIAL_METAREF = 1001; // the next available metaref
const std::string Broker::ROOTFOLDER_METAREF_STR = "1000"; // used by the "RootFolder"
int	Broker::m_metaRefId = INITIAL_METAREF;
int Broker::m_firstFree = INITIAL_METAREF;
std::list<Broker::MetaRefNode> Broker::m_metaRefDB;


/*This method resets all static variables of Broker. Called by the Dumper::~Dumper*/
void Broker::reset()
{
	m_metaRefDB.clear();
	m_firstFree = INITIAL_METAREF;

	m_constraintId = 0;
	m_metaRefId = INITIAL_METAREF;
}


void Broker::init()
{
	// this is called after the actual project registry has been scanned through
	// and the values can be set based on the information found
	m_constraintId = 1;
	m_metaRefId = (m_firstFree > INITIAL_METAREF)?m_firstFree : INITIAL_METAREF;
	/*char d[10];
	sprintf(d, "%i", m_metaRefId);
	global_vars.err <<  std::string(d) << " used as max metaref\n";*/

	m_metaRefDB.clear(); // after we know the greatest metaref this can be deleted
}


int Broker::getNextConstraintId()
{
	return m_constraintId++;
}


int Broker::getNextMetaRefId()
{
	return m_metaRefId++;
}

std::string Broker::getRegistryTokenName( IMgaObject* obj)
{
	std::string kind = Util::kind( obj);
	std::string name = Util::composePath( obj, true);

	long relid = 0;
	COMTHROW( obj->get_RelID(&relid));
	char t[16];
	sprintf( t, "%x", relid);

	ASSERT( name.length() >= 0);
	std::string tmp = name + '-' + t + '-' + kind;
	//return kind + "s" + name + t;
	return tmp;
}


void Broker::initFromObj( IMgaObject* obj, IMgaFolder* folder, const std::string& kind)
{
	// any modification in the registry policy should be syched with
	// the Any::getMyPrefix() Broker::initFromObj method

	std::string token = Broker::getRegistryTokenName( obj) + "/MetaRef";

	CComPtr<IMgaRegNode> rn;
	COMTHROW( folder->get_RegistryNode( Util::Copy( token), &rn));

	initFromRegistry( obj, folder, rn);
}

// folder is the root folder
void Broker::initFromAspectObj( IMgaObject* obj, const std::string& name, IMgaFolder* folder)
{
	// any modification in the registry policy should be syched with
	// the Broker::initFromObj method
	//std::string token = obj->getID() + ":" + obj->getName() + "/MetaRef";
	std::string token = AspectRep::m_aspectRegistryRoot + '/' + AspectRep::m_aspectMetaRefsRoot + '/' + name + "/MetaRef";

	CComPtr<IMgaRegNode> rn;
	COMTHROW( folder->get_RegistryNode( Util::Copy( token), &rn));

	initFromRegistry( obj, folder, rn);
}

void Broker::initFromRegistry(  IMgaObject* obj, IMgaFolder* folder, IMgaRegNode* reg_node)
{
	long status = 0; 
	COMTHROW( reg_node->get_Status( &status));

	if ( status == 0) // 0: here, -1: in meta, >=1: inherited")]
	{
		CComBSTR val;
		COMTHROW( reg_node->get_Value( &val));

		std::string sval = Util::Copy( val);
		int k = 0;
		if( !sval.empty())
		{
			int sc = sscanf( sval.c_str(), "%d", &k);
			ASSERT( sc == 1);
		}
		
		CComBSTR path;
		COMTHROW( reg_node->get_Path( &path));

		MetaRefNode node( obj, folder, Util::Copy( path), k);
		m_metaRefDB.push_back( node);
		m_firstFree = max( m_firstFree, node.metaref + 1);
	}

	// subnodes here
	CComPtr<IMgaRegNodes> children;
	COMTHROW( reg_node->get_SubNodes( VARIANT_TRUE, &children));

	long c = 0;
	if( children) COMTHROW( children->get_Count( &c));

	// for all subnodes
	for( long i = 1; i <= c; ++i)
	{
		CComPtr<IMgaRegNode> item;
		COMTHROW( children->get_Item( i, &item));

		initFromRegistry( obj, folder, item);
	}
}


void Broker::checkDuplicates()
{
	// map of metaref_int, and metaRefDB::iterator
	// since the list allows removing elements without invalidating iterators
	std::map< int, MetaRefDB_Iterator > check_map;

	MetaRefDB_Iterator it = m_metaRefDB.begin();
	for( ; it != m_metaRefDB.end(); ++it)
	{
		MetaRefNode node = *it;

		std::map< int, MetaRefDB_Iterator >::iterator map_it = check_map.end();
		map_it = check_map.find( node.metaref); 

		if ( map_it != check_map.end()) // same metaref found in the check_map
		{
			MetaRefDB_Iterator jt = map_it->second;
			MetaRefNode otherNode = *jt;
			int t_1 = otherNode.metaref;
			bool flag = false;

			CComBSTR b_id1, b_id2, b_nm;
			COMTHROW( node.obj->get_ID( &b_id1));
			COMTHROW( otherNode.obj->get_ID( &b_id2));
			std::string m1 = Util::Copy( b_id1);
			std::string m2 = Util::Copy( b_id2);
			//bool similar = (node.obj == otherNode.obj);//t
			COMTHROW( node.obj->get_Name( &b_nm));
			std::string p = Util::Copy( b_nm);
			if ( m1 < m2)
			{
				m_metaRefDB.erase( jt);
				check_map[ node.metaref] = it;
				flag = true;
			}
			else
			{
				it = m_metaRefDB.erase(it); // "it" will point to the next element
				--it; // decrement in order to stay consistent within the for cycle
				flag = false;
			}
			std::string token = (flag ? otherNode : node).path.substr(1);
			try {
				//(flag ? otherNode : node).obj->getRegistry()->getDescendantByPath( dpath.substr(1))->clear(); // reset the respective node
				if ( flag)
				{
					CComPtr<IMgaRegNode> rn;
					COMTHROW( otherNode.folder->get_RegistryNode( Util::Copy( token), &rn));
					if( rn) COMTHROW( rn->Clear()); //reset
				}
				else
				{
					CComPtr<IMgaRegNode> rn;
					COMTHROW( node.folder->get_RegistryNode( Util::Copy( token), &rn));
					if( rn) COMTHROW( rn->Clear()); //reset
				}
#ifdef _DEBUG
				CComBSTR btnodnm, bonodnm;
				COMTHROW( node.obj->get_Name( &btnodnm));
				COMTHROW( otherNode.obj->get_Name( &bonodnm));
				std::string fmtstr = std::string("Duplicate metaref found. Class ") + (flag ? Util::Copy( bonodnm) : Util::Copy( btnodnm)) +
					" subnode: " + std::string((flag ? otherNode : node).path.empty() ? "n/a" : (flag ? otherNode : node).path + " has been reset to Undefined value");
				std::string n1str = "Name" + Util::Copy( btnodnm) + " path: " + node.path;
				std::string n2str = "Name" + Util::Copy( bonodnm) + " path: " + otherNode.path;
				//if (t_1) global_vars.err << fmtstr << "\n" << n1str << "\n" << n2str << "\n";
#endif
			}
			catch(...) {
				// in case of library fco-s the operation above is causing an assertion/exception
			}
		}
		else 
		{
			check_map[node.metaref] = it;
		}
	}
}


--- NEW FILE: ConstraintRep.h ---
#ifndef CONSTRAINTREP_H
#define CONSTRAINTREP_H

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

class ConstraintRep : public Any
{
public:
	ConstraintRep( IMgaFCO* ptr);
	/*virtual*/ std::string doDump();
	/*virtual*/ std::string getName() const;
	/*virtual*/ std::string getDispName() const;
	void init( const std::string&, int m, const std::string& depth, int p, const std::string&, const std::string&);
	Any::KIND_TYPE getMyKind() const { return Any::CONSTRAINT; }

	void attachedTo();
	bool isAttached() const;

protected:
	void fetchEventAttribute( const std::string& event_name, unsigned int event_flag);
	void fetch();

	/**
	 * attached: means is used by some FCO so upon dumping 
	 *    is dumped as local constraint of that FCO
	 *  if not attached then it will be dumped along with global attributes
	 */
	bool m_attached;
	std::string m_name; // used because artificial constraints must have a name
	std::string m_description;
	std::string m_defaultParams;
	std::string m_equation;
	int m_priority;
	//int m_depth;
	std::string m_depth;
	std::string m_defdForNamesp;
	int m_eventMask;

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

};
#endif //CONSTRAINTREP_H

--- NEW FILE: Dumper.h ---
#ifndef DUMPER_H
#define DUMPER_H

#include "list"
#include "vector"
#include "Sheet.h"
#include "functional"

class Dumper : public Sheet {

protected:
	Dumper();

public:
	static Sheet * getInstance();
	virtual ~Dumper();

	bool build();


	static std::string makeValidFileName( const std::string& pInFile);
	static int selectOutputFiles( IMgaProject*, const std::string& proj_name, const std::string& project_path);
	static int selectOptions( IMgaProject*);
	static void registerIt( const std::string& f_name);
	static bool doParseCardinality
		(const std::string& cardinality, 
		const std::string &target, 
		const std::string &contextDesc, 
		std::string &expr);
	
	static std::string xmlFilter( const std::string& in);

protected:

	void createConstraints();
	void inheritMoReSeCoFolAsp();
	void inheritAspConsAttr();

	void doAspectPartsMap();
	// creates elements from element hierarchies

	
	void doDump();
	bool sortPtrs();
	bool aspectOrderSel(); // aspect Order Selection
	bool am(); // aSPECT mAPPING
	bool checkUniqueAspectNames();
	bool checkAll();
	bool checkRootFolder() const;
	bool checkAllFCOs();
	bool checkOrphanAttributes();
	bool checkEmptyFolders() const;
	bool findInFolders( FCO * fco);
	void findMaxOfMetaRefs();

protected:

	void inheritConstraintsAndAttributes( FCO * ptr, FCO * c_ptr);
	std::vector<AspectRep *> findAspectBasedOnName(const std::string & name_to_find) const;
};

#endif //DUMPER_H

--- NEW FILE: ConnJoint.h ---
#ifndef CONNJOINT_H
#define CONNJOINT_H

#include "Any.h"
#include "RoleRep.h"
#include "PointerItem.h"
#include "FCO.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);

	std::string dumpElements( FCO::ModelRepPtrList & model_list);

	bool checkElements( std::string connection_name);
	void createConstraints( Sheet*, const std::string& conn_name);

	bool descendantsOf( const ConnJoint& peer) const;

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;

};

#endif //CONNJOINT_H



More information about the GME-commit mailing list