// MetaElements.cpp: implementation of the MetaElements class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MetaElements.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern void AddToLog(CString);
extern void ClearUpLog();
UMLClass::UMLClass()
{

}

UMLClass::~UMLClass()
{
	//删除活动图
	for( int i = 0 ; i <= m_ActivityGraphs.GetUpperBound() ; i ++ )
	{
		UMLActivityGraph *p = m_ActivityGraphs.GetAt( i );
		delete p;
	}
	m_ActivityGraphs.RemoveAll();
}
UMLActivity::UMLActivity()
{
	m_pClass = NULL;
	m_pOwnedElement = NULL;
}
UMLActivity::~UMLActivity()
{
}

UMLActionActivity::UMLActionActivity()
{
	m_ActivityKind = ACTIVITY_ACTION;
}
UMLActionActivity::~UMLActionActivity()
{
}

UMLSubActivity::UMLSubActivity()
{
	m_pActivityGraph = NULL;
	m_ActivityKind = ACTIVITY_SUB;
}
UMLSubActivity::~UMLSubActivity()
{
}

UMLActivityGraph::UMLActivityGraph()
{
	m_pClass = NULL;
}
UMLActivityGraph::~UMLActivityGraph()
{
	if( m_Swimlanes.GetUpperBound()>= 0)
	{
		//活动属于泳道
		for( int i= 0 ; i <= m_Swimlanes.GetUpperBound() ; i ++ )
		{
			UMLSwimlane *p = m_Swimlanes.GetAt( i );
			delete p;
		}
	}
	else
	{//活动不属于泳道
		for( int i = 0 ; i <= m_Activities.GetUpperBound() ; i++ )
		{
			UMLActivity *p = m_Activities.GetAt( i );
			delete p;
		}
	}
	//删除转换边
	for( int i = 0 ; i <= m_Edges.GetUpperBound() ; i ++ )
	{
		UMLTransEdge *p = m_Edges.GetAt( i );
		delete p;
	}
	//删除控制流
	for( i = 0 ; i <= m_ControlFlows.GetUpperBound() ; i ++ )
	{
		UMLControlFlow * pCF = m_ControlFlows.GetAt( i );
		delete pCF;
	}
}

UMLAttribute::UMLAttribute()
{
	m_Visibility = VISIBILITY_PUBLIC;
	m_OrderingKind = ORDERING_NONE;
	m_Multiplicity = "1";
	m_pType = NULL;
}
UMLAttribute::~UMLAttribute()
{
}

UMLModelElement::UMLModelElement()
{
	m_pNamespace = NULL;
}
UMLModelElement::~UMLModelElement()
{

}

UMLParameter::UMLParameter()
{
	m_DirKind = PARAMETER_DIR_INOUT;
	m_pType = NULL;
}
UMLParameter::~UMLParameter()
{

}

UMLOperation::UMLOperation()
{
	m_Visibility = VISIBILITY_PUBLIC;
}
UMLOperation::~UMLOperation()
{

}

UMLRelationship::UMLRelationship()
{

}
UMLRelationship::~UMLRelationship()
{

}

UMLNamespace::UMLNamespace()
{
}
UMLNamespace::~UMLNamespace()
{

}

UMLGeneralizableElement::UMLGeneralizableElement()
{

}
UMLGeneralizableElement::~UMLGeneralizableElement()
{

}

UMLAssociationEnd::UMLAssociationEnd()
{
	m_pParticipent = NULL;
	m_Aggregation = AGGREGATION_NONE;
	m_IsNavigable = FALSE;
	m_Multiplicity = "1";
	m_Ordering = ORDERING_NONE;
	m_pAssociation = NULL;
	m_Visibility = VISIBILITY_PUBLIC;
}
UMLAssociationEnd::~UMLAssociationEnd()
{

}

void UMLAssociationEnd::SetParticipent(UMLClass *p)
{
	m_pParticipent = p;
}	

UMLClass* UMLAssociationEnd::GetParticipent()
{
	return m_pParticipent;
}

UMLElement::UMLElement()
{
}
UMLElement::~UMLElement()
{

}

UMLAssociation::UMLAssociation()
{
	m_Connection[ 0 ].m_pAssociation = this;
	m_Connection[ 1 ].m_pAssociation = this;
}
UMLAssociation::~UMLAssociation()
{

}

