/*	Author: Magdin Stoica
	Supervisor: Dr. Ryan Leduc
	
	Project created in conformity with the requirements for the Degree of Master of Engineering in Software Engineering, 
	Computing and Software Department, 
	McMaster University
	2003 - 2007
*/
//modified
#include "DesHierProject.h"
#include "ProjectSerializer.h"
#include "ProjectIndex.h"
#include "DesSubsystem.h"
#include "DesInterface.h"
#include "DesProjectNotifications.h"
#include "InterfaceIterator.h"
#include "CommonDefinitions.h"
#include "SubsystemIterator.h"
#include "LinkedCompositeIterator.h"
#include "ProjectEventPool.h"
#include "IConsistAlgo.h"
#include "LwNonBlockingAlgo.h"
#include "LwCtrlAlgo.h"
#include "LowSubsysNonBlockAlgo.h"
#include "HighSubsysNonBlockAlgo.h"
#include "LowSubsysIConsistAlgo.h"
#include "IConsistAnsAcceptAlgo.h"
#include "LdInterfaceCheckAlgo.h"
#include "HighSubsysCtrlAlgo.h"
#include "LowSubsysCtrlAlgo.h"
//add by bini
#include "TemplateNameParser.h"
#include "Instantiation.h"
#include "InstantiateTemplate.h"

//for debug
#include <iostream>

