	protected void execute()
	{
		Thread.currentThread().setName(getClass().getSimpleName() + "@" + mNode);
		Logging.warn(this, "Main loop started");		
		mHRMTestAppRunning = true;
		try {
			Thread.sleep(10000);
		} catch (InterruptedException tExc) {
		}
		while((mHRMTestAppNeeded) & (!GLOBAL_ERROR)){
			mSource.clear();
			mDestination.clear();
			mDataRates.clear();
			int tSourceNodeNumber = 0;
			int tDestinationNodeNumber = 0;
			for(int i = 0; i < NUMBER_NODE_COMBINATIONS; i++){
				tSourceNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected source node: " + tSourceNodeNumber);
				tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected destination node: " + tDestinationNodeNumber);
				while(tSourceNodeNumber == tDestinationNodeNumber){
					tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
					Logging.warn(this, "Selected destination node: " + tDestinationNodeNumber);
				}
				mSource.add(mGlobalNodeList.get(tSourceNodeNumber));
				mDestination.add(mGlobalNodeList.get(tDestinationNodeNumber));
				mDataRates.add((int)(mRandom.nextFloat() * MAX_DATA_RATE_PER_CONNECTION));
			}
			tSourceNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
			tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
			Logging.warn(this, "Selected REF destination node: " + tDestinationNodeNumber);
			while(tSourceNodeNumber == tDestinationNodeNumber){
				tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected REF destination node: " + tDestinationNodeNumber);
			}
			mRefSource = mGlobalNodeList.get(tSourceNodeNumber);
			mRefDestination = mGlobalNodeList.get(tDestinationNodeNumber);
			Logging.warn(this, "########## Creating QoS connections now...");
			HRMController.ENFORCE_BE_ROUTING = false;
			createConnections();
			Logging.warn(this, "########## Waiting for QoS connections now...");
			try {
				Thread.sleep(2000);
			} catch (InterruptedException tExc) {
			}
			int tHRMConnectionsWithFulfilledQoS = countConnectionsWithFulfilledQoS();
			LinkedList<Double> tStoredUtilBasedOnHRM = new LinkedList<Double>();
			for(int i = 0; i < mCntBuss; i++){
				Bus tBus = mGlobalBusList.get(i);
				Logging.warn(this, tBus + " (HRM)=> " + tBus.getUtilization());
				tStoredUtilBasedOnHRM.add(tBus.getUtilization());
			}
			Logging.warn(this, "########## Destroying QoS connections now...");
			resetAllConnetions();
			if(!GLOBAL_ERROR){
				Logging.warn(this, "########## Creating BE connections now...");
				HRMController.ENFORCE_BE_ROUTING = true;
				createConnections();
				Logging.warn(this, "########## Waiting for BE connections now...");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException tExc) {
				}
				int tBEConnectionsWithFulfilledQoS = countConnectionsWithFulfilledQoS();
				LinkedList<Double> tStoredUtilBasedOnBE = new LinkedList<Double>();
				for(int i = 0; i < mCntBuss; i++){
					Bus tBus = mGlobalBusList.get(i);
					Logging.warn(this, tBus + " (BE)=> " + tBus.getUtilization());
					tStoredUtilBasedOnBE.add(tBus.getUtilization());
				}
				Logging.warn(this, "   ..HRM connections with fulfilled QoS: " + tHRMConnectionsWithFulfilledQoS);
				Logging.warn(this, "   ..BE connections with fulfilled QoS: " + tBEConnectionsWithFulfilledQoS);
				Logging.warn(this, "   ..HRM REF connections with fulfilled QoS: " + mRefHRMConnections);
				Logging.warn(this, "   ..BE REF connections with fulfilled QoS: " + mRefBEConnections);
				if(mTurn == 1){
					try {
						mStatistic = Statistic.getInstance(mLocalNodeAS.getSimulation(), HRMTestApp.class, ";", false);
					} catch (Exception tExc) {
						Logging.err(this, "Can not write statistic log file", tExc);
					}
					if(mStatistic != null){
						Runtime.getRuntime().addShutdownHook(new Thread() {
							@Override
							public void run()
							{
								Logging.getInstance().warn(this, "Closing HRMController statistics log file");
								mStatistic.close();
							}
						});
					}
					LinkedList<String> tTableHeader = new LinkedList<String>();
					tTableHeader.add("Turn");
					tTableHeader.add("Good HRM routing");
					tTableHeader.add("Good BE routing");
					tTableHeader.add("-");
					tTableHeader.add("Ref source");
					tTableHeader.add("Ref destination");
					tTableHeader.add("Good HRM Ref routing");
					tTableHeader.add("Good BE Ref routing");
					tTableHeader.add("-");
					tTableHeader.add("BusCounter");
					for(int i = 0; i < mCntBuss; i++){
						tTableHeader.add("HRM_" + mGlobalBusList.get(i).getName());
					}
					for(int i = 0; i < mCntBuss; i++){
						tTableHeader.add("BE_" + mGlobalBusList.get(i).getName());
					}
					if(mStatistic != null){
						mStatistic.log(tTableHeader);
					}
				}
				LinkedList<String> tTableRow = new LinkedList<String>();
				tTableRow.add(Integer.toString(mTurn));
				tTableRow.add(Integer.toString(tHRMConnectionsWithFulfilledQoS));
				tTableRow.add(Integer.toString(tBEConnectionsWithFulfilledQoS));
				tTableRow.add("-");
				tTableRow.add(mRefSource.toString());
				tTableRow.add(mRefDestination.toString());
				tTableRow.add(Integer.toString(mRefHRMConnections));
				tTableRow.add(Integer.toString(mRefBEConnections));
				tTableRow.add("-");
				tTableRow.add(Integer.toString(mCntBuss));
				for(int i = 0; i < mCntBuss; i++){
					DecimalFormat tFormat = new DecimalFormat("0.#");
					String tUtilizationStr = tFormat.format(tStoredUtilBasedOnHRM.get(i));
					tTableRow.add(tUtilizationStr);
				}			
				for(int i = 0; i < mCntBuss; i++){
					DecimalFormat tFormat = new DecimalFormat("0.#");
					String tUtilizationStr = tFormat.format(tStoredUtilBasedOnBE.get(i));
					tTableRow.add(tUtilizationStr);
				}
				if(mStatistic != null){
					mStatistic.log(tTableRow);
					Logging.log(this, ">>>>>>>>>> Writing statistics to file..");
					mStatistic.flush();
				}
			}
			Logging.warn(this, "########## Destroying BE connections now...");
			resetAllConnetions();
			mTurn++;
			if(mTurn >= NUMBER_MEASUREMENT_TURNS){
				Logging.warn(this, "########## END OF MEASUREMENTS #########");
				break;
			}
			if(GLOBAL_ERROR){
				Logging.err(this, "########## GLOBAL ERROR - END OF MEASUREMENTS #########");
				break;
			}
		}
		Logging.log(this, "Main loop finished");
		mHRMTestAppRunning = false;
	}

	protected void execute()
	{
		Thread.currentThread().setName(getClass().getSimpleName() + "@" + mNode);
		Logging.warn(this, "Main loop started");		
		mHRMTestAppRunning = true;
		try {
			Thread.sleep(10000);
		} catch (InterruptedException tExc) {
		}
		while((mHRMTestAppNeeded) & (!GLOBAL_ERROR)){
			mSource.clear();
			mDestination.clear();
			mDataRates.clear();
			int tSourceNodeNumber = 0;
			int tDestinationNodeNumber = 0;
			for(int i = 0; i < NUMBER_NODE_COMBINATIONS; i++){
				tSourceNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected source node: " + tSourceNodeNumber);
				tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected destination node: " + tDestinationNodeNumber);
				while(tSourceNodeNumber == tDestinationNodeNumber){
					tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
					Logging.warn(this, "Selected destination node: " + tDestinationNodeNumber);
				}
				mSource.add(mGlobalNodeList.get(tSourceNodeNumber));
				mDestination.add(mGlobalNodeList.get(tDestinationNodeNumber));
				mDataRates.add((int)(mRandom.nextFloat() * MAX_DATA_RATE_PER_CONNECTION));
			}
			tSourceNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
			tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
			Logging.warn(this, "Selected REF destination node: " + tDestinationNodeNumber);
			while(tSourceNodeNumber == tDestinationNodeNumber){
				tDestinationNodeNumber = (int)(mRandom.nextFloat() * mCntNodes);
				Logging.warn(this, "Selected REF destination node: " + tDestinationNodeNumber);
			}
			mRefSource = mGlobalNodeList.get(tSourceNodeNumber);
			mRefDestination = mGlobalNodeList.get(tDestinationNodeNumber);
			Logging.warn(this, "########## Creating QoS connections now...");
			HRMController.ENFORCE_BE_ROUTING = false;
			createConnections();
			Logging.warn(this, "########## Waiting for QoS connections now...");
			try {
				Thread.sleep(2000);
			} catch (InterruptedException tExc) {
			}
			int tHRMConnectionsWithFulfilledQoS = countConnectionsWithFulfilledQoS();
			LinkedList<Double> tStoredUtilBasedOnHRM = new LinkedList<Double>();
			for(int i = 0; i < mCntBuss; i++){
				Bus tBus = mGlobalBusList.get(i);
				Logging.warn(this, tBus + " (HRM)=> " + tBus.getUtilization());
				tStoredUtilBasedOnHRM.add(tBus.getUtilization());
			}
			Logging.warn(this, "########## Destroying QoS connections now...");
			resetAllConnetions();
			if(!GLOBAL_ERROR){
				Logging.warn(this, "########## Creating BE connections now...");
				HRMController.ENFORCE_BE_ROUTING = true;
				createConnections();
				Logging.warn(this, "########## Waiting for BE connections now...");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException tExc) {
				}
				int tBEConnectionsWithFulfilledQoS = countConnectionsWithFulfilledQoS();
				LinkedList<Double> tStoredUtilBasedOnBE = new LinkedList<Double>();
				for(int i = 0; i < mCntBuss; i++){
					Bus tBus = mGlobalBusList.get(i);
					Logging.warn(this, tBus + " (BE)=> " + tBus.getUtilization());
					tStoredUtilBasedOnBE.add(tBus.getUtilization());
				}
				Logging.warn(this, "   ..HRM connections with fulfilled QoS: " + tHRMConnectionsWithFulfilledQoS);
				Logging.warn(this, "   ..BE connections with fulfilled QoS: " + tBEConnectionsWithFulfilledQoS);
				Logging.warn(this, "   ..HRM REF connections with fulfilled QoS: " + mRefHRMConnections);
				Logging.warn(this, "   ..BE REF connections with fulfilled QoS: " + mRefBEConnections);
				if(mTurn == 1){
					try {
						mStatistic = Statistic.getInstance(mLocalNodeAS.getSimulation(), HRMTestApp.class, ";", false);
					} catch (Exception tExc) {
						Logging.err(this, "Can not write statistic log file", tExc);
					}
					if(mStatistic != null){
						Runtime.getRuntime().addShutdownHook(new Thread() {
							@Override
							public void run()
							{
								Logging.getInstance().warn(this, "Closing HRMController statistics log file");
								mStatistic.close();
							}
						});
					}
					LinkedList<String> tTableHeader = new LinkedList<String>();
					tTableHeader.add("Turn");
					tTableHeader.add("Good HRM routing");
					tTableHeader.add("Good BE routing");
					tTableHeader.add("-");
					tTableHeader.add("Ref source");
					tTableHeader.add("Ref destination");
					tTableHeader.add("Good HRM Ref routing");
					tTableHeader.add("Good BE Ref routing");
					tTableHeader.add("-");
					tTableHeader.add("BusCounter");
					for(int i = 0; i < mCntBuss; i++){
						tTableHeader.add("HRM_" + mGlobalBusList.get(i).getName());
					}
					for(int i = 0; i < mCntBuss; i++){
						tTableHeader.add("BE_" + mGlobalBusList.get(i).getName());
					}
					if(mStatistic != null){
						mStatistic.log(tTableHeader);
					}
				}
				LinkedList<String> tTableRow = new LinkedList<String>();
				tTableRow.add(Integer.toString(mTurn));
				tTableRow.add(Integer.toString(tHRMConnectionsWithFulfilledQoS));
				tTableRow.add(Integer.toString(tBEConnectionsWithFulfilledQoS));
				tTableRow.add("-");
				tTableRow.add(mRefSource.toString());
				tTableRow.add(mRefDestination.toString());
				tTableRow.add(Integer.toString(mRefHRMConnections));
				tTableRow.add(Integer.toString(mRefBEConnections));
				tTableRow.add("-");
				tTableRow.add(Integer.toString(mCntBuss));
				for(int i = 0; i < mCntBuss; i++){
					DecimalFormat tFormat = new DecimalFormat("0.#");
					String tUtilizationStr = tFormat.format(tStoredUtilBasedOnHRM.get(i));
					tTableRow.add(tUtilizationStr);
				}			
				for(int i = 0; i < mCntBuss; i++){
					DecimalFormat tFormat = new DecimalFormat("0.#");
					String tUtilizationStr = tFormat.format(tStoredUtilBasedOnBE.get(i));
					tTableRow.add(tUtilizationStr);
				}
				if(mStatistic != null){
					mStatistic.log(tTableRow);
					Logging.log(this, ">>>>>>>>>> Writing statistics to file..");
					mStatistic.flush();
				}
			}
			Logging.warn(this, "########## Destroying BE connections now...");
			resetAllConnetions();
			mTurn++;
			if(mTurn > NUMBER_MEASUREMENT_TURNS){
				Logging.warn(this, "########## END OF MEASUREMENTS #########");
				break;
			}
			if(GLOBAL_ERROR){
				Logging.err(this, "########## GLOBAL ERROR - END OF MEASUREMENTS #########");
				break;
			}
		}
		Logging.log(this, "Main loop finished");
		mHRMTestAppRunning = false;
	}