UMLOperation::UMLOperation(UMLOperation &e)
{
	m_ReturnType = e.m_ReturnType ;
	m_TypedParameter = e.m_TypedParameter;
	m_Visibility = e.m_Visibility;
	name = e.name;
}
UMLOperation &UMLOperation::operator =(UMLOperation &e)
{
	m_ReturnType = e.m_ReturnType ;
	m_TypedParameter = e.m_TypedParameter;
	m_Visibility = e.m_Visibility;
	name = e.name;
	return *this;
}

UMLAssociation* UMLAssociationEnd::GetAssociation()
{
	return m_pAssociation;
}

UMLTransEdge::UMLTransEdge()
{
	m_pActivities[ 0 ] = NULL;
	m_pActivities[ 1 ] = NULL;
}
UMLTransEdge::~UMLTransEdge()
{

}

UMLControlFlow::UMLControlFlow()
{
	m_pBegin = NULL;
	m_pFirstEdge = NULL;
	m_pMainCFEnd = NULL;
}
UMLControlFlow::~UMLControlFlow()
{

}

UMLSwimlane::UMLSwimlane()
{

}
UMLSwimlane::~UMLSwimlane()
{
	for( int i = 0 ; i <= m_Activities.GetUpperBound() ; i ++ )
	{
		UMLActivity *p = m_Activities.GetAt( i );
		delete p;
	}
}

UMLSynchActivity::UMLSynchActivity()
{
	m_ActivityKind = ACTIVITY_SYNCH;
	m_pSynchActivityNext = NULL;
	m_pSynchActivityLast = NULL;
}
UMLSynchActivity::~UMLSynchActivity()
{

}