namespace DESpot
{

DesHierProject::DesHierProject(const std::wstring& name) : 
	DesProject(name, eHierProject),
	m_iConsistProp(eIConsNotVerified),
	m_lwNonBlockProp(eLwNonBlockNotVerified),
	m_lwCtrlProp(eLwCtrlNotVerified)
{
}

//_________________________________________________________________________________________________

DesHierProject::~DesHierProject(void)
{
	try
	{
		//delete all interfaces
		for(InterfaceMapIt interfIt = m_interfMap.begin(); interfIt != m_interfMap.end(); interfIt++)
		{
			DesInterface* interf = interfIt->second;
			delete interf;
			interf = null;
		}
	}
	catch(...){}
}

//_________________________________________________________________________________________________
//The degree of the project (number of low-level subsystems)
//Cannot be set as it depends on the the actual subsystem structure
int DesHierProject::getDegree() const
{
	return m_subsysMap.size() - 1; //-1 is for the root as the root subsystem is a high-level subsystem
}

//_________________________________________________________________________________________________
bool DesHierProject::isBilevel() const
{
	InterfIteratorPtr interfIt = createInterfIterator();
	for(interfIt->first(); interfIt->notDone(); interfIt->next())
	{
		const DesInterface& crtInterf = interfIt->currentItem();
		if (!crtInterf.getSubsystem().isRoot())
		{
			return false;
		}
	}
	return true;
}
//_________________________________________________________________________________________________
//Interface consistent property
bool DesHierProject::isInterfConsist() const
{
	return m_iConsistProp == eIConsYes;
}

//_________________________________________________________________________________________________

IConsistProp DesHierProject::getIConsistProp() const
{
	return m_iConsistProp;
}

//_________________________________________________________________________________________________

void DesHierProject::setIConsistProp(int iConsProp)
{
	m_iConsistProp = IConsistProp(iConsProp);
}

//_________________________________________________________________________________________________

std::wstring DesHierProject::getIConsistStamp() const
{
	return m_iConsistStamp;
}

//_________________________________________________________________________________________________

void DesHierProject::setIConsistStamp(const std::wstring& iConsStamp)
{
	m_iConsistStamp = iConsStamp;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkIConsistProp(IConsistAlgo& iConsAlgo)
{
	iConsAlgo.runAlgo();
	
	//set the controllability property
	IConsistProp newIConsProp = iConsAlgo.isInterfaceConsistent() ? eIConsYes : eIConsNo;

	if (m_iConsistProp != newIConsProp)
	{
		m_iConsistProp = newIConsProp;
		
		//set the stamp
		m_iConsistStamp = now();

		onIConsistStatusChanged();
	}

	onIConsistStatusChecked();
	return iConsAlgo.isInterfaceConsistent();
}

//_________________________________________________________________________________________________

bool DesHierProject::checkIConsistProp(IConsistAlgo& iConsAlgo,std::map<std::wstring,bool> &subsysIConsMap,DesHierProject* mainProject)
{
	iConsAlgo.runAlgo(subsysIConsMap,mainProject);
	
	//set the controllability property
	IConsistProp newIConsProp = iConsAlgo.isInterfaceConsistent() ? eIConsYes : eIConsNo;
	if (m_iConsistProp != newIConsProp)
	{
		m_iConsistProp = newIConsProp;

	}
	return iConsAlgo.isInterfaceConsistent();
}

//_________________________________________________________________________________________________

void DesHierProject::setIConsistPropMainProj(bool isICons)
{
	//set the controllability property
	IConsistProp newIConsProp;
	if(isICons == true)	
	{
		newIConsProp = eIConsYes;
	}
	else
	{
		newIConsProp = eIConsNo;
	}

	if (m_iConsistProp != newIConsProp)
	{
		m_iConsistProp = newIConsProp;
		
		//set the stamp
		m_iConsistStamp = now();

		onIConsistStatusChanged();
	}

	onIConsistStatusChecked();
	
}
//------------overloading-------------


bool DesHierProject::checkIConsistProp(IConsistAlgo& iConsAlgo, bool multi)
{
	IConsistProp newIConsProp = iConsAlgo.isInterfaceConsistent() ? eIConsYes : eIConsNo;

	if (m_iConsistProp != newIConsProp)
	{
		m_iConsistProp = newIConsProp;
		
		//set the stamp
		m_iConsistStamp = now();

		onIConsistStatusChanged();
	}

	onIConsistStatusChecked();
	return iConsAlgo.isInterfaceConsistent();
}




//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysIConsistProp(IConsistAnsAcceptAlgo& ansAcceptAlgo)
{
	//ensure the algorithm is actually checking this project
	if (&(ansAcceptAlgo.getInputProject()) != this)
	{
		throw EX("High level interface-consistent algorithm not initialized with this project. Cannot check high-level interface consistent property");
	}

	bool beforeCheckSubsysIConsist = m_pRootSubsys->isInterfConsist();

	//run the algorithm which will set the i-consist property of the root subsystem
    ansAcceptAlgo.runAlgo();

	bool afterCheckSubsysIConsist = m_pRootSubsys->isInterfConsist();

	//let clients now of any change
	if (beforeCheckSubsysIConsist != afterCheckSubsysIConsist)
	{
		onSubsysIConsistStatusChanged(*m_pRootSubsys);	
	}

	return afterCheckSubsysIConsist;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkInterfIConsistProp(LdInterfaceCheckAlgo& interfIConsistAlgo)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesInterface* interfToCheck = interfIConsistAlgo.getInputInterface();
	InterfaceMapIt interfIt = m_interfMap.find(interfToCheck->getName());
	if (interfIt == m_interfMap.end() || interfIt->second != interfToCheck)
	{
		throw EX("Interface consistent algorithm not initialized with this project. Cannot check ld-interface property.");
	}

	bool beforeCheckInterfIConsist = interfToCheck->isInterfConsist();

	//run the algorithm which will set the i-consist property of the interface
    interfIConsistAlgo.runAlgo();

	bool afterCheckInterfIConsist = interfToCheck->isInterfConsist();

	//let clients now of any change
	if (beforeCheckInterfIConsist != afterCheckInterfIConsist)
	{
		onInterfIConsistStatusChanged(*interfToCheck);	
	}

	return afterCheckInterfIConsist;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysIConsistProp(LowSubsysIConsistAlgo& lowSubsysIConsAlgo)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesSubsystem& lowSubsysToCheck = lowSubsysIConsAlgo.getInputSubsystem();
	SubsystemMapIt subsysIt = m_subsysMap.find(lowSubsysToCheck.getName());
	if (subsysIt == m_subsysMap.end() || subsysIt->second != &lowSubsysToCheck)
	{
		throw EX("Low level interface consistent algorithm not initialized with this project. Cannot check low-level interface consistent property.");
	}

	bool beforeCheckSubsysIConsist = lowSubsysToCheck.isInterfConsist();
	//Added by zain for counter example
	lowSubsysIConsAlgo.set_proj(this);

	//run the algorithm which will set the i-consist property of the root subsystem
    lowSubsysIConsAlgo.runAlgo();

	bool afterCheckSubsysIConsist = lowSubsysToCheck.isInterfConsist();

	//let clients now of any change
	if (beforeCheckSubsysIConsist != afterCheckSubsysIConsist)
	{
		onSubsysIConsistStatusChanged(lowSubsysToCheck);	
	}

	return afterCheckSubsysIConsist;
}

void DesHierProject::setSubsysIConsistPropMainProj(const DesSubsystem& subsysMainProj,bool isSubIConst)
{

	bool beforeCheckSubsysIConsist = subsysMainProj.isInterfConsist();

	subsysMainProj.setInterfConsist(isSubIConst);
	//let clients now of any change
	if (beforeCheckSubsysIConsist != isSubIConst)
	{
		onSubsysIConsistStatusChanged(subsysMainProj);	
	}
	
}

#ifdef __ENABLE_BDD__

void DesHierProject::procBddIConsistProp(BDDHISC::Hisc_ChkInfo& checkInfo)
{
	
  //set the Iconsist property
  IConsistProp newIConsProp = checkInfo.m_chkPassed ? eIConsYes : eIConsNo;

  if (m_iConsistProp != newIConsProp)
    {
      m_iConsistProp = newIConsProp;
      
      //set the stamp
      m_iConsistStamp = now();

      onIConsistStatusChanged();
    }

  onIConsistStatusChecked();
}

void DesHierProject::procBddHighIConsistProp(BDDHISC::Hisc_ChkInfo& checkInfo)
{

  bool beforeCheckSubsysIConsist = m_pRootSubsys->isInterfConsist();

  m_pRootSubsys->setInterfConsist(checkInfo.m_chkPassed);

  bool afterCheckSubsysIConsist = checkInfo.m_chkPassed;

  //let clients know of any change
  if (beforeCheckSubsysIConsist != afterCheckSubsysIConsist)
    {
      onSubsysIConsistStatusChanged(*m_pRootSubsys);	
    }

}

void DesHierProject::procBddLowIConsistProp(BDDHISC::Hisc_ChkInfo& checkInfo,  const DesSubsystem& lowSubsysToCheck) 
{

  bool beforeCheckSubsysIConsist = lowSubsysToCheck.isInterfConsist();

  lowSubsysToCheck.setInterfConsist(checkInfo.m_chkPassed);
  
  bool afterCheckSubsysIConsist = checkInfo.m_chkPassed;

  //let clients know of any change
  if (beforeCheckSubsysIConsist != afterCheckSubsysIConsist)
    {
      onSubsysIConsistStatusChanged(lowSubsysToCheck);	
    }
}

void DesHierProject::procBddInterfProp(BDDHISC::Hisc_ChkInfo& checkInfo, const DesInterface&  interfToCheck)
{

  bool beforeCheckInterfIConsist = interfToCheck.isInterfConsist();

  interfToCheck.setInterfConsist(checkInfo.m_chkPassed);

  bool afterCheckInterfIConsist = checkInfo.m_chkPassed;

  //let clients know of any change
  if (beforeCheckInterfIConsist != afterCheckInterfIConsist)
    {
      onInterfIConsistStatusChanged(interfToCheck);	
    }
}

#endif


//_________________________________________________________________________________________________
//Level-wise non-blocking

bool DesHierProject::isLwNonBlocking() const
{
	return m_lwNonBlockProp == eLwNonBlockYes;
}

//_________________________________________________________________________________________________

LwNonBlockProp DesHierProject::getLwNonBlockProp() const
{
	return m_lwNonBlockProp;
}

//_________________________________________________________________________________________________

void DesHierProject::setLwNonBlockProp(int lwNonBlockProp)
{
	m_lwNonBlockProp = LwNonBlockProp(lwNonBlockProp);
}

//_________________________________________________________________________________________________

std::wstring DesHierProject::getLwNonBlockStamp() const
{
	return m_lwNonBlockStamp;
}

//_________________________________________________________________________________________________

void DesHierProject::setLwNonBlockStamp(const std::wstring& lwNonBlockStamp)
{
	m_lwNonBlockStamp = lwNonBlockStamp;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkLwNonBlockProp(LwNonBlockingAlgo& lwNonBlockAlgo)
{
	lwNonBlockAlgo.runAlgo();
	
	//set the nonblocking property
	LwNonBlockProp newLwNonBlockProp = lwNonBlockAlgo.isLwNonBlocking() ? eLwNonBlockYes : eLwNonBlockNo;
	
	if (m_lwNonBlockProp != newLwNonBlockProp) 
	{
		m_lwNonBlockProp = newLwNonBlockProp;

		//set the stamp
		m_lwNonBlockStamp = now();

		onLwNonBlockStatusChanged();
	}

	onLwNonBlockStatusChecked();

	return lwNonBlockAlgo.isLwNonBlocking();
}
//_________________________________________________________________________________________________

bool DesHierProject::checkLwNonBlockProp(LwNonBlockingAlgo& lwNonBlockAlgo,std::map<std::wstring, bool> &subsysNonBlockMap)
{
	lwNonBlockAlgo.runAlgo(subsysNonBlockMap);
	LwNonBlockProp newLwNonBlockProp = lwNonBlockAlgo.isLwNonBlocking() ? eLwNonBlockYes : eLwNonBlockNo;
	
	if (m_lwNonBlockProp != newLwNonBlockProp) 
	{
		m_lwNonBlockProp = newLwNonBlockProp;
	
	}

	return lwNonBlockAlgo.isLwNonBlocking();
}

//_________________________________________________________________________________________________

void DesHierProject::setLwNonBlockPropMainProj(bool isNonBlock)
{
	//set the nonblocking property
	LwNonBlockProp newLwNonBlockProp;
	if(isNonBlock)
	{
		newLwNonBlockProp = eLwNonBlockYes;
	}
	else
	{
		newLwNonBlockProp = eLwNonBlockNo;
	}
	
	if (m_lwNonBlockProp != newLwNonBlockProp) 
	{
		m_lwNonBlockProp = newLwNonBlockProp;

		//set the stamp
		m_lwNonBlockStamp = now();

		onLwNonBlockStatusChanged();
	}

	onLwNonBlockStatusChecked();

}
//-----------overloading------

bool DesHierProject::checkLwNonBlockProp(LwNonBlockingAlgo& lwNonBlockAlgo,bool multi)
{
	LwNonBlockProp newLwNonBlockProp = lwNonBlockAlgo.isLwNonBlocking() ? eLwNonBlockYes : eLwNonBlockNo;
	
	if (m_lwNonBlockProp != newLwNonBlockProp) 
	{
		m_lwNonBlockProp = newLwNonBlockProp;

		//set the stamp
		m_lwNonBlockStamp = now();

		onLwNonBlockStatusChanged();
	}

	onLwNonBlockStatusChecked();

	return lwNonBlockAlgo.isLwNonBlocking();
}




//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysNonBlockProp(HighSubsysNonBlockAlgo& hSubsysNonBlockAlgo)
{
	//ensure the algorithm is actually checking this project
	if (&(hSubsysNonBlockAlgo.getInputProject()) != this)
	{
		throw EX("High level non-blocking algorithm not initialized with this project. Cannot check high-level nonblocking.");
	}

	bool beforeCheckRootNonBlocking = m_pRootSubsys->isNonBlocking();

	//run the algorithm which will set the non-blocking property of the root subsystem
    hSubsysNonBlockAlgo.runAlgo();

	bool afterCheckRootNonBlocking = m_pRootSubsys->isNonBlocking();

	//let clients know of any change
	if (beforeCheckRootNonBlocking != afterCheckRootNonBlocking)
	{
		onSubsysLwNonBlockStatusChanged(*m_pRootSubsys);	
	}

	return afterCheckRootNonBlocking;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysNonBlockProp(LowSubsysNonBlockAlgo& lowSubsysNonBlockAlgo)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesSubsystem& lowSubsysToCheck = lowSubsysNonBlockAlgo.getInputSubsystem();
	SubsystemMapIt subsysIt = m_subsysMap.find(lowSubsysToCheck.getName());
	if (subsysIt == m_subsysMap.end() || subsysIt->second != &lowSubsysToCheck)
	{
		throw EX("Low level non-blocking algorithm not initialized with this project. Cannot check low-level nonblocking.");
	}

	bool beforeCheckSubsysNonBlocking = lowSubsysToCheck.isNonBlocking();
	// Added by zain for counter example
	lowSubsysNonBlockAlgo.set_proj(this);
	//run the algorithm which will set the non-blocking property of the root subsystem
    lowSubsysNonBlockAlgo.runAlgo();

    //    int i=0;  // why is this here? Can be deleted?

	bool afterCheckSubsysNonBlocking = lowSubsysToCheck.isNonBlocking();

	//let clients know of any change
	if (beforeCheckSubsysNonBlocking != afterCheckSubsysNonBlocking)
	{
		onSubsysLwNonBlockStatusChanged(lowSubsysToCheck);	
	}

	return afterCheckSubsysNonBlocking;
}

void DesHierProject::setSubsysNonBlockPropMainProj(const DesSubsystem& subsysChecked, bool isNonBlock)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesSubsystem& subsys=subsysChecked;
	SubsystemMapIt subsysIt = m_subsysMap.find(subsys.getName());
	if (subsysIt == m_subsysMap.end() || subsysIt->second != &subsys)
	{
		throw EX("High-level/Low-Level non-blocking algorithm not initialized with this project. Cannot check low-level/high-level nonblocking.");
	}

	bool beforeCheckSubsysNonBlocking = subsys.isNonBlocking();

	bool afterCheckSubsysNonBlocking = isNonBlock;
	subsys.setNonBlocking(isNonBlock);
	//let clients know of any change
	if (beforeCheckSubsysNonBlocking != afterCheckSubsysNonBlocking)
	{
		onSubsysLwNonBlockStatusChanged(subsys);	
	}

	
}
#ifdef __ENABLE_BDD__

void  DesHierProject::procBddLwNonBlockProp(BDDHISC::Hisc_ChkInfo& checkInfo)
{
	//set the nonblocking property
	LwNonBlockProp newLwNonBlockProp = checkInfo.m_chkPassed ? eLwNonBlockYes : eLwNonBlockNo;
	
	if (m_lwNonBlockProp != newLwNonBlockProp) 
	{
		m_lwNonBlockProp = newLwNonBlockProp;

		//set the stamp
		m_lwNonBlockStamp = now();

		onLwNonBlockStatusChanged();
	}

	onLwNonBlockStatusChecked();


}


void  DesHierProject::procBddHighNonBlockProp(BDDHISC::Hisc_ChkInfo& checkInfo)
{

  bool beforeCheckRootNonBlocking = m_pRootSubsys->isNonBlocking();

  m_pRootSubsys->setNonBlocking(checkInfo.m_chkPassed);

  bool afterCheckRootNonBlocking = checkInfo.m_chkPassed;

  //let clients know of any change
  if (beforeCheckRootNonBlocking != afterCheckRootNonBlocking)
    {
      onSubsysLwNonBlockStatusChanged(*m_pRootSubsys);	
    }
}


void  DesHierProject::procBddLowNonBlockProp(BDDHISC::Hisc_ChkInfo& checkInfo,  const DesSubsystem& lowSubsysToCheck)
{

  bool beforeCheckSubsysNonBlocking = 	lowSubsysToCheck.isNonBlocking();

  lowSubsysToCheck.setNonBlocking(checkInfo.m_chkPassed);

  bool afterCheckSubsysNonBlocking = checkInfo.m_chkPassed;

  //let clients know of any change
  if (beforeCheckSubsysNonBlocking != afterCheckSubsysNonBlocking)
    {
      onSubsysLwNonBlockStatusChanged(lowSubsysToCheck);	
    }

}

#endif

//_________________________________________________________________________________________________
//Level-wise controllable

bool DesHierProject::isLwControllable() const
{
	return m_lwCtrlProp == eLwCtrlYes;
}

//_________________________________________________________________________________________________

LwCtrlProp DesHierProject::getLwCtrlProp() const
{
	return m_lwCtrlProp;
}

//_________________________________________________________________________________________________

void DesHierProject::setLwCtrlProp(int lwCtrlProp)
{
	m_lwCtrlProp = LwCtrlProp(lwCtrlProp);
}

//_________________________________________________________________________________________________

std::wstring DesHierProject::getLwCtrlStamp() const
{
	return m_lwCtrlStamp;
}

//_________________________________________________________________________________________________

void DesHierProject::setLwCtrlStamp(const std::wstring& lwCtrlStamp)
{
	m_lwCtrlStamp = lwCtrlStamp;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkLwCtrlProp(LwCtrlAlgo& lwCtrlAlgo)
{
	lwCtrlAlgo.runAlgo();
	
	//set the controllability property
	LwCtrlProp newLwCtrlProp = lwCtrlAlgo.isLwControllable() ? eLwCtrlYes : eLwCtrlNo;
	
	if (m_lwCtrlProp != newLwCtrlProp)
	{
		m_lwCtrlProp = newLwCtrlProp;

		//set the stamp
		m_lwCtrlStamp = now();

		onLwCtrlStatusChanged();
	}
    
	onLwCtrlStatusChecked();
	
	return lwCtrlAlgo.isLwControllable();
}
//_________________________________________________________________________________________________

bool DesHierProject::checkLwCtrlProp(LwCtrlAlgo& lwCtrlAlgo,std::map<std::wstring, bool> &subsysCtrlMap)
{
	lwCtrlAlgo.runAlgo(subsysCtrlMap);
	
	//set the controllability property
	LwCtrlProp newLwCtrlProp = lwCtrlAlgo.isLwControllable() ? eLwCtrlYes : eLwCtrlNo;
	
	if (m_lwCtrlProp != newLwCtrlProp)
	{
		m_lwCtrlProp = newLwCtrlProp;

	}
    
	return lwCtrlAlgo.isLwControllable();
	
}
//____________________________________________________________________________________________
void DesHierProject::setLwCtrlPropMainProj(bool isCtrl)
{
	LwCtrlProp newLwCtrlProp;

	if(isCtrl)
	newLwCtrlProp =  eLwCtrlYes;
	else
	newLwCtrlProp = eLwCtrlNo;
	
	if (m_lwCtrlProp != newLwCtrlProp)
	{
		m_lwCtrlProp = newLwCtrlProp;

		//set the stamp
		m_lwCtrlStamp = now();

		onLwCtrlStatusChanged();
	}
    
	onLwCtrlStatusChecked();
	
}
//--------overloading
bool DesHierProject::checkLwCtrlProp(LwCtrlAlgo& lwCtrlAlgo, bool multi)
{
		LwCtrlProp newLwCtrlProp = lwCtrlAlgo.isLwControllable() ? eLwCtrlYes : eLwCtrlNo;
	
	if (m_lwCtrlProp != newLwCtrlProp)
	{
		m_lwCtrlProp = newLwCtrlProp;

		//set the stamp
		m_lwCtrlStamp = now();

		onLwCtrlStatusChanged();
	}
    
	onLwCtrlStatusChecked();
	
	return lwCtrlAlgo.isLwControllable();
}




//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysLwCtrlProp(HighSubsysCtrlAlgo& hSubsysLwCtrlAlgo)
{
	//ensure the algorithm is actually checking this project
	if (&(hSubsysLwCtrlAlgo.getInputProject()) != this)
	{
		throw EX("High level controllable algorithm not initialized with this project. Cannot check high-level controllability.");
	}

	bool beforeCheckRootCtrl = m_pRootSubsys->isControllable();

	//run the algorithm which will set the controllable property of the root subsystem
    hSubsysLwCtrlAlgo.runAlgo();

	bool afterCheckRootCtrl = m_pRootSubsys->isControllable();

	//let clients now of any change
	if (beforeCheckRootCtrl != afterCheckRootCtrl)
	{
		onSubsysLwCtrlStatusChanged(*m_pRootSubsys);	
	}

	return afterCheckRootCtrl;
}

//_________________________________________________________________________________________________

bool DesHierProject::checkSubsysLwCtrlProp(LowSubsysCtrlAlgo& lowSubsysLwCtrlAlgo)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesSubsystem& lowSubsysToCheck = lowSubsysLwCtrlAlgo.getInputSubsystem();
	SubsystemMapIt subsysIt = m_subsysMap.find(lowSubsysToCheck.getName());
	if (subsysIt == m_subsysMap.end() || subsysIt->second != &lowSubsysToCheck)
	{
		throw EX("Low level controllable algorithm not initialized with this project. Cannot check low-level controllable property.");
	}

	bool beforeCheckSubsysCtrl = lowSubsysToCheck.isControllable();
	// added by zain for counter example
	lowSubsysLwCtrlAlgo.set_proj(this);
	//run the algorithm which will set the i-consist property of the root subsystem
    lowSubsysLwCtrlAlgo.runAlgo();

	bool afterCheckSubsysCtrl = lowSubsysToCheck.isControllable();

	//let clients now of any change
	if (beforeCheckSubsysCtrl != afterCheckSubsysCtrl)
	{
		onSubsysLwCtrlStatusChanged(lowSubsysToCheck);	
	}

	return afterCheckSubsysCtrl;
}
//_________________________________________________________________________________________________

void DesHierProject::setSubsysCtrlPropMainProj(const DesSubsystem& subsysChecked, bool isSubContrl)
{
	//ensure the algorithm is actually checking a subsystem belonging to this project
	const DesSubsystem& subsys = subsysChecked;
	SubsystemMapIt subsysIt = m_subsysMap.find(subsys.getName());
	if (subsysIt == m_subsysMap.end() || subsysIt->second != &subsys)
	{
		throw EX("High-level/Low-level controllable algorithm not initialized with this project. Cannot check high-level/low-level controllable property.");
	}

	bool beforeCheckSubsysCtrl = subsys.isControllable();

	bool afterCheckSubsysCtrl = isSubContrl;
	subsys.setControllable(isSubContrl);
	//let clients now of any change
	if (beforeCheckSubsysCtrl != afterCheckSubsysCtrl)
	{
		onSubsysLwCtrlStatusChanged(subsys);	
	}

	
}

#ifdef __ENABLE_BDD__

void DesHierProject::procBddLwCtrlProp(BDDHISC::Hisc_ChkInfo& checkInfo) 
{
	
  //set the controllability property
  LwCtrlProp newLwCtrlProp = checkInfo.m_chkPassed ? eLwCtrlYes : eLwCtrlNo;
	
  if (m_lwCtrlProp != newLwCtrlProp)
    {
      m_lwCtrlProp = newLwCtrlProp;

      //set the stamp
      m_lwCtrlStamp = now();

      onLwCtrlStatusChanged();
    }
    
  onLwCtrlStatusChecked();

}


void DesHierProject::procBddHighCtrlProp(BDDHISC::Hisc_ChkInfo& checkInfo)
{

  bool beforeCheckRootCtrl = m_pRootSubsys->isControllable();

  m_pRootSubsys->setControllable(checkInfo.m_chkPassed);

  bool afterCheckRootCtrl = checkInfo.m_chkPassed;

  //let clients now of any change
  if (beforeCheckRootCtrl != afterCheckRootCtrl)
    {
      onSubsysLwCtrlStatusChanged(*m_pRootSubsys);	
    }
}


void DesHierProject::procBddLowCtrlProp(BDDHISC::Hisc_ChkInfo& checkInfo,  const DesSubsystem& lowSubsysToCheck)
{

  bool beforeCheckSubsysCtrl = lowSubsysToCheck.isControllable();

  lowSubsysToCheck.setControllable(checkInfo.m_chkPassed);

  bool afterCheckSubsysCtrl = checkInfo.m_chkPassed;

  //let clients now of any change
  if (beforeCheckSubsysCtrl != afterCheckSubsysCtrl)
    {
      onSubsysLwCtrlStatusChanged(lowSubsysToCheck);	
    }

}

#endif



//_________________________________________________________________________________________________
//Resets all properties and all incremental data calculated for them
//so that they can be rechecked from scratch
void DesHierProject::clean(bool deepClean)
{

	//reset the hierarchical properties
	m_iConsistProp = eIConsNotVerified;
	m_iConsistStamp = L"";
	onIConsistStatusChanged();

	m_lwNonBlockProp = eLwNonBlockNotVerified;
	m_lwNonBlockStamp = L"";
	onLwNonBlockStatusChanged();

	m_lwCtrlProp = eLwCtrlNotVerified;
	m_lwCtrlStamp = L"";
	onLwCtrlStatusChanged();
	

	if (deepClean)
	{


		//invalidate all interfaces
		for(InterfaceMapIt interfIt = m_interfMap.begin(); interfIt != m_interfMap.end(); interfIt++)
		{
			DesInterface* crtInterf = interfIt->second;
			crtInterf->clean();
		}

		//invalidate all subsystems
		for(SubsystemMapIt subsysIt = m_subsysMap.begin(); subsysIt != m_subsysMap.end(); subsysIt++)
		{
			DesSubsystem* crtSubsys = subsysIt->second;
			
			//clean all the low-level subsystems. The root subsystem was already cleaned by 
			//the call to DesProject::resetProperties
			if (crtSubsys->isRoot() == false)
			{
				crtSubsys->clean();
			}
		}
	}


	DesProject::clean(deepClean);


}

//_________________________________________________________________________________________________

const DesSubsystem& DesHierProject::addHighLevelSubsys(const std::wstring& name)
{
	DesSubsystem* rootSubsys = new DesSubsystem(name, *m_eventPool);

	try
	{
		addHighLevelSubsys(rootSubsys);

		//notify all listeners
		onHighLevelSubsysAdded(*m_pRootSubsys);
	}
	catch(...)
	{
		delete rootSubsys;
		throw; //re-throw the error;
	}

	return *m_pRootSubsys;
}

//_________________________________________________________________________________________________

const DesInterface& DesHierProject::addInterface(const std::wstring& name)
{
	DesInterface* pInterf = new DesInterface(name, *m_eventPool);
	
	try
	{
		addInterface(pInterf);

		//notify all listeners
		onInterfaceAdded(*pInterf);
	}
	catch(...)
	{
		delete pInterf;
		throw;
	}

	return *pInterf;
}

//_________________________________________________________________________________________________
//Added by Parul to map the interface to the subsystem 
const DesInterface& DesHierProject::addInterface(const std::wstring& name,const std::wstring& subsysName)
{

	SubsystemMapCIt subsysIt = m_subsysMap.find(subsysName);
	if (subsysIt == m_subsysMap.end())
	{
		throw EX("Cannot find subsystem with given name.")
	}
	DesSubsystem* pSubsys = subsysIt->second;
	DesInterface* pInterf = new DesInterface(name, pSubsys, *m_eventPool);
	
	try
	{
		addInterface(pInterf);

		//notify all listeners
		onInterfaceAdded(*pInterf);
	}
	catch(...)
	{
		delete pInterf;
		throw;
	}

	return *pInterf;

	
}

//_________________________________________________________________________________________________

const DesSubsystem& DesHierProject::addLowLevelSubsys(const std::wstring& name, const std::wstring& interfName)
{

	//find the interface with the given name and add a dependency on the root subsystem
	InterfaceMapCIt interfIt = m_interfMap.find(interfName);
	if (interfIt == m_interfMap.end())
	{
		throw EX("Cannot find interface with given name. Cannot add low-level subsystem")
	}
	DesInterface* pInterf = interfIt->second;


	DesSubsystem* lSubsys = new DesSubsystem(name, pInterf, *m_eventPool);
	addLowLevelSubsys(lSubsys);


	// set parentSubsys  to parent subsystem of interface
	DesSubsystem& parentSubsys= const_cast<DesSubsystem &>(pInterf->getSubsystem());


	//m_pRootSubsys->addDependency(pInterf, lSubsys);
	parentSubsys.addDependency(pInterf, lSubsys);


	//notify all listeners
	onLowLevelSubsysAdded(*lSubsys);

	onDependencyAdded(parentSubsys, *m_interfMap[interfName], *lSubsys);


	return *lSubsys;
}

//_________________________________________________________________________________________________

void DesHierProject::renameSubsystem(const std::wstring& name, const std::wstring& newName)
{
	//find the subsystem
	SubsystemMapIt subsysIt = m_subsysMap.find(name);
	if (subsysIt == m_subsysMap.end())
	{
		throw EX("Cannot find a subsystem with the given name. Cannot rename subsystem")
	}

	if (m_nameIndex.findName(newName))
	{
		throw EX("The new name is already used in the project. Cannot rename subsystem")
	}
	
	DesSubsystem* pSubsys = subsysIt->second;
	pSubsys->setName(newName);

	//Re-map the subsystem and reindex it now that its name was changed
	m_subsysMap.erase(subsysIt);
	m_subsysMap[newName] = pSubsys;
	m_nameIndex.reIndex(name, *pSubsys);

	//notify all clients
	onSubsysRenamed(*pSubsys);
}

//_________________________________________________________________________________________________

void DesHierProject::renameSubsystem(const DesSubsystem& subsys, const std::wstring& newName)
{
	//Make sure the given subsystem is actually part of this project
	const DesSubsystem* pFoundSubsys = null;
	m_nameIndex.findSubsystem(subsys.getName(), pFoundSubsys);
	if (pFoundSubsys != &subsys)
	{
		throw EX("Given subsystem is not part of this project")
	}
	
	renameSubsystem(subsys.getName(), newName);
}

//_________________________________________________________________________________________________

void DesHierProject::renameInterface(const std::wstring& name, const std::wstring& newName)
{
	InterfaceMapIt interfIt = m_interfMap.find(name);
	if (interfIt == m_interfMap.end())
	{
		throw EX("Cannot find an interface with the given name. Cannot rename interface")
	}

	if (m_nameIndex.findName(newName))
	{
		throw EX("The new name is already used in the project. Cannot rename interface.")
	}
	
	DesInterface* pFoundInterf = interfIt->second;

	//rename the interface
	pFoundInterf->setName(newName);

	//update the interface map and the index
	m_interfMap.erase(interfIt);
	m_interfMap[newName] = pFoundInterf;
	m_nameIndex.reIndex(name, *pFoundInterf);

	//notify all clients
	onInterfRenamed(*pFoundInterf);
}

//_________________________________________________________________________________________________

void DesHierProject::renameInterface(const DesInterface& interf, const std::wstring& newName)
{
	//Make sure the given interface is part of this project
	const DesInterface* pFoundInterf = null;
	m_nameIndex.findInterface(interf.getName(), pFoundInterf);
	if (pFoundInterf != &interf)
	{
		throw EX("The given interface is not part of this project. Cannot rename interface")
	}

	renameInterface(interf.getName(), newName);
}

//_________________________________________________________________________________________________

void DesHierProject::deleteSubsystem(const std::wstring& name)
{
	//find the subsystem to delete
	SubsystemMapIt subsysIt = m_subsysMap.find(name);
	if (subsysIt == m_subsysMap.end())
	{
		throw EX("Cannot find a subsystem with the given name. Cannot delete subsystem")
	}

	DesSubsystem* pSubsys = subsysIt->second;
	
	//throw exception if the root subsystem is being deleted
	if (pSubsys->isRoot())
	{
		throw EX("Deleteing of root subsystem is not allowed")
	}
	bool notLeaf = false;
	for(InterfaceMapIt interfIt = m_interfMap.begin(); interfIt != m_interfMap.end(); interfIt++)
		{
			DesInterface* crtInterf = interfIt->second;
			if(&(crtInterf->getSubsystem()) == pSubsys)
			{
				notLeaf=true;
				break;
			}
	}
	if(notLeaf)
	{
		//delete all the dependent subsystems and interfaces
		std::vector<std::wstring> subsysList;
		
		DesSubsystem::DependIteratorPtr depIt = pSubsys->createDependsIterator();
		for(depIt->first(); depIt->notDone(); depIt->next())
		{
				const DesSubsystem::Dependency& depend = depIt->currentItem();
					subsysList.push_back(depend.subsystem->getName());
				
			}
		
		for(unsigned int iSubsys = 0; iSubsys < subsysList.size(); iSubsys++)
		{
			deleteSubsystem(subsysList[iSubsys]);
		}

		std::vector<std::wstring> interfList;
		for(InterfaceMapIt interfIt = m_interfMap.begin(); interfIt != m_interfMap.end(); interfIt++)
		{
			DesInterface* crtInterf = interfIt->second;
			if(&(crtInterf->getSubsystem()) == pSubsys)
			interfList.push_back(crtInterf->getName());
		}
		for(unsigned int iInterf = 0; iInterf < interfList.size(); iInterf++)
		{
			deleteInterface(interfList[iInterf]);
		}
		if(!pSubsys->isRoot())
		{
		const DesSubsystem& parent = pSubsys->getInterface().getSubsystem();
		DesSubsystem& pSubsysNC= const_cast<DesSubsystem &>(parent);
		pSubsysNC.deleteDependency(pSubsys);
	}
	}
	else
	{
		//this is a low-level subsystem. Remove the dependency of the root on this low-level subsystem
		//before deleting
		//m_pRootSubsys->deleteDependency(pSubsys);
		const DesSubsystem& parent = pSubsys->getInterface().getSubsystem();
		DesSubsystem& pSubsysNC= const_cast<DesSubsystem &>(parent);
		pSubsysNC.deleteDependency(pSubsys);
	}

	//delete all the subsystem's DES
	DesSubsystem::DesIteratorPtr desIt = pSubsys->createDesIterator();
	for(desIt->first(); desIt->notDone(); desIt->next())
	{
		const Des& des = desIt->currentItem();
		deleteDes(des.getName(), *pSubsys);
	}
	//erase from the map and index
	m_subsysMap.erase(subsysIt);
	m_nameIndex.erase(name);

	//notify all clients that we are about to delete the subsystem
	
	onDeletingSubsys(*pSubsys);

	delete pSubsys;
	pSubsys = null;

	//notify that we have deleted the subsystem
	onSubsysDeleted(name);

	}

//_________________________________________________________________________________________________

void DesHierProject::deleteInterface(const std::wstring& name)
{
	//find the interface to delete
	InterfaceMapIt interfIt = m_interfMap.find(name);
	if (interfIt == m_interfMap.end())
	{
		throw EX("Cannot find an interface with the given name. Cannot delete interface")
	}

	DesInterface* pInterf = interfIt->second;
	const DesSubsystem& parent=pInterf->getSubsystem();
	DesSubsystem& pSubsysNC= const_cast<DesSubsystem &>(parent);

	//before deleting the interface, delete the dependency that uses it
	DesSubsystem* dependSubsys = null;
	//if (m_pRootSubsys->getDependent(pInterf, dependSubsys))
	if (pSubsysNC.getDependent(pInterf, dependSubsys))
	{
		//a low-level subsystem is dependent on this subsystem so delete it
		deleteSubsystem(dependSubsys->getName());
		dependSubsys = null;
	}
	//m_pRootSubsys->deleteDependency(pInterf);
	pSubsysNC.deleteDependency(pInterf);
	//delete all the interface's DES
	DesInterface::DesIteratorPtr desIt = pInterf->createDesIterator();
	for(desIt->first(); desIt->notDone(); desIt->next())
	{
		const Des& des = desIt->currentItem();
		deleteDes(des.getName(), *pInterf);
	}

	//erase from map and index
	m_interfMap.erase(interfIt);
	m_nameIndex.erase(name);

	//notify all clients that we are about to delete the interface
	onDeletingInterf(*pInterf);

	delete pInterf;
	pInterf = null;

	//notify all clients that we have deleted the interface
	onInterfDeleted(name);
}

//_________________________________________________________________________________________________

const DesInterface& DesHierProject::getInterface(const std::wstring& name) const
{
	return *m_interfMap.find(name)->second;
}

//_________________________________________________________________________________________________

DesHierProject::InterfIteratorPtr DesHierProject::createInterfIterator() const
{
	const InterfIterator* pInterfIt = new InterfaceIterator(m_interfMap);
	return InterfIteratorPtr(pInterfIt);
}

//_________________________________________________________________________________________________

const DesSubsystem& DesHierProject::getSubsystem(const std::wstring& name) const
{
	//added by zain for counder example
	if(!(m_subsysMap.find(name)==m_subsysMap.end()))
	{
		return *m_subsysMap.find(name)->second;
	}
	else
	{

	  // this is not returning anything if an error.  I think this
	  // should be an exception instead
		QString Terr ="Fatal Error: The error subsystem \"%1\" could not be found. Please inform DESpot developers.";
		QString SubsysNameErr=Terr.arg(QString::fromStdWString(name));
		//QMessageBox::critical(NULL, "DESpot",SubsysNameErr);

		throw (SubsysNameErr.toStdWString());

	}
}

//_________________________________________________________________________________________________
/*DesSubsystem* DesHierProject::getSubsystem(std::wstring& name) const
{return m_subsysMap.find(name)->second;
}
*/

DesHierProject::SubsysIteratorPtr DesHierProject::createSubsysIterator() const
{
	const SubsysIterator* pSubsysIt = new DESpot::SubsystemIterator(m_subsysMap);
	return SubsysIteratorPtr(pSubsysIt);
}

//_________________________________________________________________________________________________

void DesHierProject::addDes(Des* pDes, const std::wstring& container, 
								  DesLevel desLevel /*= eSupervisorDes*/)
{
	//Find the container
	ProjectIndex::TypedComp  comp;
	if (m_nameIndex.findName(container, &comp) == false)
	{
		throw EX("Cannot find a container with the given name. The component could not be added.")
	}

	switch(comp.first)
	{
		case ProjectIndex::eSubsystemComp:
		{
			DesSubsystem* subsys = m_subsysMap[container];
			addDes(pDes, *subsys, desLevel);
			break;
		}

		case ProjectIndex::eInterfaceComp:
		{
			DesInterface* interf = m_interfMap[container];
            if(pDes->getType()==eSubsystemDes)
            {
                   throw EX("Invalid DES type.")
            }
			addDes(pDes, *interf,desLevel);
			break;
		}

		default:
			throw EX("Invalid container. The component cannot be addded")
	}
}

//_________________________________________________________________________________________________

void DesHierProject::addDes(Des* pDes, const DesSubsystem& subsys, DesLevel desLevel)
{
	//Find the subsystem to make sure it is in this project
	ProjectIndex::TypedComp comp;
	if (m_nameIndex.findName(subsys.getName(), &comp) == false)
	{
		throw EX("Cannot find a container with the given name. The component could not be added.")
	}

	if (comp.second != &subsys)
	{
		throw EX("The given subsystem is not part of this project. The component could not be added.")
	}
//add by bini
	//make sure plant/supervisor does not contain %%
	std::wstring name = pDes->getName();
	TemplateNameParser* NameParser=new TemplateNameParser(name);
	if(desLevel!=eTemplateDes&&m_nameValidator.validate(name)==false)
	{
		throw EX("This supervisor/plant name contains '%'.  Only template names can contain '%'.  Cannot add DES.")
	}	
	//make sure name is a valid template name
	if(desLevel==eTemplateDes&&(NameParser->isTemplateName()==false))
	{
		throw EX("This is not a valid template name. Cannot add DES.")
	}
	//make sure the name is not already used
	if(desLevel==eTemplateDes&&subsys.findDes(name)==true)
	{
		throw EX("This name is already in use. Cannot add template DES.")
	}
	if (desLevel!=eTemplateDes&&m_nameIndex.findName(pDes->getName()))
	{
		throw EX("This name is already in use. Cannot add DES.")
	}


	DesSubsystem* inSubsys = m_subsysMap[subsys.getName()];
	pDes->setParentSystemName(subsys.getName());
	inSubsys->addDes(pDes, desLevel);

	//index the name
	if(desLevel==eTemplateDes&&m_nameIndex.findName(name))
	{
	}
	else
	{
	m_nameIndex.addComp(*pDes);
	}


	onDesAdded(*pDes, desLevel, subsys);
}

//_________________________________________________________________________________________________

void DesHierProject::addDes(Des* pDes, const DesInterface& interf, DesLevel desLevel)
{
	//Find the subsystem to make sure it is in this project
    pDes->setLevel(desLevel);
	ProjectIndex::TypedComp comp;
	std::wstring name = pDes->getName();
	if (m_nameIndex.findName(interf.getName(), &comp) == false)
	{
		throw EX("Cannot find a container with the given name. The component could not be added.")
	}

	if (comp.second != &interf)
	{
		throw EX("The given interface is not part of this project. The component could not be added.")
	}
//add by bini
	TemplateNameParser* NameParser=new TemplateNameParser(name);
	if(desLevel!=eTemplateDes&&m_nameValidator.validate(name)==false)
	{
		throw EX("This supervisor name contains '%'. Only template names can contain '%'. Cannot add DES.")
	}	
    if(desLevel==eTemplateDes&&NameParser->isTemplateName()==false)
    {
        throw EX("This is not a valid template name. Cannot add DES.")
    }
	//make sure interface does not contain %%
	if(m_nameValidator.validate(interf.getName())==false)
	{
		throw EX("This name is not an interface name. Cannot add DES.")
	}	
	//make sure the name is not already used
	if(desLevel==eTemplateDes&&interf.findDes(name)==true)
	{
		throw EX("This name is already in use. Cannot add DES.")
	}
	if (desLevel!=eTemplateDes&&m_nameIndex.findName(pDes->getName()))
	{
		throw EX("This name is already in use. Cannot add DES.")
	}


	DesInterface* inInterf = m_interfMap[interf.getName()];
	pDes->setParentSystemName(interf.getName());
	inInterf->addDes(pDes,desLevel);

	//index the name
	if(desLevel==eTemplateDes&&m_nameIndex.findName(name))
	{
	}
	else
	{
	m_nameIndex.addComp(*pDes);
	}

	onDesAdded(*pDes, desLevel,interf);
}
//_________________________________________________________________________________________________
//add by bini
//add an instantiation
bool DesHierProject::addInstantiation(Instantiation* pInstantiation,Des* template_crt)
{

	ProjectIndex::TypedComp comp;
	Instantiation* inst = null;
	if(template_crt->getType()==eSubsystemDes)
	{
   		DesSubsystem* inSubsys = m_subsysMap[getParentSubsystem(*template_crt).getName()];
		if(inSubsys->findInst(pInstantiation->getName(),&inst))
		{	
			InstantiateTemplate::InstantiatedTemplate* result=new 			InstantiateTemplate::InstantiatedTemplate;
			if(pInstantiation->getInputType()==eRange)
			{
				result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(pInstantiation->getParameter()));
			}
			else
			{
				result=InstantiateTemplate::generateTemplateParameterFromTuple(*(pInstantiation->getParameter()));
			}
			InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
			while(result->end()!=it)
			{	
				TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;					
				TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
				while (iterator != (&*it)->end())
            			{
      					parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
          				iterator++;
            			 }
				 std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(template_crt->getName(),*(parameter)));
				 deleteDes(name,*inSubsys);
			         it++;
			}
			QMessageBox::information(NULL, 	"DESpot","Error: This name is already in use. Cannot add Instantiation.");
			return false;
		}
		else
		{	
			inSubsys->addInstantiation(pInstantiation);
		}
	}
	else if (template_crt->getType()==eInterfaceTemplateDes)
	{
		DesInterface* interf = m_interfMap[getParentInterface(*template_crt).getName()];
		if(interf->findInst(pInstantiation->getName(),&inst))
		{	
			InstantiateTemplate::InstantiatedTemplate* result=new 			InstantiateTemplate::InstantiatedTemplate;
			if(pInstantiation->getInputType()==eRange)
			{
				result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(pInstantiation->getParameter()));
			}
			else
			{
				result=InstantiateTemplate::generateTemplateParameterFromTuple(*(pInstantiation->getParameter()));
			}
			InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
			while(result->end()!=it)
			{	
				TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;					
				TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
				while (iterator != (&*it)->end())
            			{
      					parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
          				iterator++;
            			 }
				 std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(template_crt->getName(),*(parameter)));
				 deleteDes(name,*interf);
			         it++;
			}
			QMessageBox::information(NULL, "DESpot","Error: This name is already in use. Cannot add Instantiation.");
                        return false;
		}
		else
		{	
			interf->addInstantiation(pInstantiation);
		}
		
	}
	//index the name
		//if(m_nameIndex.findName(pInstantiation->getName()))
		//{
		//}
		//else
		//{
			m_nameIndex.addComp(*pInstantiation);
		//}
	
		onInstAdded(*pInstantiation,*template_crt);

		return true;
	
}
//_________________________________________________________________________________________________
//add by bini
//removes a inst from the interface and destroys it
void DesHierProject::deleteInstantiation(const std::wstring& instName,DesInterface& parentInterf)
{
	
	InterfaceMapIt interfIt = m_interfMap.find(parentInterf.getName());
	
	if (interfIt == m_interfMap.end())
	{
		throw EX("Cannot find the given interface. Cannot delete Instantiation.");
	}
		
	DesInterface* interf = interfIt->second;
	Instantiation* foundinst = null;
	if (interf->findInst(instName, &foundinst))
	{
		onRemovingInstantiation(*foundinst,parentInterf);
		interf->deleteInstantiation(instName);
		m_nameIndex.erase(instName);
		onInstantiationRemoved(instName,parentInterf);
	}
}
//_________________________________________________________________________________________________
//add by bini
//removes a inst from the subsystem and destroys it
void DesHierProject::deleteInstantiation(const std::wstring& instName,DesSubsystem& parentSubsys)
{
	
	SubsystemMapIt subsysIt = m_subsysMap.find(parentSubsys.getName());
	
	if (subsysIt == m_subsysMap.end())
	{
		throw EX("Cannot find the given subsystem. Cannot delete Instantiation.");
	}
		
	DesSubsystem* subsys = subsysIt->second;
	Instantiation* foundinst = null;
	if (subsys->findInst(instName, &foundinst))
	{
		onRemovingInstantiation(*foundinst,parentSubsys);
		subsys->deleteInstantiation(instName);
		m_nameIndex.erase(instName);
		onInstantiationRemoved(instName,parentSubsys);
	}
}

