void CRUTblEquivSetBuilder::AddRecomputeTree(CRUMV *pMV)
{
	RUASSERT(CDDObject::eRECOMPUTE == pMV->GetRefreshType());

	if (TRUE == GetDisJointAlg().HasVertex(pMV->GetUID()))
	{
		// The mv is already in the graph and his sub tree must also be there  
		// by induction 
		return;
	}
	
	GetDisJointAlg().AddVertex(pMV->GetUID());
	
	// Go over all the childs
	CRUTblList &tblList = pMV->GetTablesUsedByMe();
	DSListPosition tblPos = tblList.GetHeadPosition();
	while (NULL != tblPos)
	{
		CRUTbl *pTbl = tblList.GetNext(tblPos);
		
		if (TRUE == pTbl->IsFullySynchronized())
		{
			GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());

			AddSyncTable(pTbl);
		
			pTbl->SetLongLockIsNeeded();
			
			continue;
		}

		if (FALSE == pTbl->IsInvolvedMV())
		{
			// This is not an involved mv do not add it to the set.
			// A not involved mv does not require syncronization 
			// because it may only be changed by the refresh utility
			// and this is prevented by the ddl locks that are place on this
			// object
			continue;
		}

		// The object is an mv - if its on request we should do nothing
		// forcing lock may be skipped and all involved on request 
		// are already in the graph
		
		GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());

		CRUMV *pNextMV = pTbl->GetMVInterface();

		RUASSERT(NULL != pNextMV);

		if (CDDObject::eON_REQUEST == pNextMV->GetRefreshType() )
		{
			// All on requests mv's are already in the graph 
			continue;
		}
		
		RUASSERT(CDDObject::eRECOMPUTE == 
			     pNextMV->GetRefreshType());

		// call this function recursively for adding all sub tree 
		AddRecomputeTree(pNextMV);
	}
}