void UMLActivityGraph::GetControlFlows()
{
	CPtrTempl<UMLSynchActivity*>synches;
	//删除已有控制流
	for( int t = 0 ; t <= m_ControlFlows.GetUpperBound() ; t ++)
	{
		UMLControlFlow *pc = m_ControlFlows.GetAt( t ) ; 
		int idx = pc->m_pBegin->m_BeginControlFlow.GetFirstIdx( pc );
		pc->m_pBegin->m_BeginControlFlow.RemoveAt( idx );
		for( int i = 0 ; i <= pc->m_pEndList.GetUpperBound() ; i ++ )
		{
			UMLSynchActivity *pSA = pc->m_pEndList.GetAt( i );
			idx = pSA->m_EndControlFlow.GetFirstIdx( pc );
			pSA->m_EndControlFlow.RemoveAt( idx );
		}
		pc->m_pEndList.RemoveAll();
		delete pc;
	}
	m_ControlFlows.RemoveAll();

	//查找并发活动
	if( m_Swimlanes.GetUpperBound() >= 0 )
	{
		//包含泳道
		for( int i = 0 ; i <= m_Swimlanes.GetUpperBound() ; i ++ )
		{
			UMLSwimlane *pS = m_Swimlanes.GetAt( i );
			for( int j = 0 ; j <= pS->m_Activities.GetUpperBound() ; j ++ )
			{
				UMLActivity *pA = pS->m_Activities.GetAt( j );
				if( pA->m_ActivityKind == ACTIVITY_SYNCH )
				{
					synches.Add( (UMLSynchActivity*)pA );
				}
			}
		}
	}
	else
	{//不包含泳道
		for( int i = 0 ; i <= m_Activities.GetUpperBound() ; i ++ )
		{
			UMLActivity *pA = m_Activities.GetAt( i );
			if( pA->m_ActivityKind == ACTIVITY_SYNCH )
			{
					synches.Add( (UMLSynchActivity*)pA );
			}
		}
	}
	//生成控制流
	for( t = 0 ; t <= synches.GetUpperBound() ; t ++ )
	{
		UMLSynchActivity *s = synches.GetAt( t );
		for(  int i = 0 ; i <= s->m_OutTransEdge.GetUpperBound() ; i ++ )
		{
			UMLTransEdge *e = s->m_OutTransEdge.GetAt( i );
			UMLControlFlow *pF;
			pF = GetControlBySynchAndEdge( s , e );
			if( pF )
			{
				CString txt;
				txt.Format("controlflow of edge:%s has %d activities",e->name,pF->m_pActivities.GetUpperBound() + 1);
				//AfxMessageBox( txt );
				AddToLog( txt );
				m_ControlFlows.Add( pF );
				pF->m_pBegin->m_BeginControlFlow.Add( pF );
				for( int xi = 0 ; xi <= pF->m_pEndList.GetUpperBound() ; xi ++ )
				{
					UMLSynchActivity *pUSA = pF->m_pEndList.GetAt( xi );
					pUSA->m_EndControlFlow.Add( pF );
				}
			}
		}
		
	}
	//分解主控制流
	DetachMainControlFlow( );
	//设置所有控制流所属的主控制流的等待点
	CPtrTempl<UMLSynchActivity*>hasNext;

	//－找到所有有NEXT的节点
	for( int i = 0 ; i <= synches.GetUpperBound() ; i ++ )
	{
		UMLSynchActivity *pUSA = synches.GetAt( i );
		if( pUSA->m_pSynchActivityNext )
		{
			hasNext.Add( pUSA );
		}
	}
	//-从有next的节点开始向后遍历
	for( i = 0 ; i <= hasNext.GetUpperBound() ; i ++ )
	{
		CPtrTempl<UMLSynchActivity*>all;
		CPtrTempl<UMLActivity*>tn,utn;
		UMLSynchActivity * cur = hasNext.GetAt( i );
		utn.Add( cur );
		while( utn.GetUpperBound() >= 0 )
		{
			UMLActivity* p = utn.GetAt( 0 );
			if( p != cur->m_pSynchActivityNext )
			{
				for( int j = 0 ; j <= p->m_OutTransEdge.GetUpperBound() ;j ++ )
				{
					UMLTransEdge *e = p->m_OutTransEdge.GetAt( j );
					if( !tn.Find( e->m_pActivities[ 1 ] ) && !utn.Find( e->m_pActivities[ 1 ] ) )
					{
						utn.Add( e->m_pActivities[ 1 ] );
					}
				}
			}
			if( p->m_ActivityKind == ACTIVITY_SYNCH )
			{
				UMLSynchActivity* a = (UMLSynchActivity*)p;
				if( !all.Find( a ) )
				{
					all.Add( a );
				}
			}
			tn.Add( p );
			utn.RemoveAt( 0 );
		}
		for( int j = 0 ; j <= m_ControlFlows.GetUpperBound(); j ++ )
		{
			UMLControlFlow *pu = m_ControlFlows.GetAt( j );
			BOOL ok = TRUE;
			if( !all.Find( pu->m_pBegin ) )
			{
				ok = FALSE;
			}
			else
			{
				for( int k = 0 ; k <= pu->m_pEndList.GetUpperBound() ; k ++ )
				{
					UMLSynchActivity *ed = pu->m_pEndList.GetAt( k );
					if( !all.Find( ed ) )
					{
						ok = FALSE;
						break;
					}
				}
			}
			if( ok )
			{
				pu->m_pMainCFEnd = cur->m_pSynchActivityNext ;
			}
		}
	}
}