//_________________________________________________________________________________________________

void DesHierProject::changeDesName(Des& des, const std::wstring& newDesName)
{
	//make sure the name is not already used
	if (m_nameIndex.findName(newDesName))
	{
		throw EX("This name is already in use. Cannot change the name of DES.")
	}
	TemplateNameParser* NameParser2=new TemplateNameParser(newDesName);
	if (NameParser2->isTemplateName()==true)
	{
		throw EX("This name is not a Template DES name");
	}
	//find the owner of this DES and ask it to change the name and update itself
	std::wstring oldName = des.getName();
	switch(des.getType())
	{
		case eSubsystemDes:
		{
			DesSubsystem* subsys = const_cast<DesSubsystem*>(des.getSubsystemOwner());
			subsys->changeDesName(des, newDesName);
			break;
		}

		case eInterfaceDes:
		{
			DesInterface* interf = const_cast<DesInterface*>(des.getInterfaceOwner());			
			interf->changeDesName(des, newDesName);
			break;
		}

		case eInterfaceTemplateDes:
		{
			DesInterface* interf = const_cast<DesInterface*>(des.getInterfaceOwner());			
			interf->changeDesName(des, newDesName);
			break;
		}

		default:
			throw EX("The given des has incorrect type. It has to be subsystem or interface DES. Cannot change the name of DES.");
	}

	//reindex the DES
	m_nameIndex.reIndex(oldName, des);

	onDesNameChanged(des, oldName);
}

//_________________________________________________________________________________________________
//modified by bini
void DesHierProject::deleteDes(const std::wstring& desName)
{
	//go through all interfaces and find DES
	for(InterfaceMapIt interfIt = m_interfMap.begin(); interfIt != m_interfMap.end(); interfIt++)
	{
		DesInterface& crtInterf = *interfIt->second;
		Des* foundDes = null;
		DesLevel desLevel;
		if (crtInterf.findDes(desName, &foundDes,&desLevel))
		{
			if(foundDes->isInstantiated())
			{
				DesProject::InstIteratorPtr InstIt = crtInterf.createInstIterator();
				for(InstIt->first();InstIt->notDone();InstIt->next())
				{
                    Instantiation in=InstIt->currentItem();
					if(InstIt->currentItem().getTemplateDes()==foundDes)
					{
                        InstantiateTemplate::InstantiatedTemplate* result=new InstantiateTemplate::InstantiatedTemplate;

						if(InstIt->currentItem().getInputType()==eRange)
						{
							result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(InstIt->currentItem().getParameter()));
						}
						else
						{
							result=InstantiateTemplate::generateTemplateParameterFromTuple(*(InstIt->currentItem().getParameter()));
						}
						InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
				
						while(result->end()!=it)
						{	
							TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;
					
							TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
							while (iterator != (&*it)->end())
            					 	{
               	 						parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
                						iterator++;
            						 }
							const Instantiation inst=InstIt->currentItem();
					
							std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(desName,*(parameter)));
							deleteInstantiation(inst.getName(),crtInterf);
							deleteDes(name);
							it++;
						}
					}
				}
			}
				onRemovingDes(*foundDes, crtInterf);
			
				crtInterf.deleteDes(desName);

				//remove DES name from index
				m_nameIndex.erase(desName);

				onDesRemoved(desName, crtInterf);

				return;
		}
	}

	//go through all subsystem and find DES
	for(SubsystemMapIt subsysIt = m_subsysMap.begin(); subsysIt != m_subsysMap.end(); subsysIt++)
	{
		DesSubsystem& crtSubsys = *subsysIt->second;
		DesLevel desLevel;
		Des* foundDes = null;
		if (crtSubsys.findDes(desName, &foundDes, &desLevel))
		{
			
			if(foundDes->isInstantiated())
			{
				DesProject::InstIteratorPtr InstIt = m_pRootSubsys->createInstIterator();
				for(InstIt->first();InstIt->notDone();InstIt->next())
				{
					if(InstIt->currentItem().getTemplateDes()==foundDes)
					{
						const Instantiation inst=InstIt->currentItem();
						InstantiateTemplate::InstantiatedTemplate* result=new 			InstantiateTemplate::InstantiatedTemplate;
						if(InstIt->currentItem().getInputType()==eRange)
						{
							result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(InstIt->currentItem().getParameter()));
						}
						else
						{
							result=InstantiateTemplate::generateTemplateParameterFromTuple(*(InstIt->currentItem().getParameter()));
						}
						InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
				
						while(result->end()!=it)
						{	
							TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;
					
							TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
							while (iterator != (&*it)->end())
            					 	{
               	 						parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
                						iterator++;
            						 }
							
					
							std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(desName,*(parameter)));
							deleteInstantiation(inst.getName(),crtSubsys);
							deleteDes(name);
							it++;
						}
					}
				}
			}
			onRemovingDes(*foundDes, desLevel, crtSubsys);

			crtSubsys.deleteDes(desName);

			//remove DES name from index
			m_nameIndex.erase(desName);

			onDesRemoved(desName, desLevel, crtSubsys);
			
			return;
		}
	}
}