UMLControlFlow* UMLActivityGraph::GetControlBySynchAndEdge(UMLSynchActivity *a, UMLTransEdge *edge)
{
	UMLControlFlow *rlt = NULL;
	CPtrTempl<UMLActivity*>traversedA;
	CPtrTempl<UMLActivity*>newA;
	traversedA.Add( a );
	newA.Add( edge->m_pActivities[ 1 ] );
	rlt = new UMLControlFlow;
	rlt->m_pBegin = a;
	//rlt->m_pEnd = NULL;
	rlt->m_pFirstEdge = edge;
	rlt->m_pEdges.Add( edge );
	{//LOG
		CString log;
		log.Format("fetching control from syns:%s edge:%s",LPCTSTR(a->name) , LPCTSTR(edge->name));
		AddToLog( log );
	}
	while( newA.GetUpperBound() >= 0 )
	{
		//移出一个新的后继节点
		UMLActivity *pA = newA.GetAt( 0 );
		newA.RemoveAt( 0 );
		//如果后继节点已经遍历过，就抛弃
		if( traversedA.Find( pA ) ) continue;
		//如果后继节点是并发节点，那么结束处理
		if( pA->m_ActivityKind == ACTIVITY_SYNCH )
		{
			rlt->m_pEndList.Add( (UMLSynchActivity*) pA );
			//rlt->m_pEnd = (UMLSynchActivity*)pA;
			//AddToLog("got control flow");
			//return rlt;
			traversedA.Add( pA );
			continue;
		}
		//如果后继节点是终止节点，停止处理
		if( pA->m_ActivityKind == ACTIVITY_FINISH )
		{
			AddToLog("discard for noncontrolflow");
			delete rlt;
			return NULL;
		}
		//如果不是并发节点，添加到遍历集，并将其后继添加到新集合
		traversedA.Add( pA );
		rlt->m_pActivities.Add( pA );
		for( int i = 0 ; i <= pA->m_OutTransEdge.GetUpperBound() ; i ++ )
		{
			UMLTransEdge *edge = pA->m_OutTransEdge.GetAt( i );
			if( traversedA.Find(edge->m_pActivities[ 1 ]) == FALSE && newA.Find( edge->m_pActivities[ 1 ] ) == FALSE )
			{
				newA.Add( edge->m_pActivities[ 1 ] );
				rlt->m_pEdges.Add( edge );
			}
		}
	}
	if( rlt->m_pEndList.GetUpperBound() < 0 )
	{//没有终止并发节点
		AddToLog("discard for noncontrolflow");
		delete rlt;
		return NULL;
	}
	{
		CString txt;
		txt.Format("Got a control flow with %d synch end",rlt->m_pEndList.GetUpperBound() + 1);
		AddToLog( txt );
	}
	return rlt;
}

UMLElementType UMLModelElement::Type()
{
	return TYPE_ELEMENT;
}

UMLElementType UMLActionActivity::Type()
{
	return TYPE_ACTIONACTIVITY;
}

UMLElementType UMLActivity::Type()
{
	return TYPE_ACTIVITY;
}

UMLElementType UMLActivityGraph::Type()
{
	return TYPE_ACTIVITYGRAPH;
}

UMLElementType UMLAssociation::Type()
{
	return TYPE_ASSOCIATION;
}

UMLElementType UMLAssociationEnd::Type()
{
	return TYPE_ASSOCIATIONEND;
}

UMLElementType UMLAttribute::Type()
{
	return TYPE_ATTRIBUTE;
}

UMLElementType UMLClass::Type()
{
	return TYPE_CLASS;
}

UMLElementType UMLControlFlow::Type()
{
	return TYPE_CONTROLFLOW;
}

UMLElementType UMLGeneralizableElement::Type()
{
	return TYPE_GELEMENT;
}

UMLElementType UMLNamespace::Type()
{
	return TYPE_NAMESPACE;
}

UMLElementType UMLOperation::Type()
{
	return TYPE_OPERATION;
}

UMLElementType UMLParameter::Type()
{
	return TYPE_PARAMETER;
}

UMLElementType UMLRelationship::Type()
{
	return TYPE_RELATIONSHIP;
}

UMLElementType UMLSubActivity::Type()
{
	return TYPE_SUBACTIVITY;
}

UMLElementType UMLSwimlane::Type()
{
	return TYPE_SWIMLANE;
}

UMLElementType UMLSynchActivity::Type()
{
	return TYPE_SYNCHACTIVITY;
}

UMLElementType UMLTransEdge::Type()
{
	return TYPE_TRANSEDGE;
}