//_________________________________________________________________________________________________
//modified by bini
void DesHierProject::deleteDes(const std::wstring& desName, const DesSubsystem& parentSubsys)
{
	SubsystemMapIt subsysIt = m_subsysMap.find(parentSubsys.getName());
	
	if (subsysIt == m_subsysMap.end())
	{
		throw EX("Cannot find the given subsystem. Cannot delete DES.");
	}
	
	DesSubsystem* subsys = subsysIt->second;
	DesLevel desLevel;
	Des* foundDes = null;
	if (subsys->findDes(desName, &foundDes, &desLevel))
	{
		
			if(foundDes->isInstantiated())
			{
                DesProject::InstIteratorPtr InstIt = subsys->createInstIterator();
				for(InstIt->first();InstIt->notDone();InstIt->next())
				{
					if(InstIt->currentItem().getTemplateDes()==foundDes)
					{
						InstantiateTemplate::InstantiatedTemplate* result=new 			InstantiateTemplate::InstantiatedTemplate;
						if(InstIt->currentItem().getInputType()==eRange)
						{
							result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(InstIt->currentItem().getParameter()));
						}
						else
						{
							result=InstantiateTemplate::generateTemplateParameterFromTuple(*(InstIt->currentItem().getParameter()));
						}
						InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
				
						while(result->end()!=it)
						{	
							TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;
					
							TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
							while (iterator != (&*it)->end())
            					 	{
               	 						parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
                						iterator++;
            						 }
                            const Instantiation *inst = new Instantiation();
                            inst=&(InstIt->currentItem());
					
							std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(desName,*(parameter)));
                            deleteInstantiation(inst->getName(),*subsys);
							deleteDes(name);
							it++;
						}
					}
				}
			}
		onRemovingDes(*foundDes, desLevel, *subsys);

		subsys->deleteDes(desName);

		//remove DES name from index
		m_nameIndex.erase(desName);

		onDesRemoved(desName, desLevel, *subsys);
	}
}

//_________________________________________________________________________________________________
//modified by bini
void DesHierProject::deleteDes(const std::wstring& desName, const DesInterface& parentInterf)
{
	InterfaceMapIt interfIt = m_interfMap.find(parentInterf.getName());
	
	if (interfIt == m_interfMap.end())
	{
		throw EX("Cannot find the given interface. Cannot delete DES.");
	}
		
	DesInterface* interf = interfIt->second;
	Des* foundDes = null;
	DesLevel desLevel;
	if (interf->findDes(desName, &foundDes,&desLevel))
	{
		
		if(foundDes->isInstantiated())
		{
			DesProject::InstIteratorPtr InstIt = parentInterf.createInstIterator();
			for(InstIt->first();InstIt->notDone();InstIt->next())
			{
				if(InstIt->currentItem().getTemplateDes()==foundDes)	
				{
					InstantiateTemplate::InstantiatedTemplate* result=new 			InstantiateTemplate::InstantiatedTemplate;
					if(InstIt->currentItem().getInputType()==eRange)
						{
							result=InstantiateTemplate::generateTemplateParameterFromTemplate(*(InstIt->currentItem().getParameter()));
						}
						else
						{
							result=InstantiateTemplate::generateTemplateParameterFromTuple(*(InstIt->currentItem().getParameter()));
						}
					InstantiateTemplate::InstantiatedTemplateItr it=result->begin();
				
					while(result->end()!=it)
					{	
						TemplateNameParser::TemplateParameter* parameter=new TemplateNameParser::TemplateParameter;
					
						TemplateNameParser::TemplateParameterItr iterator=(&*it)->begin();
						while (iterator != (&*it)->end())
         					{
               	 					parameter->insert(TemplateNameParser::TemplateParameter::value_type(iterator->first,iterator->second));
                					iterator++;
            					 }
                        const Instantiation *inst = new Instantiation();
                        inst=&(InstIt->currentItem());
				
						std::wstring name =*(InstantiateTemplate::getNameFromInstantiatedTemplate(desName,*(parameter)));
                        deleteInstantiation(inst->getName(),*interf);
						deleteDes(name);
						it++;
					}
				}
			}
		}
		onRemovingDes(*foundDes, *interf);
		
		interf->deleteDes(desName);

		//remove DES name from index
		m_nameIndex.erase(desName);

		onDesRemoved(desName, *interf);
	}
}