void UMLActivityGraph::DetachMainControlFlow()
{
/*（错）
1.找到第一个并发节点和最后一个并发节点"对"
2.找到所有连接并发活动的桥的桥头和桥尾
3.排序这些并发节点
4.串接主控制流
*/
/*
1、找出所有的控制流CS
2、一个新的控制流集合CSi
3、任取出一个控制流C，CSi += C,CS-=C
4、如果CS有某个C'与CSi中的某个控制流同端,那么CSi+=C',转到4,否则转到5
5、计算CSi中的所有桥，去掉桥，得到n个子集，将各个子集头尾相连，如果CS不空转到2，否则结束
*/
/*
1、用所有的控制流的起始终止并发节点组成临接矩阵，对于那些孤立的并发节点就是并发起始节点
2、从并发起始节点开始，构造从起始节点可达的所有并发节点集A
3、从A中去掉无平行边桥
4、从新计算并发起始节点，并计算并发终止节点，连接
*/
	CPtrTempl<UMLSynchActivity*>syns;
	CObjTempl<int>allEnd;
	ReachableArray ra;
	AddToLog("Checking controlflow set:");
	//找到所有的并发节点
	for( int i = 0 ; i <= m_ControlFlows.GetUpperBound() ; i ++ )
	{
		UMLControlFlow *pCF = m_ControlFlows.GetAt( i );
		if( !syns.Find( pCF->m_pBegin ) ) syns.Add( pCF->m_pBegin );
		for( int j = 0 ; j <= pCF->m_pEndList.GetUpperBound() ; j ++ )
		{
			UMLSynchActivity *pUSA = pCF->m_pEndList.GetAt( j );
			if( !syns.Find(pUSA ) ) syns.Add( pUSA );
		}
	}
	if( syns.GetUpperBound() < 0 )
	{
		AddToLog("Checking controlflow set finished");
		return;
	}
	//构造临接矩阵
	ra.Init( syns.GetUpperBound() + 1 );
	for( i  = 0 ; i <= m_ControlFlows.GetUpperBound() ; i ++ )
	{
		UMLControlFlow *pCF = m_ControlFlows.GetAt( i );
		int tail , head;
		tail = syns.GetFirstIdx( pCF->m_pBegin );
		for( int j = 0 ; j <= pCF->m_pEndList.GetUpperBound() ; j ++)
		{
			UMLSynchActivity *pUSA = pCF->m_pEndList.GetAt( j );
			head = syns.GetFirstIdx( pUSA );
			ra.SetEdge( tail , head );
		}
	}
	ra.PrepareForCal();
	ra.Cal();
	//找到所有的尾节点：所有不可达的节点
	for( i = 0 ; i <= syns.GetUpperBound() ; i ++ )
	{
		BOOL found = TRUE;
		for( int j = 0 ; j <= syns.GetUpperBound() ; j ++ )
		{
			if( i == j )continue;
			if( ra.Reachable( i , j ) )
			{
				found = FALSE;
				break;
			}
		}
		if( found ) allEnd.Add( i );
	}
	//找到所有到某个尾节点都可达的节点
	
	for( i = 0 ; i < allEnd.GetSize() ; i ++ )
	{
		CObjTempl<int>allReachable;
		ReachableArray ras;//二次索引
		int idx = allEnd.GetAt( i );
		for( int j = 0 ; j <= syns.GetUpperBound() ; j ++ )
		{
			if( idx != j && ra.Reachable( j , idx ) ) allReachable.Add( j );
		}
		allReachable.Add( idx );
		ras.Init( allReachable.GetSize() );
		//allReachable中所有的节点连成一片
		//在allReachable中查找桥，去掉桥，然后在将联通的分支头尾相连
		for( j  = 0 ; j <= m_ControlFlows.GetUpperBound() ; j ++ )
		{
			UMLControlFlow *pCF = m_ControlFlows.GetAt( j );
			int tail , head;
			int atail , ahead;
			tail = syns.GetFirstIdx( pCF->m_pBegin );
			atail = allReachable.Find( tail );
			for( int k = 0 ; k <= pCF->m_pEndList.GetUpperBound() ; k ++ )
			{
				UMLSynchActivity *pUSA = pCF->m_pEndList.GetAt( k );
				head = syns.GetFirstIdx( pUSA );
				ahead = allReachable.Find( head );
				if( atail >=0 && ahead >= 0 )
				{
					ras.SetEdge( atail , ahead );
				}
			}
		}
		ras.PrepareForCal();
		ras.Cal();
		/*查找桥*/
		CObjTempl<POINT>bridges;
		for( j = 0 ; j < allReachable.GetSize() ; j ++ )
		{
			for( int k = 0 ; k < allReachable.GetSize() ; k ++ )
			{
				if( j != k )
				{
					if( ras.GetEdge( j , k ) )
					{
						if( ras.IsBridge( k , j ) )
						{
							int tail;
							UMLSynchActivity *utail;
							tail = allReachable.GetAt( j );
							utail = syns.GetAt( tail );
							if( utail->m_OutTransEdge.GetUpperBound()>=1)
							{
								//有平行边，不是桥
							}
							else
							{
								//没有平行边，是桥
								POINT p;
								p.x = j ;
								p.y = k;
								bridges.Add( p );
							}
						}
					}
				}
			}
		}
		//处理桥
		if( bridges.GetSize() )
		{
			//找出最近的桥
			int head ,tail;
			head = ras.GetHead();
			tail = ras.GetTail();
			head = allReachable.GetAt( head );
			tail = allReachable.GetAt( tail );
			UMLSynchActivity *uhead,*utail;
			uhead = syns.GetAt( head );
			utail = syns.GetAt( tail );
			while( bridges.GetSize() )
			{
				int sel = 0;
				for( int x = 0 ; x < bridges.GetSize(); x++ )
				{
					POINT from = bridges.GetAt( x );
					BOOL found = TRUE;
					for( int y = 0 ; y < bridges.GetSize() ; y ++ )
					{
						if( x != y )
						{
							POINT to = bridges.GetAt( y );
							if( !ras.Reachable( from.x , to .y ) )
							{
								found = FALSE;
								break;
							}
						}
					}
					if( found )
					{
						//找到了最近的桥
						sel = x;
						break;
					}
				}
				//处理最近的桥
				POINT first ;
				first = bridges.GetAt( sel );
				bridges.RemoveAt( sel );

				first.x = allReachable.GetAt( first.x );
				first.y = allReachable.GetAt( first.y );
				if( first.x == tail )
				{//首部得删除
					tail = first.y;
					utail = syns.GetAt( tail );
				}
				else
				{
					utail->m_pSynchActivityNext = syns.GetAt( first.x );
					syns.GetAt( first.x )->m_pSynchActivityLast = utail;
					tail = first.y;
					utail = syns.GetAt( tail );
				}
				//找出被删除得控制流
				for( x = 0 ; x <= m_ControlFlows.GetUpperBound() ;)
				{
					UMLSynchActivity *f ,*t;
					UMLControlFlow *cf = m_ControlFlows.GetAt( x );
					f = syns.GetAt( first.x );
					t = syns.GetAt( first.y );
					if( f == cf->m_pBegin && cf->m_pEndList.Find( t ) )
					{
						int idx = cf->m_pBegin->m_BeginControlFlow.GetFirstIdx( cf );
						cf->m_pBegin->m_BeginControlFlow.RemoveAt( idx );
						for( int s = 0  ;  s <= cf->m_pEndList.GetUpperBound() ; s ++ )
						{
							UMLSynchActivity *pUSA = cf->m_pEndList.GetAt( s );
							idx = pUSA->m_EndControlFlow.GetFirstIdx( cf );
							pUSA->m_EndControlFlow.RemoveAt( idx );
						}
						m_ControlFlows.RemoveAt( x );
						AddToLog("find a controlflow not needed ,delete it");
						break;
					}
					x++;
				}
			}
			if( tail != head )
			{
				utail->m_pSynchActivityNext = uhead;
				uhead->m_pSynchActivityLast = utail;
			}
		}
		else
		{//无桥，直接首尾相连
			int head ,tail;
			head = ras.GetHead();
			tail = ras.GetTail();
			head = allReachable.GetAt( head );
			tail = allReachable.GetAt( tail );
			UMLSynchActivity *uhead,*utail;
			uhead = syns.GetAt( head );
			utail = syns.GetAt( tail );
			utail->m_pSynchActivityNext = uhead;
			uhead->m_pSynchActivityLast = utail;
		}
	}
	for( i = 0 ; i <= m_ControlFlows.GetUpperBound() ;i ++ )
	{
		UMLControlFlow *pCF = m_ControlFlows.GetAt( i );
		pCF->GetReachableSynch();
	}
	AddToLog("Checking controlflow set finished");
}

int UMLActivityGraph::GetRouteNumberOnEnd(UMLActivity *from, UMLActivity *to)
{
	CPtrTempl<UMLTransEdge*>tn,utn;
	int num = 0;
	//找出from的所有后继边
	for( int i = 0 ; i <= from->m_OutTransEdge.GetUpperBound() ; i ++ )
	{
		UMLTransEdge *p = from->m_OutTransEdge.GetAt( i );
		utn.Add( p );
	}
	while( utn.GetUpperBound()>= 0 )
	{
		UMLTransEdge* cur = utn.GetAt( 0 );
		if( cur->m_pActivities[ 1 ] != to )
		{//目标节点不是to，将后续边加入到未遍历边中
			for( int i = 0 ; i <= cur->m_pActivities[ 1 ]->m_OutTransEdge.GetUpperBound() ; i ++ )
			{
				UMLTransEdge *e = cur->m_pActivities[ 1 ]->m_OutTransEdge.GetAt( i );
				if( !tn.Find( e ) && !utn.Find( e ) )
				{
					utn.Add( e );
				}
			}
		}
		else
		{//目标节点是to节点
			num ++;
		}
		utn.RemoveAt( 0 );
		tn.Add( cur );
	}
	return num;
}

int UMLActivityGraph::GetRouteNumberOnEnd(UMLActivity *from, UMLTransEdge *first, UMLActivity *to)
{
	CPtrTempl<UMLTransEdge*>tn,utn;
	int num = 0;
	utn.Add( first );
	while( utn.GetUpperBound()>= 0 )
	{
		UMLTransEdge* cur = utn.GetAt( 0 );
		if( cur->m_pActivities[ 1 ] != to )
		{//目标节点不是to，将后续边加入到未遍历边中
			for( int i = 0 ; i <= cur->m_pActivities[ 1 ]->m_OutTransEdge.GetUpperBound() ; i ++ )
			{
				UMLTransEdge *e = cur->m_pActivities[ 1 ]->m_OutTransEdge.GetAt( i );
				if( !tn.Find( e ) && !utn.Find( e ) )
				{
					utn.Add( e );
				}
			}
		}
		else
		{//目标节点是to节点
			num ++;
		}
		utn.RemoveAt( 0 );
		tn.Add( cur );
	}
	return num;
}