//_________________________________________________________________________________________________

const DesInterface& DesHierProject::getParentInterface(const Des& des)
{
	if ((des.getType() != eInterfaceDes)&&(des.getType() != eInterfaceTemplateDes))
	{
		throw EX("The given des is not an interface DES. Cannot return interface");
	}

	DesInterface* crtInterf_temp=m_interfMap[des.getParentSystemName()];
	const DesInterface& crtInterf=*(const_cast<DesInterface*>(crtInterf_temp));
	return crtInterf;

	throw EX("Cannot find an interface containing the given DES");
}

//_________________________________________________________________________________________________

const DesSubsystem& DesHierProject::getParentSubsystem(const Des& des)
{
	if (des.getType() != eSubsystemDes)
	{
		throw EX("The given des is not a subsystem DES. Cannot return subsystem");
	}

	DesSubsystem* crtSubsys_temp=m_subsysMap[des.getParentSystemName()];
	const DesSubsystem& crtSubsys=*(const_cast<DesSubsystem*>(crtSubsys_temp));
	return crtSubsys;
	

	throw EX("Cannot find a subystem containing the given DES");
}

//_________________________________________________________________________________________________

//Create an iterator that goes through all the internal Des in the project
DesProject::DesIteratorPtr DesHierProject::createDesIterator() const
{
	//start with the DES in the root subsystems
	DesIterator* desIt = const_cast<DesIterator*>(DesProject::createDesIterator().release());

	//go through all interfaces and find DES
	InterfIteratorPtr interfIt = createInterfIterator();
	for(interfIt->first(); interfIt->notDone(); interfIt->next())
	{
		const DesInterface& crtInterf = interfIt->currentItem();
		DesIterator* crtDesIt = const_cast<DesIterator*>(crtInterf.createDesIterator().release());
		desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
	}

	//Go through all subsystems and interfaces of the project and
	//link their DES iterator into one common iterator
	SubsysIteratorPtr subsysIt = createSubsysIterator();
	for(subsysIt->first(); subsysIt->notDone(); subsysIt->next())
	{						  
		const DesSubsystem& crtSubsys = subsysIt->currentItem();
		if (crtSubsys.isRoot() == false)
		{
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtSubsys.createDesIterator().release());		
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}
	
	return DesIteratorPtr(desIt);
}

//_________________________________________________________________________________________________

//Create an iterator that goes through all the internal Des in the project
DesProject::DesIteratorPtr DesHierProject::createDesIterator()
{
	//start with the DES in the root subsystems
	DesIterator* desIt = const_cast<DesIterator*>(DesProject::createDesIterator().release());

	//go through all interfaces and find DES
	InterfIteratorPtr interfIt = createInterfIterator();
	for(interfIt->first(); interfIt->notDone(); interfIt->next())
	{
		const DesInterface& crtInterf = interfIt->currentItem();
		DesIterator* crtDesIt = const_cast<DesIterator*>(crtInterf.createDesIterator().release());
		desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
	}

	//Go through all subsystems and interfaces of the project and
	//link their DES iterator into one common iterator
	SubsysIteratorPtr subsysIt = createSubsysIterator();
	for(subsysIt->first(); subsysIt->notDone(); subsysIt->next())
	{						  
		const DesSubsystem& crtSubsys = subsysIt->currentItem();
		if (crtSubsys.isRoot() == false)
		{
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtSubsys.createDesIterator().release());		
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}
	
	return DesIteratorPtr(desIt);
}

//_________________________________________________________________________________________________

//Create an iterator that goes through either the plant or the supervisor Des
DesProject::DesIteratorPtr DesHierProject::createDesIterator(DesLevel desLevel) const
{
	//start with the DES in the root subsystems
	DesIterator* desIt = const_cast<DesIterator*>(DesProject::createDesIterator(desLevel).release());

	if (desLevel != ePlantDes)
	{
		//go through all interfaces and find DES
		InterfIteratorPtr interfIt = createInterfIterator();
		for(interfIt->first(); interfIt->notDone(); interfIt->next())
		{
			const DesInterface& crtInterf = interfIt->currentItem();
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtInterf.createDesIterator(desLevel).release());
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}
	


	//Go through all subsystems and interfaces of the project and
	//link their DES iterator into one common iterator
	SubsysIteratorPtr subsysIt = createSubsysIterator();
	for(subsysIt->first(); subsysIt->notDone(); subsysIt->next())
	{						  
		const DesSubsystem& crtSubsys = subsysIt->currentItem();
		
		if (crtSubsys.isRoot() == false)
		{
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtSubsys.createDesIterator(desLevel).release());		
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}
	
	return DesIteratorPtr(desIt);
}

//_________________________________________________________________________________________________

//Create an iterator that goes through either the plant or the supervisor Des
DesProject::DesIteratorPtr DesHierProject::createDesIterator(DesLevel desLevel) 
{
	//start with the DES in the root subsystems
	DesIterator* desIt = const_cast<DesIterator*>(DesProject::createDesIterator(desLevel).release());

	if (desLevel != ePlantDes)
	{
		//go through all interfaces and find DES
		InterfIteratorPtr interfIt = createInterfIterator();
		for(interfIt->first(); interfIt->notDone(); interfIt->next())
		{
			const DesInterface& crtInterf = interfIt->currentItem();
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtInterf.createDesIterator(desLevel).release());
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}

	//Go through all subsystems and interfaces of the project and
	//link their DES iterator into one common iterator
	SubsysIteratorPtr subsysIt = createSubsysIterator();
	for(subsysIt->first(); subsysIt->notDone(); subsysIt->next())
	{						  
		const DesSubsystem& crtSubsys = subsysIt->currentItem();
		
		if (crtSubsys.isRoot() == false)
		{
			DesIterator* crtDesIt = const_cast<DesIterator*>(crtSubsys.createDesIterator(desLevel).release());		
			desIt = new LinkedCompositeIterator<Des&, const Des&>(desIt, crtDesIt);
		}
	}
	
	return DesIteratorPtr(desIt);
}

//_________________________________________________________________________________________________

void DesHierProject::addHighLevelSubsys(DesSubsystem* subsys)
{
	if (m_pRootSubsys != null)
	{
		throw EX("The high-level subsystem has already been created. Only one high-level subsystem is permitted")
	}

	if (m_nameIndex.findName(subsys->getName()))
	{
		//this case is abnormal as nothing can be added before adding a high-level subsystem
		throw EX("This name is already in use. Cannot add high-level subsystem.")
	}

	m_pRootSubsys = subsys;
	m_subsysMap[subsys->getName()] = m_pRootSubsys;

	//index the name
	m_nameIndex.addComp(*m_pRootSubsys);
}

//_________________________________________________________________________________________________

void DesHierProject::addInterface(DesInterface* interf)
{
	//make sure the name is not already used
	if (m_nameIndex.findName(interf->getName()))
	{
		throw EX("This name is already in use. Cannot add interface.")
	}
	
	m_interfMap[interf->getName()] = interf;

	//index the name
	m_nameIndex.addComp(*interf);

}
/*
void DesHierProject::addInterface(const DesInterface* interf)
{
	//make sure the name is not already used
	if (m_nameIndex.findName(interf->getName()))
	{
		throw EX("This name is already in use. Cannot add interface.")
	}
	
	m_interfMap[interf->getName()] = interf;

	//index the name
	m_nameIndex.addComp(*interf);

}
*/
//_________________________________________________________________________________________________

void DesHierProject::addLowLevelSubsys(DesSubsystem* lSubsys)
{
	//make sure the name is not already used
	if (m_nameIndex.findName(lSubsys->getName()))
	{
		throw EX("This name is already in use. Cannot add low-level subsystem.")
	}

	m_subsysMap[lSubsys->getName()] = lSubsys;

	//index the name
	m_nameIndex.addComp(*lSubsys);
}

//_________________________________________________________________________________________________

DesSubsystem* DesHierProject::getSubsystem(const std::wstring& name)
{
	SubsystemMapIt subsysIt = m_subsysMap.find(name);
	//for(SubsystemMapIt it = m_subsysMap.begin(); it!=m_subsysMap.end(); it++)
	//{
	//	std::wstring subsysName = it->first;
	//	DesSubsystem* subsys = it->second;
	//}
	DesSubsystem* subsys = subsysIt->second;
	return subsys;
}

//_________________________________________________________________________________________________

int DesHierProject::getInterfaceCount() const
{
	return m_interfMap.size();
}

//_________________________________________________________________________________________________

DesInterface* DesHierProject::getInterface(const std::wstring& name)
{
	return m_interfMap.find(name)->second;
}