UMLModelElement::UMLModelElement(UMLModelElement &m)
{
	name = m.name;
	m_pNamespace = m.m_pNamespace;
}

void UMLControlFlow::GetReachableSynch()
{
	CPtrTempl<UMLActivity*>utn;
	CPtrTempl<UMLActivity*>tn;
	m_ReachableSynch.RemoveAll();
	for( int i = 0 ; i <= m_pEndList.GetUpperBound() ; i ++ )
	{
		utn.Add( m_pEndList.GetAt( i ));
	}
	while( utn.GetUpperBound()>=0)
	{
		UMLActivity* p = utn.GetAt( 0 );
		for( int i= 0 ; i <= p->m_OutTransEdge.GetUpperBound() ; i ++ )
		{
			UMLTransEdge *e = p->m_OutTransEdge.GetAt( i );
			if( !tn.Find(e->m_pActivities[ 1 ]) && !utn.Find( e->m_pActivities[ 1 ] ) )
			{
				if( e->m_pActivities[ 1 ] != m_pMainCFEnd )
					utn.Add( e->m_pActivities[ 1 ] );
			}
		}
		utn.RemoveAt( 0 );
		tn.Add( p );
		if( p->m_ActivityKind == ACTIVITY_SYNCH )
		{
			if( !m_ReachableSynch.Find( (UMLSynchActivity*)p ) )
			{
				m_ReachableSynch.Add( (UMLSynchActivity*)p );
			}
		}
	}
}

void UMLControlFlow::GetReachableSynch(UMLActivity *me, UMLActivityPointerList &list)
{
	CPtrTempl<UMLActivity*>utn;
	CPtrTempl<UMLActivity*>tn;
	list.RemoveAll();
	utn.Add( me );
	while( utn.GetUpperBound()>=0)
	{
		UMLActivity* p = utn.GetAt( 0 );
		for( int i= 0 ; i <= p->m_OutTransEdge.GetUpperBound() ; i ++ )
		{
			UMLTransEdge *e = p->m_OutTransEdge.GetAt( i );
			if( !tn.Find(e->m_pActivities[ 1 ]) && !utn.Find( e->m_pActivities[ 1 ] ) )
			{
				if( e->m_pActivities[ 1 ] != m_pMainCFEnd )
					utn.Add( e->m_pActivities[ 1 ] );
			}
		}
		utn.RemoveAt( 0 );
		tn.Add( p );
		if( p->m_ActivityKind == ACTIVITY_SYNCH )
		{
			if( !list.Find( (UMLSynchActivity*)p ) )
			{
				list.Add( (UMLSynchActivity*)p );
			}
		}
	}
	if( list.Find( m_pMainCFEnd) == FALSE )list.Add( m_pMainCFEnd );
}