//_________________________________________________________________________________________________

int DesHierProject::getSubsystemCount() const
{
	return m_subsysMap.size();
}

//_________________________________________________________________________________________________

void DesHierProject::onIConsistStatusChanged()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onIConsistStatusChanged();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onIConsistStatusChecked()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onIConsistStatusChecked();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onInterfIConsistStatusChanged(const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onInterfIConsistStatusChanged(interf);
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onSubsysIConsistStatusChanged(const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onSubsysIConsistStatusChanged(subsys);
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onLwCtrlStatusChanged()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onLwCtrlStatusChanged();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onLwCtrlStatusChecked()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onLwCtrlStatusChecked();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onSubsysLwCtrlStatusChanged(const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onSubsysLwCtrlStatusChanged(subsys);
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onLwNonBlockStatusChanged()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onLwNonBlockStatusChanged();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onLwNonBlockStatusChecked()
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onLwNonBlockStatusChecked();
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onSubsysLwNonBlockStatusChanged(const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		try
		{
			DesProjectNotifications* pListner = m_projListeners[iListner];
			if (pListner != null)
			{
				//This listener implements the HISC project notifications so send it to it
				pListner->onSubsysLwNonBlockStatusChanged(subsys);
			}
		}
		catch(...){} //not interested in exceptions thrown by listners
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onHighLevelSubsysAdded(const DesSubsystem& highLevelSubsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onHighLevelSubsysAdded(highLevelSubsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onInterfaceAdded(const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onInterfaceAdded(interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onLowLevelSubsysAdded(const DesSubsystem& lowLevelSubsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{

		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];


				if (pListner != null)
				{
					//This listener implements the	HISC project notifications so send it to it

					pListner->onLowLevelSubsysAdded(lowLevelSubsys);

				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}


}

//_________________________________________________________________________________________________

void DesHierProject::onDependencyAdded(const DesSubsystem& subsys, 
										   const DesInterface& interf, 
										   const DesSubsystem& dependent)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();

        clean(false);


	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{

		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it

					pListner->onDependencyAdded(subsys, interf, dependent);

				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}


}

//_________________________________________________________________________________________________

void DesHierProject::onSubsysRenamed(const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onSubsysRenamed(subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onInterfRenamed(const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onInterfRenamed(interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDeletingSubsys(const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDeletingSubsys(subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onSubsysDeleted(const std::wstring& subsysName)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onSubsysDeleted(subsysName);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDeletingInterf(const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDeletingInterf(interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onInterfDeleted(const std::wstring& interfName)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onInterfDeleted(interfName);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDesAdded(const Des& des, DesLevel desLevel, const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDesAdded(des, desLevel, subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDesAdded(const Des& des, DesLevel desLevel, const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

    for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
    {
        if (m_projListeners[iListner] != null)
        {
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDesAdded(des,desLevel, interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
        }
    }
}
//_________________________________________________________________________________________________
//add by bini
void DesHierProject::onInstAdded(Instantiation& addedInst, Des& template_crt)
{
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);
	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner)
				{
					pListner->onInstAdded2(addedInst,template_crt);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}

}

//_________________________________________________________________________________________________

void DesHierProject::onRemovingDes(const Des& des, DesLevel desLevel, const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onRemovingDes(des, desLevel, subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onRemovingDes(const Des& des, const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onRemovingDes(des, interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDesRemoved(const std::wstring& desName, DesLevel desLevel, const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDesRemoved(desName, desLevel, subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::onDesRemoved(const std::wstring& desName, const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onDesRemoved(desName, interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}
//_________________________________________________________________________________________________
//add by bini
void DesHierProject::onRemovingInstantiation(const Instantiation& inst, const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onRemovingInstantiation(inst, subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________
//add by bini
void DesHierProject::onRemovingInstantiation(const Instantiation& inst, const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onRemovingInstantiation(inst, interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________
//add by bini
void DesHierProject::onInstantiationRemoved(const std::wstring& instName, const DesSubsystem& subsys)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onInstantiationRemoved(instName, subsys);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________
//add by bini
void DesHierProject::onInstantiationRemoved(const std::wstring& instName, const DesInterface& interf)
{
	//Notifications are not sent while the project is being loaded. This important because in
	//some cases project properties are being reset when a change is done to the project which
	//is not the case while the project is being loaded
	if (m_bLoadInProgress) 
		return;

	setModified();
	clean(false);

	for(unsigned int iListner = 0; iListner < m_projListeners.size(); iListner++)
	{
		if (m_projListeners[iListner] != null)
		{
			try
			{
				DesProjectNotifications* pListner = m_projListeners[iListner];
				if (pListner != null)
				{
					//This listener implements the HISC project notifications so send it to it
					pListner->onInstantiationRemoved(instName, interf);
				}
			}
			catch(...){} //not interested in exceptions thrown by listners
		}
	}
}

//_________________________________________________________________________________________________

void DesHierProject::setFlags(resultStruct rs)
{
	if (rs.NBChecked)
	{
		m_lwNonBlockProp = (LwNonBlockProp)rs.nonBlocking;
		m_lwNonBlockStamp = now();
	}

	if (rs.ctrlChecked)
	{
		m_lwCtrlProp = (LwCtrlProp)rs.controllable;
		m_lwCtrlStamp = now();
	}

	if (rs.iConsistChecked)
	{
		m_iConsistProp = (IConsistProp)rs.iConsistent;	
		m_iConsistStamp = now();
	}
}
//_________________________________________________________________________________________________
//add by bini
void DesHierProject::instantiatetemplate(const std::wstring& templateName,Instantiation* inst,DesSubsystem* sub)
{
	TemplateNameParser::TemplateParameter* parameter=inst->getParameter();
	DesLevel level=inst->getLevel();	
	Des* templatedes=null;
	DesLevel desLevel;
	if (sub->findDes(templateName,&templatedes,&desLevel))
	{
		if (templatedes->isTemplate()==false)
		{
                        setSuccessful(false);
			throw EX("This cannot be instantiated");
		}
		if(inst->getInputType()==eRange)
		{
		InstantiateTemplate::DesArray* manydes=InstantiateTemplate::generateDesFromTemplate(templatedes,InstantiateTemplate::generateTemplateParameterFromTemplate(*parameter));
		InstantiateTemplate::DesArrayItr itr=manydes->begin();
		while (itr != manydes->end())
       		{
           		if (m_nameIndex.findName((*itr)->getName()))
            		{
		          setSuccessful(false);
              		  throw EX("One of the DES names is already in use.  Can not add instantiation.");
           		}
           		 itr++;
        	}
		itr=manydes->begin();
		while(itr!=manydes->end())
		{
			addDes(*itr,*sub,level);
			itr++;
		}
		setSuccessful(true);
		templatedes->setInstantiated(true);
		}
		else
		{
		InstantiateTemplate::DesArray* manydes=InstantiateTemplate::generateDesFromTemplate(templatedes,InstantiateTemplate::generateTemplateParameterFromTuple(*parameter));
		
		InstantiateTemplate::DesArrayItr itr=manydes->begin();
		while (itr != manydes->end())
       		{
           		if (m_nameIndex.findName((*itr)->getName()))
            		{
			   setSuccessful(false);
              		  throw EX("One of the DES names is already in use.  Can not add instantiation.");
           		}
           		 itr++;
        	}
		itr=manydes->begin();
		while(itr!=manydes->end())
		{
			addDes(*itr,*sub,level);
			itr++;
		}
		setSuccessful(true);
		templatedes->setInstantiated(true);
		}

		
	}
}
//_________________________________________________________________________________________________
//add by bini
void DesHierProject::instantiatetemplate(const std::wstring& templateName,Instantiation* inst,DesInterface* interf)
{
	TemplateNameParser::TemplateParameter* parameter=inst->getParameter();
	DesLevel level=inst->getLevel();	
	Des* templatedes=null;
	DesLevel desLevel;
	if (interf->findDes(templateName,&templatedes,&desLevel))
	{
		if (templatedes->isTemplate()==false)
		{
			QMessageBox::information(NULL, "DESpot","Error: This cannot be instantiated");
                        setSuccessful(false);
			return;
		}
		
		if(inst->getInputType()==eRange)
		{
			InstantiateTemplate::DesArray* manydes=InstantiateTemplate::generateDesFromTemplate(templatedes,InstantiateTemplate::generateTemplateParameterFromTemplate(*parameter));
			InstantiateTemplate::DesArrayItr itr=manydes->begin();
		while (itr != manydes->end())
       		{
           		if (m_nameIndex.findName((*itr)->getName()))
            		{
				setSuccessful(false);
              			QMessageBox::information(NULL, "DESpot","Error: One of the DES names is already in use.  Can not add instantiation.");
				return;
           		}
           		 itr++;
        	}
		itr=manydes->begin();
		while(itr!=manydes->end())
		{
			addDes(*itr,*interf,level);
			itr++;
		}
		templatedes->setInstantiated(true);
		setSuccessful(true);
		}
		else
		{
			InstantiateTemplate::DesArray* manydes=InstantiateTemplate::generateDesFromTemplate(templatedes,InstantiateTemplate::generateTemplateParameterFromTuple(*parameter));
			
		
		InstantiateTemplate::DesArrayItr itr=manydes->begin();
		while (itr != manydes->end())
       		{
           		if (m_nameIndex.findName((*itr)->getName()))
            		{
				setSuccessful(false);
              		 	QMessageBox::information(NULL, "DESpot","Error: One of the DES names is already in use.  Can not add instantiation.");
				return;
           		}
           		 itr++;
        	}
		itr=manydes->begin();
		while(itr!=manydes->end())
		{
			addDes(*itr,*interf,level);
			itr++;
		}
		templatedes->setInstantiated(true);
		setSuccessful(true);
		}

		
	}
}




}; //end of namespace DESpot
