package Test::AutomationFramework; 
use 5.012003;
use strict;
use warnings;
use Date::Manip;
use File::Path;
#use Test::More;
use Getopt::Long;
use File::Copy;
use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);
use File::Find;
use Regexp::Assemble;
use Cwd;
use IO::Socket;			# might not work in http mode
use Term::ReadKey;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
$| = 1;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
help
processTCs
processTC
processProperty
genDriver_taf_pl
genDriver_taf_cgi
initTAF
);


our $VERSION = '0.058.51';   	

###################### TAF Global Variables ###############################
	my %tsProperty			; my %tafProperty	; my %tafPropertyRev; my $propertyOp='';	my $regression=0; my $help=0; my $sleep4Display = 1; my $notUsegetTCName= 0; my %recordTags=();
	my $tcIdCtr=0			; my $tsDriver = "null" ;	 				# cmd-line-overwrite $testDriverName (generated by -e .. index.pl or index.ps1)
 	my $pr2Screen = 1		; my $tcIdMin= 0	; my $reportHtmlSummaryStr = ''; 	# String for mouse-over display TC summary
	my $Execution_24_7	= "n";
	my $Execution_24_7_title= "y";
	my $Execution_local_only= "n";
	my $Execution_from_cgi  = "n";
	my $NofExecution	= "1"; my $NofExecutionCtr=0;
	my $ExecutionLength	= "10000 hour";
	my $ExecutionType 	= '>'; 
	my @tcDesc;		 my $tsFilter=".*";
	my $exitTAFTCId		;
	my $tcComment1		="Comment1";
	my $tcComment2		="PlaceHolderforComment2";
	my $MaxTCExecTime 	= 10	; 
	my $NofPropertyExecCtr	= 0	;
	my $NofPropertyExec     = 0	;
	my $tags		="_full_,_smoke_,_smoketest_,_regression_,_regressiontest_,_bat_,_32bit_,_64bit_,_list_,_load_,_erase_";
	my $TSHookIsPerl	= "n";
	my $http_port		= ":8080";
	my $outputFormat	= "text"; 	# noOutput
	my $htmlRefreshRate     = 5;
	my $htmlRefreshRateWebUI= 5;
	my $htmlRefreshRateLogUI= 200;
	my $createOrAppendTS    = "create"; 	#"append";	# create
	my $outputPause 	= 0;
	my $titleStatus		= "";
	my $perl = $^X;  $perl =~ s/\\/\\\//g;	 # todo3 \\ linux
	my $perl_ = $^X; $perl_=~ s/\\/\//g;	 # todo3 \\

###################### TAF Generated Variables ###############################
	my $scriptName 			= $0; $scriptName =~ s/\\/\//g;  # linux
	my $workingDir			= getcwd(); 
	my $TSHookName 			= "index.pl";
	my $TSHookNameGenerated 	= "index.pl";

###################### TAF Default Variables ###############################
	my $overWriteTC			= "y";
	my $interact 			= "n";
	my $tcPropertyPatternName 	= "tcRunResult";
	my $tcPropertyPatternPattern 	= ".*"; 
	my $tcPropertyPatternName1 	= "tcRunResult";
	my $tcPropertyPatternPattern1 	= ".*"; 
	my $tcPropertyPatternName2 	= "tcRunResult";
	my $tcPropertyPatternPattern2 	= ".*"; 
	my $tcPropertyPatternName3 	= "tcRunResult";
	my $tcPropertyPatternPattern3	= ".*"; 
	my $tcPropertyName 		= "all";
	my $tcPropertyPattern		= Regexp::Assemble->new; 
	my $tcNamePattern		= "TC*"; 		
	my $tcOp			= 'list';	
	my $tcCtr  			= 0;
	my $tcDelta			= 20;	
	my $markSymbol			= '|';
	my $c				= "c:";
	my $taf				= "taf.pl";
	my $tafCGI			= "taf.cgi";
	my $SUTSymbol			= "_";
	my $tsFilterDefault 		= "_";
	my $tcFilterDefault 		= ".*";
	my $_TAF			= "_TAF";		# very useful variable 
	my $SvrDrive 			= $c.'/'.$_TAF; 	# *:will be reset later in generated variable section
	my $SvrProjName 		= '_testsuite1_'; 
	my $SvrTCName 			= '_testcase1_';
	my $SvrTCNamePattern 		= "*"; 
	my $SvrPropNamePattern 		= '.*';
	my $SvrPropValuePattern 	= ".*";

	my $SvrTCNameExecPattern 	= ".".$SvrTCNamePattern;  	# * 
	my $SvrLogDir 			= ''.$SvrProjName.''; 		# * 
	my $ps1_args 			= "-ps1_args___powershell_args";  	# should not include -ps1_args 
	my $exitTAFGracefullyLock   	= $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt"; # *
	my $exitTAFGracefullyString	= 1;
 	my $performanceMode		= "slow4webUI"; 			# fast4cmd
	my $generateTestsuiteBAT	= $c.'/'.$_TAF."/taf_generateTestsuite.bat"; 	# *
	my $tsFrom			="";
	my $tsTo   			="";
	my $resetTSFileName		="";
	my $externalLogName		="$c/$_TAF/externalLog.txt";		# *
	my $commandLogName		="$c/$_TAF/_cmdLogs.txt";		# *
	my $commandLogLifeSpan		= "-3 days";
###################### TAF WebUI Default Settings ###############################

	my $excelReportColumnWidth 	= 9; 
	my $AutomationtsName		="Automation_MVSDK";
 	my $makeMark			= 'n'; my $makeMarkComment		= '';
 	my $makeMarkLastDay		= &getExecDay();
	my $web_ui_title		="Test Automation Framework"; 
	my $webUI_TCDescWidth 		= 120; 					# <<<<<<<<<<<<<<
	my $scrollAmount		= 0; 
	my $borderWidth			= 0; 
	my $borderStyle			= "SOLID"; 
	my $passFailDisplayWidth	= 8;					# TS Variable. Should be reset for each TS execution 
	my $maxPassFailDisplayWidth	= 40; 
	my $reportHtmlSummaryScale 	= 3600; 				# in seconds
	my $reportHtmlSummaryScaleMajor = 12; 					# in seconds
	my $tsProperty    		= 'tsProperty.txt';
	my $tsPropertyWidth		= 150;					# <<<<<<<<<<<<<<<<<
	my $testcaseNode		= "testcase"	; 			
	my $testType    		= "ts";					# ts for testsuite
	my $reportHtml  		= 'index.htm';
	my $reportHtml1 		= '_tcReport_.html';
	my $reportHtmlHistory		= '_tcReportHistory_.html';
	my $reportHtmlSummary   	= '_tcReportSummary_.html';
	my $tc_pl			= "tc.pl";

	my $reportHtml_http  		= 'index_http.htm'; 			# $reportHtml."_http";
	my $reportHtml1_http 		= '_tcReport_.html'."_http";
	my $reportHtmlHistory_http	= '_tcReportHistory_.html'."_http";

	my $web_ui_title_tip 		= "Run TAF-Team Version based on IIS/httpd";
	my $hostname 			= "localhost";
	my $ip 				= "127.0.0.1";

	my $rst 			= `ping -n 1 $hostname`; 
 	if    ($rst =~ /Ping request could not/i) { $web_ui_title_tip = "Click to update every TAF testsuites";}
 	elsif ($rst  =~ /unknown/i)                { $web_ui_title_tip = "Click to update every TAF testsuites";}
 	else {
 		$hostname 		= `hostname`; chop $hostname; 
 		$ip			= inet_ntoa((gethostbyname($hostname))[4]);
 	}
		
	my $url 			= 'file:///'.$SvrDrive;  		# will be updated in the sub-processTCs
	my $urlHttp			= 'http://'.$ip.$http_port;		# will be updated in the sub-processTCs
	my $indexTitleRefresh   = sprintf("<a href=\"${url}/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDiive=$c;_TAF=$_TAF;generateTestsuiteAgain')\" title=\"Refresh *all* TAF Testsuites\" >Framework</a>");
	my $indexTitleRefreshCGI= sprintf("<a href=\"${urlHttp}/$tafCGI?tafArgs=SysDrive=${SvrDrive}_semi_generateTestsuiteAgain;tafRedirectory=${urlHttp}/$reportHtml_http\" title=\"Refresh *all* TAF Testsuites\">Framework</a>");
	
	if (-e "$c/$_TAF/_tafGlobalVars.txt") { &readTAFGlobalVars(); } else { &printTAFGlobalVars();}  # Global Variables 

	######### Generated Variables 
	$SvrDrive 			= $c.'/'.$_TAF; 
	$exitTAFGracefullyLock   	= $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt";
	$SvrTCNameExecPattern 	= ".".$SvrTCNamePattern;  				# * 
	$SvrLogDir 			= ''.$SvrProjName.''; 				# * 
	$generateTestsuiteBAT	= $c.'/'.$_TAF."/taf_generateTestsuite.bat"; 		# *
	$externalLogName		="$c/$_TAF/externalLog.txt";			# *
	$commandLogName		="$c/$_TAF/_cmdLogs.txt";				# *

sub new { my $package = shift; return bless({}, $package); }

sub tcLoop {			###### Testsuite Loop #####
	my $returnValue;
	if (-e "$c/$_TAF/$SvrProjName/_tafGlobalVars.txt") { &readTAFTSVars();} # TS Global Variables will overwrite TAF Global Variables
	while ((($Execution_24_7 eq 'y') || ($NofExecution > $NofExecutionCtr)) && ($NofPropertyExec >= $NofPropertyExecCtr )) {
		&markDaily();
		$NofExecutionCtr++;
		my $tcOp_ = $tcOp; if ($tcOp_ =~ /list/) {$tcOp_ = "list & update";}
		if ($pr2Screen == 1) { if (($NofExecution == 1) && ($Execution_24_7 ne 'y')){ print "Processing           $c/$_TAF/$SvrProjName     ($tcOp_)          <- Testsuite \n" if ($outputFormat =~ /text/i) ; } else {print "Processing ($NofExecutionCtr\/$NofExecution) ......\n" ; } } else { print "";}

		if (($propertyOp =~ /^\s*$/) || ($propertyOp =~ /tcDescAuto/i)) {&tcPre(); &tcMain_(); &tcPost(); 
		} else { 
			#&xtcMain_(); if ($NofPropertyExec =~ /y/i) { $propertyExecCtrEqZero = "y"; $propertyOp = ""; } else {$NofPropertyExecCtr++;}
			&tcMain_();  $NofPropertyExecCtr++;
		} # TC Property Process
		#### uncomment for debugging if ($pr2Screen==1) { if ($propertyOp) { print " -> $SvrDrive/$SvrProjName/_${propertyOp}.txt\n"; }	print " - Completed -\n"; } else { print "";} 
	}
	return $returnValue;
}
sub tcPre {
	# if (-e $SvrDrive.'/'.$SvrProjName) {;} else { print "$SvrDrive/$SvrProjName doesn't exist.\n"; exit; }	# Fix 2013/04/13 
	##################### PrePRocessor #####################
	if ($tcOp =~ /create/i) {
		if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1,"<html><body>")	}; 
		if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http,"<html><body>--- _tcReport_.htm will be available after list/update operation ---</body></html>")	}; 
		if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary,"<html><body>--- summary file will be available after list/update operation ---</body></html>")	}; 
		if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body>--- history file will be available after list/update operation ---</body></html>")	}; 
	}
	&readTestSuitProperty();
	########################################################
}

sub tcMain_ { $notUsegetTCName= 1; find(\&recursiveSearchtcMain, $SvrDrive); }
sub recursiveSearchtcMain() { 
	my $returnValue ='';
	if ($SvrTCNamePattern eq '*') { $SvrTCNamePattern = '.*';} 
	if (($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i))  # TC Filter
	{	
		$tcIdCtr++;
		my $eachTC 	= &getRoot($File::Find::name);	
		$SvrTCName 	= &getDir ($File::Find::name);
		$eachTC	 	= &getRoot($eachTC);
		if (-e "$SvrTCName/_tafGlobalVars.txt") { &readTAFTCVars();} # TC Global Variables will overwrite TAF Global Variables
		&getWeb_($eachTC) =~ /scrollAmount\s*=\s*(\d+)/; $scrollAmount = $1; if ($scrollAmount) {;} else {$scrollAmount =0;}
		&getWeb_($eachTC) =~ /borderWidth\s*=\s*(\d+)/ ; $borderWidth  = $1; if ($borderWidth) {;} else {$borderWidth=0;}
		&getWeb_($eachTC) =~ /borderStyle\s*=\s*(.+)/  ; $borderStyle  = $1; if ($borderStyle) {;} else {$borderStyle=0;}

		if (    ($tcOp !~ /^\s*$/)&&($SvrTCName =~/$SvrTCNameExecPattern/)&&($tcIdCtr >= $tcIdMin) 
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName, "value") =~ /$tcPropertyPatternPattern/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName1, "value") =~ /$tcPropertyPatternPattern1/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName2, "value") =~ /$tcPropertyPatternPattern2/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName3, "value") =~ /$tcPropertyPatternPattern3/i)
		)  { 		# Property/testcaseExec Filter
		   if ($propertyOp) {								# Property Processor
		        ##################### Property OPeration Start ####################
			if ($propertyOp =~ /tcDescAuto/) {					# add tcDesc when generateTestsuite
				my $tcDescAuto="";
				if ($#tcDesc eq 0 ) {;} else { $tcDescAuto = "add=tcDesc:".shift @tcDesc; }
				my $tcDescAuto_ = $tcDescAuto; $tcDescAuto =~ s/_space_/ /g; $tcDescAuto =~ s/_column_/:/g; $tcDescAuto =~ s/_eq_/=/g; 
				printf "%-20s %s %s\n", "processProperty:", &getTCName($File::Find::name),$tcDescAuto;
				&processProperty("",&getTCName($File::Find::name), $tcDescAuto_);
			} elsif (($propertyOp =~ /_doit_/i) || ($propertyOp =~ /^\s*_?get_/i) || ($propertyOp =~ /^\s*_?list_/i)) {   	# property Operation (_doit_)
				my $propertyOp_  = $propertyOp; 
				$propertyOp_  =~ s/_doit_//g; 
				my $rst = &processProperty("",&getTCName($File::Find::name), $propertyOp_);
				my $File_Find_name = $File::Find::name; $File_Find_name =~ s/\/$tc_pl//g;
				if ($rst =~ /\n/) {
					#### uncomment for debug   print "$File_Find_name\t$propertyOp_=\n$rst\n";
 					&appendtoFile_	($SvrDrive.'/'.$SvrProjName.'/'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=\n$rst\n")				;
					print $SvrDrive.'/'.$SvrProjName.": $propertyOp_ = $rst"				;
				} else {
					#### uncomment for debug   print "$File_Find_name\t$propertyOp_=$rst\n";
 					&appendtoFile_	($SvrDrive.'/'.$SvrProjName.'/'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=$rst\n")				;
					print $SvrDrive.'/'.$SvrProjName.": $propertyOp_ = $rst"				;
				}
			} else {
				print "[TS/TC=$File::Find::name]  propertyOp=$propertyOp    _doit_\n"; # property Operation (print it)
			}
		        ##################### Property OPeration End   ####################
		   } # else 
		   if (($propertyOp =~ /tcDescAuto/i) || ($propertyOp =~ /^\s*$/)) {			# TC Exec Processor
			##################### TC Operation Start ######################
			if ($scrollAmount ==0 and $borderWidth ==0) { 					# TC Execution
				my $scrollAmount_ = 1 ; if ($tcOp =~ /list/) { $scrollAmount_ = 0; } 
				if ($tcOp =~ /exec/i) { &updateWeb_(&getDir($File::Find::name),$scrollAmount_, $borderWidth, "SOLID", $ExecutionType); &generateRootIndex ()	; } # update RootIndex
				$returnValue = $returnValue. &processTC("","$tcOp=$eachTC",$pr2Screen)."\n"; 
					&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				if ($performanceMode =~ /slow4WebUI/i) {
					&reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
					&reportTCSummary ();
					&updateTestsuitePassFail ()	;
				}
				&updateWeb_(&getDir($File::Find::name),0, $borderWidth, "SOLID");
				if (($tcOp !~ /list/) && ($tcOp !~ /mark/)) { sleep $sleep4Display;}
			} elsif ( $scrollAmount != 0 ) {						# Handle different TC exec state - handle concurrency 
				if       (($scrollAmount != 0 and $borderWidth== 0 )) { $borderWidth = 1; $borderStyle = "DOTTED"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /DOTTED/i)) {$borderWidth =1; $borderStyle = "SOLID"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /SOLID/i)) {$scrollAmount=0; $borderWidth =0; $borderStyle = "SOLID"; }
					&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				if ($performanceMode =~ /slow4WebUI/i) {
					#### &reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
					&reportTCSummary ();
					&updateWeb_(&getDir($File::Find::name),$scrollAmount, $borderWidth, $borderStyle);
				}
			} ##################### TC Operation End ######################
			if ((&getExitTAFGracefullyLock() eq &getRoot_2($File::Find::name)) || (&getExitTAFGracefullyLock() eq "exitTAF" ) ) { print "TAF exited gracefully\n"; &tcPost(); &releaseExitTAFGracefullyLock(); exit; } 
				&generateRootIndex ()	; 
		   } 
		} else {	# to handle no-run execution add to ts/tc/thProperty.txt
				&dumyTC_ ();
		}

		$scrollAmount = 0; $borderWidth = 0; $borderStyle = "SOLID";
		#}	# Property Filter 							# Passing $scrollAmount, $borderWidth, $borderStyle, 
	} # TC Filter
}
sub tcPost {
	##################### Post PRocessor ###################
	if (-e $SvrDrive.'/'.$SvrProjName ) {				# fix 2013/04/13
	&createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"")				;
	&reportTCHistory("null");					# TC ReporHistory -> testsuite\_tcReportHistory_.html
	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body><pre>\n")	;
 	&appendtoFile_		($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"</pre></body></html>\n")				;
   	&mergeFile_		($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1)		;
   	&mergeFile_		($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http)	;
	&prHtml1()			;
	&appendtoFileFile_	($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1,      $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml)	;
	&appendtoFileFile_	($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http);
	&prHtml2()			;
	&reportTCSummary ();
	&generateRootIndex      ()	; 
	&updateTestsuiteHTA     ()	;
	&updateTestsuitePassFail()	;
	$AutomationtsName   = "$SvrProjName";
    	&generateExcelReport	() 	;	
	&sortCmdLog();
	}
	sleep $outputPause;
	########################################################
} 

sub heartBeat { print "This is heartBeat\n";}
# sub heartBeat { goto &fetchmail}

sub fetchmail {
my $Acctusername 	= "w";
my $TAFusername 	= "w";
my $gmail 		= "wripcity\@gmail.com";
my $password 		= "beaverton";

	############# generate the .fetchmailrc if it doens't exist ##################
my $str=<<EOF;
poll pop.gmail.com with proto POP3 and options no dns user '$gmail' there with password '$password' is '$TAFusername' here  options ssl 
EOF
	my $fetchMailRCFName = "c:/cygwin/home/$Acctusername/.fetchmailrc" ;
	if ( -e $fetchMailRCFName) { ; } else { 
		mkpath "c:/cygwin/home/$Acctusername";	
		open Fout, ">$fetchMailRCFName"; print Fout $str; close Fout; print " -> $fetchMailRCFName\n";}
	############# generate the .fetchmailrc if it doens't exist ##################

	############# generate the fetchmail.bat if it doens't exist ##################
	$str="/usr/bin/fetchmail.exe -vk";
	my $fetchMailBATFName = "c:/cygwin/home/$Acctusername/fetchmail.bat" ;
	if ( -e $fetchMailBATFName) { ; } else { open Fout, ">$fetchMailBATFName"; print Fout $str; close Fout; print " -> $fetchMailBATFName\n";}
	############# generate the .fetchmailrc if it doens't exist ##################


	my $tcId = 1; $tcId = shift if @_; 
 	my $fetchMailDate ;
 	my $cmd = 'c:\cygwin\bin\bash.exe -l /home/'.$Acctusername.'/fetchmail.bat';  my $rst = `$cmd 2>&1`; 
 	foreach my $each (split /\n/, $rst) { if ($each =~ /protocol POP3\) at\s*(.+): poll completed/) { $fetchMailDate = $1; } }
 	copy ('c:/cygwin/var/spool/mail/'.$Acctusername, 'c:/_TAF/_gmail_.txt'); 
 	$rst = "log is skipped\n";
 	return "---------- Start  ".(caller(0))[3]."-----------\n$cmd\n".$rst."----------  End   ".  (caller(0))[3]. "-----------\n";
}
 

sub getTAFArgsFromFile {
	my $fname = "$c/$_TAF/_tafArgs.txt";
	my $return="";
	if (-e $fname) { open Fin, $fname; while ($_ =<Fin>) { chop; $return .=";$_";	}	close Fin; }
	$return =~ s/^\s*;+//g; $return =~ s/;+/;/g;
       	$return =~ s/\s*//g; # $return =~ s/$/;/;
	unlink $fname;
	return $return;
}
sub markDaily {
	if ((($makeMarkLastDay  < &getExecDay()) && ($makeMark =~ /n/)) or (($tcCtr)%($tcDelta)== 0)) {
		$makeMarkLastDay = &getExecDay(); $makeMark = 'y'; 
	} else {
			$makeMark = 'n';
	}
	$tcCtr++;
}

sub getExecDay {
	my $initStartTime = &UnixDate( "Jan 1, 2012", "%m/%d/%Y %H:%M:%S %Z" );
	my $endStartTime  = &UnixDate( "now" , "%m/%d/%Y %H:%M:%S %Z" );
	my $totalTimeSpan = &DateCalc(&ParseDate($initStartTime),&ParseDate($endStartTime));  #### => YY:MM:WK:DD:HH:MM:SS  the years, months, etc. between the two
	my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $totalTimeSpan;
	my $makeMarkLastDay_Local =  int ($H/24); 
	return $makeMarkLastDay_Local;
}

sub generateTAFVars   {goto &printTAFGlobalVars}
sub generateTAFTSVars {goto &printTAFTSVars}
sub generateTAFTCVars {goto &printTAFTCVars}

sub printTAFGlobalVars { open Fout, ">$c/$_TAF/_tafGlobalVars.txt"; print Fout &printGlobalVars(); close Fout; print " -> $c/$_TAF/_tafGlobalVars.txt\n"; }
sub printTAFTSVars { open Fout, ">$c/$_TAF/$SvrProjName/_tafGlobalVars.txt"; print Fout &printTSGlobalVars(); close Fout; print " -> $c/$_TAF/$SvrProjName/_tafGlobalVars.txt\n"; }
sub printTAFTCVars { open Fout, ">$c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt"; print Fout &printTCGlobalVars(); close Fout; print " -> $c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt\n"; }

sub updateTAFGlobalVars { my $str =  "testcaseNode                  =$testcaseNode\n"; $str = shift if @_; 

			if (-e "$c/$_TAF/_tafGlobalVars.txt") {
			open Fout, ">>$c/$_TAF/_tafGlobalVars.txt"		 ; print Fout $str	; close Fout; print " ->> $c/$_TAF/_tafGlobalVars.txt\n"; 
			} else { print "updateTAFGlobalVars: $c:/$_TAF/_tafGlobalVars.txt does *NOT* exist\n"; }
		
		}

sub updateTAFTSVars     { my $str="Execution_24_7_title          =n\nExecution_local_only           =y\n";  $str = shift if @_; 
			
			if (-e "$c/$_TAF/$SvrProjName/_tafGlobalVars.txt") {
			open Fout, ">>$c/$_TAF/$SvrProjName/_tafGlobalVars.txt"; print Fout $str; close Fout; print " ->> $c/$_TAF/$SvrProjName/_tafGlobalVars.txt\n"; 
			} else { print "updateTAFTSVars: $c:/$_TAF/$SvrProjName/_tafGlobalVars.txt does *NOT* exist\n"; }
			}

sub updateTAFTCVars     { my $str="Execution_24_7_title          =n\nExecution_local_only           =y\n";  $str = shift if @_; 
			if (-e "$c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt") {
			open Fout, ">>$c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt"; print Fout $str; close Fout; print " ->> $c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt\n"; 
			} else { print "updateTAFTCVars: $c:/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt does *NOT* exist\n"; }
			}


sub clearTAFGlobalVars { unlink "$c/$_TAF/_tafGlobalVars.txt"		 ; print " -rm-> $c/$_TAF/_tafGlobalVars.txt\n"; }
sub clearTAFTSVars     { unlink "$c/$_TAF/$SvrProjName/_tafGlobalVars.txt" ; print " -rm-> $c/$_TAF/$SvrProjName/_tafGlobalVars.txt"; }
sub clearTAFTCVars     { unlink "$c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt"; print " -rm-> $c/$_TAF/$SvrProjName/$SvrTCNamePattern/_tafGlobalVars.txt\n"; }
####################### remove duplicate records in file
sub removeDuplicate { 
	my $fname  = shift;
	if ($fname ) {;} else { print "remvoeDuplicate: needs filename\n"; exit; }
	if (-e $fname ) {;} else { print "remvoeDuplicate: $fname doesn't exist\n"; exit; }
	my $fname_tmp = $fname."_.htm"; 
open FILE , $fname; 
open FILE_tmp , "> $fname_tmp";
my $firstOccurence = "_firstOccurence_";
while ($_ = <FILE>) { if (($firstOccurence !~ /^_firstOccurence_$/) and ($_ ne $firstOccurence)) { print FILE_tmp $_; $firstOccurence = $_; } }
close FILE;
close FILE_tmp;
copy ($fname_tmp, $fname);
}

####################### copy Testsuite                  
sub copyTestsuite { shift; print "copy $tsFrom -> $tsTo\n"; rcopy ($tsFrom, $tsTo) or die $!; 1;}
sub copyTS        { shift; print "copy $tsFrom -> $tsTo\n"; 
	if (-e $tsFrom) {;} else { print "Warning: $tsFrom doesn't exist. It is created.\n"; mkdir $tsFrom; }	
	if (-e $tsTo  ) {;} else { print "Warning: $tsTo   doesn't exist. It is created.\n"; mkdir $tsTo  ; }	
	rcopy ($tsFrom, $tsTo) or die $!; return 1;}
############

sub generatePropertyTestsuite {goto &generateTestsuiteByDesc}
sub generateTestsuiteBasedOnProperty{
$SvrProjName =~ s/\\/\//g;
&tcMain_1(); 
1;
}
#######################generate Property TCs from desc

sub generateTestsuiteByDesc { $SvrProjName =~ s/\\/\//g; &tcMain_1(); 1; }
sub tcMain_1 { 
	print "	Scanning for testsuites at $SvrProjName ......\n"; 	
	find(\&recursiveSearchtcMain_1, $SvrProjName); 				# print "	[fyi: -> $generateTestsuiteBAT]\n"; 
1;
}
sub recursiveSearchtcMain_1() { 
	if (($File::Find::name =~ /\/$TSHookName\s*$/) && ($tcPropertyName !~ /all/i))
	{ 	
		&readTCDesc($File::Find::name);
	 	$tcPropertyPattern->add($tcPropertyName ); 
		my @property = split ("\/", $File::Find::name) ; 
		my $tags_ = $tags; $tags_ =~ s/,/\|/g; $tags_ = "($tags_)"; 
		if ($property[$#property -1] =~ /$tags_/ ) {;} 			####  stop recursivly creating property test suite
		else {		
			&generateTS ($File::Find::name, $tcPropertyName); 
		}
	}
}

sub generateTestsuiteAgain {
my $SvrProjName_ = $SvrProjName; $SvrProjName = "$c\\$_TAF"; $SvrProjName =~ s/\\/\//g;
&tcMain_2(); 
$SvrProjName=$SvrProjName_; $SvrProjName =~ s/\\/\//g; &readTAFProperty(); &generateRootIndex("exit");
1;
}

sub tcMain_2 { 
	print "	Scanning for testsuites at $SvrProjName ......\n"; 	
	find(\&recursiveSearchtcMain_2, $SvrProjName); print "	[fyi: -> $generateTestsuiteBAT]\n"; 
1;
}
sub recursiveSearchtcMain_2() { 
	if (($File::Find::name =~ /$reportHtml\s*$/))
	{ 	
		my $cmd = $File::Find::name; 
		$cmd =~ s/\/?$reportHtml//;
		$cmd =~ s/$c\/$_TAF//;
		$cmd =~ s/^\s*\///;
		if ($cmd) { $cmd = "testsuite=$cmd;performanceMode=fast;list"; 
		$passFailDisplayWidth	= 8;					# TS Variable. Should be reset for each TS execution 
		&processTCs("", $cmd); 
		
		}
	}
}

sub generateTestsuiteScript {
	my $testsuite; 								# ="c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl"; 
	$testsuite = $SvrProjName; my $testsuiteTAF = $SvrProjName; $testsuiteTAF =~ s/c://g; # here
	foreach my $each (split /,/, $tags) {
print <<EOF;
REM $c/$_TAF/taf.pl -processTSs create=$testsuite							rem create Tag     TS
$c/$_TAF/taf.pl tcPropertyName=$each;testsuite=$testsuite;generateTestsuiteByDesc			rem create Tag     TS
$c/$_TAF/taf.pl testsuite=$testsuite/$each;generateTestsuite						rem create TAF-tag TS
$c/$_TAF/taf.pl testsuite=$testsuite;testcaseNode=testcase;generateTestsuite				rem create TAF     TS
$c/$_TAF/taf.pl testsuite=$testsuiteTAF;testcaseNode=testcase;list

EOF
;
}

}
sub generateTS {
	my $str; 
	my $tsHook 		= "index.pl"	; $tsHook 		= shift if @_			;  
	my $tcPropertyNameLocal = "_smoketest_"	; $tcPropertyNameLocal 	= shift if @_			;
	my $tsDir 		= $tsHook	; $tsDir		=~ s/(\/$TSHookName\s*$)//g	;  
	my $tsHookChild 	= "$tsDir/${tcPropertyName}/$TSHookNameGenerated"			; # c:\_TAF
	my $tsDirChild 		= "$tsDir/$tcPropertyNameLocal"						; # c:\...			

	my $otherCmd = "copy (\"$tsDir/_tcLogAppend.txt\", \"$tsDirChild/_tcLogAppend.txt\")";
	$ps1_args =~ s/\\/\//g;
	
	if ($tsHook =~ /\.ps1\s*$/)	{ $tsHook	= "powershell -executionpolicy unrestricted -file $tsHook "; } # change1   # solve the ps1->pl cerversion bug

my $perlCode=<<EOF_;
use File::Copy;
if (\$ARGV[0]) { 
	#_cmd_holder_#
} else {
print \<\<EOF;
#_desc_holder_#
EOF
;
}
EOF_
;
	############ TS - > subTS maping Table _tcMap.txt 
	my $ctr_local=1; 
	for (my $i = 1; $i <= $#tcDesc; $i++) { 
		if ( $tcDesc[$i] =~ /($tcPropertyPattern)/i ) {		
			my $tmp = sprintf ("$tsDir\/testcase%04d => $tsDirChild/testcase%04d", $i, $ctr_local);
			&appendtoFileUniqly("$tsDir/_tcMap.txt", $tmp);
			$ctr_local++;
		}
	}

	########## read the Mapping to %_tcMap my %_tcMap; open Fin, "$tsDir/_tcMap.txt"; while ($_=<Fin>) { $_ =~ /(.+)=>(.+)/; $_tcMap{$2}=$1; } close Fin;

	$ctr_local=1;
	for (my $i = 1; $i <= $#tcDesc; $i++) { 
		if ( $tcDesc[$i] =~ /($tcPropertyPattern)/i ) {		
		$tcDesc[$i] = &removeTags($tcDesc[$i]);
		my $tmpStr = "if (\$ARGV[0] == $ctr_local) { \$rst = \`$tsHook $i -ps1_args $ps1_args\` ; $otherCmd; print \$rst; } \n";	  # change 2
		$perlCode =~ s/#_cmd_holder_#/$tmpStr\t#_cmd_holder_#/;
		$tmpStr = "$tcDesc[$i]\n";			# remove tcDesc Serial Number
		$tmpStr =~ s/\\/\//g;  
		$perlCode =~ s/#_desc_holder_#/$tmpStr#_desc_holder_#/;		$ctr_local++;
		}
	}
	if ($ctr_local > 1) {
	if (-e $tsDirChild) {;} else { mkpath $tsDirChild;}
		$perlCode =~ s/#_cmd_holder_#//g;
		$perlCode =~ s/#_desc_holder_#//g;
		open Fout , ">$tsHookChild"; print Fout $perlCode; close Fout; print  "	-> $tsHookChild\n";
	}
}

sub readTCDesc {
	my $cmd = shift; my $ctr = 1;
	$#tcDesc = -1;		
	if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file $cmd -ps1_args $ps1_args"; } 		# change 3
 	foreach my $each (split /\n/, `$cmd`) {
 		if ($each =~ /^\s*$/) {; }
 		elsif ($each =~ /^\s*_test/) { ; } 
 		else {
			#### $tcDesc[$ctr++] = $each; original before add _full_ 
 			$tcDesc[$ctr++] = $each."_full_";
 		}
 	}

}


#######################generate Property TCs from desc
sub scanTestsuites {					######### generate index.htm
	shift; my $doit="n";  my @dir;
	if ($tsFilter =~/_doit_/i) { $doit='y'; $tsFilter =~ s/_doit_//i;} 
	elsif ($tsFilterDefault =~/_doit_/i) { $doit='y'; $tsFilterDefault =~ s/_doit_//i;} 
	elsif ($SvrProjName =~ /_doit_/i) { $doit = 'y'; $SvrProjName =~ s/_doit_//i; }
	
	if ($tsFilterDefault =~ /^$c/)	 {
		@dir = glob "${tsFilterDefault}*"; 
	} else {
		@dir = glob "${c}/${tsFilterDefault}*"; 	# c:\_filter is added to the search pattern
	}

 	if ($SvrProjName !~ /_testSuit_/i) {
 		if ($SvrProjName =~ /^$c/)	 {
 			@dir = glob "${SvrProjName}*"; 
 		} else {
 			@dir = glob "${c}/${SvrProjName}*"; 
 		}
 	}

foreach my $each (@dir) {
	$each =~ s/\\/\//g;
find(sub { if (($File::Find::name =~ /index\.\w+$/i) && ($File::Find::name !~ /${c}\/${_TAF}/i)&&($File::Find::name !~ /${c}.${_TAF}/i))  # todo1 \\
		{
			my $dirName =  $File::Find::name; $dirName =~ s/[\\|\/]index..+$//g; $tsFilterDefault =~ s/\\/\//g;
			if ($dirName =~ /$tsFilterDefault/i) {
			$ps1_args =~ s/ /___/g; 
			$notUsegetTCName = 0; 
			my $cmd = sprintf "$SvrDrive/$taf testsuite=$dirName;web_ui_title=$dirName;ps1_args=$ps1_args;generateTestsuite" ;  
			print "scanTestsuites: $cmd\n"; 
			if ($doit =~ /\by\b/) { # $cmd =~ s/\//\\/g;  # todo2 \\
				print "Running ... >>>>\n$cmd\n<<<<\n"; 
				$workingDir = $dirName; $SvrProjName = $dirName; $web_ui_title = $dirName; $ps1_args = $ps1_args; &generateTestsuite();
			}
			}
		}
	 }, $each);
}
	1;
}
sub getWeb_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
 	my $scrollamount 	= -1 		; 
 	my $borderwidth  	= -1  		; 
 	my $borderStyle  	= 'SOLID'  	; 
	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;

	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  /scrollamount=\s*(\d+)\s*/; $scrollamount = $1;
 				$_ =~  /border:RED\s+(\d+)\s*px/; $borderwidth = $1;
 				$_ =~  /\d+\s*px\s+(\w+)\s*"/; $borderStyle= $1;
 			} 
 		}
 		close Fin;
	}
	return "borderWidth=$borderwidth;scrollAmount=$scrollamount;borderStyle=$borderStyle";
}

sub getTSMaxScrollAmount{
	my $testsuite= "$c/$_TAF/_testsuite2_"; $testsuite = shift if @_;
	my $scrollAmount = -1; 
		if (-e "$testsuite/$reportHtml") {
		open Fin, "$testsuite/$reportHtml";
 		while ($_ = <Fin>) {
			if ($_ =~  /scrollamount=\s*(\d+)\s*/) {
				my $scrollamount = $1; 
				if ($scrollamount > $scrollAmount) { $scrollAmount = $scrollamount; }
 			}
		}
 		close Fin;
	}
	return $scrollAmount;
}

#######################generateRootIndex {
sub generateRootIndex {					######### generate index.htm
	my $exit_y_n = "NO" ; $exit_y_n = shift if @_;
	my %tafUI;
	&readTAFProperty(); # read %tafProperty;
	#### part 1 ####
open INDEX, ">$SvrDrive/index.htm_"; 
print INDEX<<EOF;
<html>
<META http-equiv="refresh" content="$htmlRefreshRate"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" c:/_TAF/taf.pl testcaseNode=_null_;testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;generateTAFTestsuite
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = 'c:\\windows\\system32\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = 'c:\\windows\\system32\\schtasks.exe /create /TR "$c\\$_TAF\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = 'c:\\windows\\system32\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
<body><pre>
<h2><a href="$urlHttp/$reportHtml_http" title="$web_ui_title_tip over Network"> Test Automation </a>$indexTitleRefresh</h2>
EOF

find(sub { if ($File::Find::name =~ /index\.htm$/i) {
			my $tmp= $File::Find::name; $tmp=~ s/$SvrDrive//;
			my $tmp1 = $File::Find::name; $tmp1 =~ s/\/index.htm//g; $tmp1 =~ s/\/$reportHtml//; 
			my $tmp2 = $File::Find::name; $tmp2 =~ s/\/index.htm//g;
			my $testsuite = $tmp2;
			if ($tafProperty{$tmp2}) { $tmp2 = $tafProperty{$tmp2}; } else { $tmp2 = $tmp2; }
			if ($tafProperty{$tmp2} ) { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tafProperty{$tmp2}); }  
			else { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tmp2); }
			$tmp2 = sprintf("%-${tsPropertyWidth}s", $tmp2);
			$tafUI{$tmp2}=" <marquee style=\"border:RED 0px SOLID\" width=48 direction=right behavior=alternate loop=10000 scrollamount=".&getTSMaxScrollAmount($testsuite).">*</marquee> <a href=\"$url".$tmp."\">$tmp2</a><a style=\"color:white\">$SvrDrive$tmp</a>\n" if ($tmp ne "/index.htm");
		}
	 }, $SvrDrive);

 	foreach my $each1 (sort keys %tafUI) { print INDEX $tafUI{$each1} if ($each1 !~ /^\s*$c\/$_TAF\s*$/); }

print INDEX <<EOF;
</pre></body></html>
<style type="text/css"> a { text-decoration:none} </style>
EOF
;
close INDEX;
  		move ($SvrDrive.'/index.htm_', $SvrDrive.'/'."index.htm");
	#### part 1 ####
	#### part 2 ####
open INDEX, ">$SvrDrive/index_http.htm_";		########## generate index_http.htm 

print INDEX<<EOF;
<html>
<META http-equiv="refresh" content="$htmlRefreshRate"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
<body><pre> <h2><a href="$urlHttp/$reportHtml_http" title="Click to view *all* Testsuites"> Test Automation </a>$indexTitleRefreshCGI ($hostname/$ip)</h2>
EOF
find(sub { if ($File::Find::name =~ /index_http\.htm$/i) {
			my $tmp = $File::Find::name; $tmp =~ s/$SvrDrive//;
			my $tmp2 = $File::Find::name; $tmp2 =~ s/\/index_http.htm//g;
			my $testsuite = $tmp2;
			if ($tafProperty{$tmp2} ) { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tafProperty{$tmp2}); }  
			else { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tmp2); }
			$tafUI{$tmp2}=" <marquee style=\"border:RED 0px SOLID\" width=48 direction=right behavior=alternate loop=10000 scrollamount=".&getTSMaxScrollAmount($testsuite).">*</marquee> <a href=\"$urlHttp".$tmp."\">$tmp2</a><a style=\"color:white\">$SvrDrive$tmp</a>\n" if ($tmp ne "/index.htm");
		}
	 }, $SvrDrive);

 	foreach my $each1 (sort keys %tafUI) { print INDEX $tafUI{$each1} if ($each1 !~ /^\s*$c\/$_TAF\s*$/); }  

print INDEX <<EOF;
</pre></html>
<style type="text/css"> a { text-decoration:none} </style>
EOF
;
close INDEX;
  		move ($SvrDrive.'/index_http.htm_', $SvrDrive.'/'."index_http.htm");
	#### part 2 ####
	if ($exit_y_n =~ /exit/) { sleep $outputPause; exit; }
1;
}


####################### read Testsuite web_ui_title
sub readWebTitle{ 
	my $dir = shift;  my %prop; my $webTitle = "Test Automation Framework";
	if (-e "$dir/tsProperty.txt") { 	# todo hardcoded variable
		open Fin, "$dir/tsProperty.txt"; 
		while ($_ =<Fin>) {
			my $tmp=""; /(\s*)/; $_ =~ /^\s*(.+)\|/       ; $tmp = $1; $prop{$tmp}=$_; 
			if ($_ =~ /web_ui_title\s*:\s*(.+)\s*:\s*web_ui_title/) {$webTitle = $1;}
		} close Fin; 
	}
	return $webTitle;
}

####################### get Testsuite Total Exec Time 
sub getTestsuiteTotalExecTime {
	my $index= shift; my $index_; my $tsTotalExecTime = 0;
		if (-e $index) {
		open FinTS, $index; 
		while ($_ = <FinTS>) { if ($_ =~ /^\s*<span\s+style="color:black;/i) { $_ =~ /(\d+)\s*\(s\)/; $tsTotalExecTime = $tsTotalExecTime + $1;} }
		close FinTS;
		} 
	return &timeConvert($tsTotalExecTime); 
}

####################### get Testsuite Total Exec Time 
sub timeConvert {
	my $totalTime = shift; 
	my $hr  = int ($totalTime/3600); 
	my $min = int (($totalTime - $hr*3600) / 60);
	my $sec = int (($totalTime - $hr*3600 - $min * 60));
	$totalTime = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
	$totalTime = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
}

#######################generateFailedTCHtml {
sub createTestsuitePassFailedHtml {
	my $index= shift; my $index_;
	####################### failed.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_failed\.htm/;
		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=fail/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_failed\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:green;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:black;/i) { ;
			} else { 
				print Fout $_; }
			}
		close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_failed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=fail/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index_http\.htm/index_failed_http\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:green;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:black;/i) { ;
			} else { print Fout $_; }
		}
		close Fout; close Fin;
		}
	}	
	####################### failed.htm #####################

	####################### pass.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_passed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=pass/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_passed\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:black;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
			} else { 
				print Fout $_; }
			}
		close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_passed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=pass/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index_http\.htm/index_passed_http\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:black;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
			} else { print Fout $_; }
		}
		close Fout; close Fin;
		}
	}	
	####################### pass.htm #####################
	####################### other.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_others\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
				if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=\\\\d+_pipe_null/g; }
				if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_others\.htm/g; }
				if (&getLatestPassFail($_) =~ /color:green;/i) { ;
				} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
				} else { print Fout $_; }
			}
			close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_others\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
				if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=\\\\d+_pipe_null/g; }
				if ($_ =~ /RunFile/) { $_ =~ s/index_http\.htm/index_others_http\.htm/g; }
				if (&getLatestPassFail($_) =~ /color:green;/i) { 
				} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
				} else { print Fout $_; }
			}
			close Fout; close Fin;
		}
	}	
	####################### other.htm #####################
}

#######################generateFailedTCHtml 

#######################generate_tagsHtml
sub generateTagHtml {
	my $index= shift; my $index_;
	my $tagName = "_smoke_"; 
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_$tagName\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
				if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=\\\\d+_pipe_null/g; }
				if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_${tagName}\.htm/g; }
				if (&processProperties("","dir", $tagName) =~ /color:green;/i) { print Fout $_; } # here to start
			}
			close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_others\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
				if (&getLatestPassFail($_) =~ /color:green;/i) { 
				} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
				} else { print Fout $_; }
			}
			close Fout; close Fin;
		}
	}	
}
#######################generate_tagsHtml

sub getLatestPassFail {
	$_ = shift; my $color; my @symbol = $_ =~ />.<\/a><a\s+style=/g; my @color  = $_ =~ /<a style=\"color:\w+\"/g; 
for (my $i = 0; $i < $#symbol; $i++) { 
	$symbol[$i] =~ />(.)</; $symbol[$i] = $1;
	if ($symbol[$i] =~ /^\s*$/) {;}  # dumy 
	elsif ($symbol[$i] =~ /\|/) {;}  # mark
	else { $color[$i] =~ /\"(color:\w+)\"/; return "$1;"; }
}
return "";
}
sub getLatestPassFail_old {
	$_ = shift; my $color;
	if ($_ =~ /^\s*<span\s+style="color:black;">/) {
		if ($_ =~ /^\s*<span\s+style="color:black;">\s*<a\s+style="color:\s*(\w+)"/) {$color = $1;} else {$color = "black";}
	}
	if ($color) { return "color:$color;";} else {return "_";}
}


sub updateWeb {
	my  %tsProperty;
 	my $tcname = 'TC_tc1'; $tcname = shift if @_		;	
 	my $scrollamount = 0 ; $scrollamount = shift if @_	;
	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g	;

	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml		;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"	;
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~ /scrollamount=\s*(\d+)\s*/;
 				$_ =~ s/scrollamount=\s*$1\s*/scrollamount=$scrollamount/;
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;

  		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	}
	return "tcCtr_Dynamics=$scrollamount";
}

################################################################################
#        
################################################################################
sub hungryMatch {    # hungryMatch("startStr_returnStr_endStr","startStr","endStr")
    my $str        = shift; my $startStr    = shift; my $endStr    = shift;

    if (index($str, $startStr) < 0) { return "";}
    if (index($str, $endStr  ) < 0) { return "";}
    my $offset     = index($str,$startStr) + length $startStr;
    my $len     = index($str,$endStr)  - $offset;
    if ($len < 0) { $len = 0; }
    return substr ($str, $offset, $len);
}
sub match1stRegexp { my $str = shift; my $pattern = shift; @_ = split (/$pattern/, $str); return $_[0]; }
sub matchRestRegexp { my $str = shift; my $pattern = shift; @_ = split (/$pattern/, $str); $str =~ s/^\s*$_[0]//; $str =~ s/^\s*$pattern//; return $str;}
sub removeTags { my $str = shift; @_ = ($str=~ /\b_\S+_\b/ig); foreach my $each (@_) {
		if ($each !~ /\//) { $str =~ s/\b$each\b//g ; 
		}
	
	} 
	
	return $str; }
sub updateTestsuiteHTA {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( &hungryMatch($_,"\/\/\/","index.htm") ) { my $ts= &hungryMatch($_,"\/\/\/","index.htm") ; &createTestsuiteHTA ($ts); } }
	close Fin;
}

sub tsPostProcessPlugin {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( &hungryMatch($_,"/\/\/\/","index.htm")) { my $ts= &hungryMatch($_,"\/\/\/","index.htm"); print "postProcessPlugin: $ts\n";} }
	close Fin;
}
sub updateTestsuitePassFail {
	if (-e $SvrDrive."/index.htm" ) {
	open FinIndex, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <FinIndex>) { chop; 
		if ( &hungryMatch($_, "\/\/\/","index.htm" )) { 
			my $ts     = &hungryMatch($_,"\/\/\/","index.htm")."index.htm" ; &createTestsuitePassFailedHtml ($ts); 
			my $ts_http = $ts; $ts_http =~ s/index\.htm/index_http\.htm/; &createTestsuitePassFailedHtml ($ts_http); 
		} 
	}
	close FinIndex;
	}
}

sub createTestsuiteHTA {
	my $tsDir = shift; @_ = split /\//, $tsDir; my $testsuite = $_[$#_];
	&createFile_( $tsDir.'ts.hta', 
"
<html>
<head>
	<script language=\"JavaScript\">
		function RunFileHTTP(testsuite, testcase) {
//			alert(\"testsuite is \" + testsuite + \" testcase is \" + testcase );
			 WshShell = new ActiveXObject(\"WScript.Shell\");
		    	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + ' /f'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
			 cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR \"$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec\" /TN TAF_'+testsuite+' /sc monthly /mo 1 /F'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
    		  	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
		}

	function sleep(milliseconds) {
	  var start = new Date().getTime();
	  for (var i = 0; i < 1e7; i++) {
	    if ((new Date().getTime() - start) > milliseconds){
	      break;
	    }
  	}
}

	</script>

</head>
<body onLoad =\"RunFileHTTP(\'$testsuite\', \'.*\')\">Run $testsuite\/ts.hta</button> <p>
</body>
</html>

")
;

}	

################################################################################
#        
################################################################################
sub initTAF {
	foreach my $each (split /\n/, `schtasks /query`) {
		if ($each =~ /TAF_/i) {
			$each =~ /^\s*(.+)\s+(\d+\/\d+\/\d+)\s+/;
			my $processName = $1; my $cmd = "schtasks /delete /tn $processName /f"; `$cmd`;
		}
	}
}

################################################################################
#        
################################################################################

sub readTestSuitProperty {
	if ( -e $SvrDrive.'/'.$SvrProjName.'/'."tsProperty.txt") {
	open Fin, $SvrDrive.'/'.$SvrProjName.'/'."tsProperty.txt";
	while ($_ = <Fin>) { chop;
 		if ($_ =~ /web_ui_title\s*:\s*(.+)\s*:\s*web_ui_title/)  { $web_ui_title = $1; }
		# else { $web_ui_title = "Test Automation Framework"; }
		my $tcname, my $tcdesc;
		($tcname, $tcdesc) = split /[\|]/, $_;
		if ($tcdesc) {
		#### Remove xml tags from the tcDesc for property display 
		$tcdesc =~ s/<.*>//g;
		$tcname =~ s/^\s*//; $tcname =~ s/\s*$//;  # $tcdesc =~ s/^\s*//;
		$tsProperty{$tcname}= $tcdesc;
		}
	}
	close Fin;
	}
}

################################################################################
#        
################################################################################

sub readTAFProperty {
	if ( -e $SvrDrive.'/'.$tsProperty) {
	open Fin, $SvrDrive.'/'.$tsProperty;
	while ($_ = <Fin>) {
		chop;
 		if ($_ =~ /web_ui_title\s*:(.+):\s*web_ui_title/)  { $web_ui_title = $1; }
		my $tcname, my $tcdesc;
		($tcname, $tcdesc) = split /[\|]/, $_;
		if ($tcdesc) {
		$tcname =~ s/^\s*//; $tcname =~ s/\s*$//;  # $tcdesc =~ s/^\s*//;
		$tafProperty{$tcname}= $tcdesc;
		$tafPropertyRev{$tcdesc} = $tcname;
		}
	}
	close Fin;
	}
}

################################################################################
#        
################################################################################
sub getTSNameFromTSDesc {
	&readTAFProperty();
	my $tcDesc = "018"; $tcDesc = shift if @_;
	foreach my $each (keys %tafPropertyRev) {
		if ($each =~ /$tcDesc/i) { my $tmp = $tafPropertyRev{$each}; $tmp =~ s/$c\/$_TAF\///; return $tmp; }
	}
}
################################################################################
#        
################################################################################
sub runFromGmailService {
while (1==1) {
`$c/$_TAF/$taf runFromGmail`; 
sleep 10;
}
}
sub runFromGmail {
my $cmd='c:\cygwin\bin\bash.exe -l /home/yongyan.wang/fetchmail.bat'; my $rst = `$cmd`;
# my $gmailFName = 'c:/cygwin/var/spool/mail/w'; my $testsuite="";
my $gmailFName = 'c:/cygwin/var/spool/mail/yongyan.wang'; my $testsuite="";

if ( -e $gmailFName) { open Fin, $gmailFName; while ($_ = <Fin>) { if ($_ =~ /^\s*subject:\s+Run\s*(.+)\s*$/i) { $testsuite=$1; } } close Fin; }

if ($testsuite =~ /^\s*\d+/) {
	my $cmd = "c:/strawberry/perl/bin/perl.exe $c/$_TAF/$taf testsuite=".&getTSNameFromTSDesc($testsuite).";exec";
	my $rst = `$cmd`;
	print ">>$cmd\n$rst\n";
} else { print "\nPlease input the testsuite *Number* (not $testsuite)\n"; }

unlink $gmailFName;
}


################################################################################
#	Subroutine Name : logTC
#		Function: create TC _tcLog.html for each TC
#	Input Parameters: Test Case name
#	Output/Returns  : c:\inetpub\wwwroot\*.html
################################################################################
sub logTC {		# 	Update TC Log on webUI (TH:WebUI)
    my $currentTime  = &UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z" );
    my $tcname       = shift; $tcname = &getTCName ($tcname);
	 if (&getTCLogFname($tcname) =~ /_tcLog\.txt\s*$/ ) { 
	    my 	$webLogText =  &readFile("$tcname/_tcLog.html");
	       	$webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	       	$webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	       	$webLogText =~ s/\n/_nl_/g;
	       	$webLogText =~ s/\s*_nl_\s*/\n/g;
    		my $fileText = &readFile(&getTCLogFname($tcname)); 
    		my $fileText_= &readFile(&getTCLogFname_($tcname));   # for _tcLogAppendix_.txt (pyAnvil logs)
    		my $fileText__= &readFile(&getTCLogFname__($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
    		if (-e $tcname) {;} else {mkpath $tcname;}
	 	open Fout, "> $tcname/_tcLog.html" || die "Warning: $tcname/_tcLog.html doesn't exist\n";
		print Fout &prJScript(); 
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText__ if ($fileText__);
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } elsif ((&getTCLogFname ($tcname) =~ /_tcLogAppend\.txt\s*$/) || (&getTCLogFname_ ($tcname) =~ /_tcLogAppend_\.txt\s*$/) ||(&getTCLogFname__ ($tcname) =~ /_tcLogAppend__\.txt\s*$/) ){ 
	    	my $webLogText =  &readFile("$tcname/_tcLog.html");
	        $webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	        $webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	        $webLogText =~ s/\n/_nl_/g;
       		$webLogText =~ s/\s*_nl_\s*/\n/g;
       		$webLogText =~ s/^\s*//g; 

    		my $fileText = &readFile(&getTCLogFname($tcname)); 
    		my $fileText_ = &readFile(&getTCLogFname_($tcname));  # for _tcLogAppendix_.txt (pyAnvil logs)
    		my $fileText__= &readFile(&getTCLogFname__($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
	
		######## add html tags to $fileText_ #######  
		if ($fileText_) {$fileText_ = &addURLs($fileText_); }
		if ($fileText ) {$fileText  = &addURLs($fileText ); }
		######## add html tags to $fileText_ ####### 

    		if (-e $tcname) {;} else {mkpath $tcname;}
		open Fout, "> $tcname/_tcLog.html" || die "Warning: $tcname/_tcLog.html doesn't exist\n";
		print Fout &prJScript(); 
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText__ if ($fileText__);
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
		print Fout $webLogText;
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } else {
    		if (-e "$tcname/_tcLog.html") {;} else {mkpath $tcname;
		open Fout, "> $tcname/_tcLog.html" || die "Warning: $tcname/_tcLog.html doesn't exist\n";
		print Fout &prJScript(); 
		my $dirRoot = &getRoot($tcname); 
    		my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
		my $runTCOnce = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;exec')\"  title=\"**JScript**: Generate Logs e.g. $tcname/_tcLogAppend.txt \">St</a>";
		

		my $runTCOnceHttp = "<a href=\"${urlHttp}/$tafCGI?tafArgs=SysDrive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;exec_realSemi_tafRedirectory=${urlHttp}/$SvrProjName/$reportHtml_http\"  title=\"**Http**: Generate Logs e.g. $tcname/_tcLogAppend.txt\">Art</a>";
		$runTCOnceHttp =~ s/;/_semi_/g; $runTCOnceHttp=~ s/_realSemi_/;/g;

         	print Fout "==================== Update on $currentTime ${runTCOnce}$runTCOnceHttp ===================== $tcname\n";
    		print Fout "$tcname has no log\n";
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
         	print Fout "</pre></body></html>\n";
         	close Fout;
		}
	 } 
	 rmtree &getTCLogFname ($tcname) ;
	 rmtree &getTCLogFname_ ($tcname) ;
	 rmtree &getTCLogFname__ ($tcname) ;
	 return " tcLog[Append].[txt|html] are refreshed";
}


sub addURLs {
	my $return="";	
	foreach my $each (split "\n", shift ) {
		$_ = $each;
		#### The followings are for Powershell only 
		#s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; s/\(/_leftPara/g; s/\)/_rightPara/g; s/</_lessThan/g; s/>/_greaterThan/g;s/=/_equal/g;
		#s/"/_doubleQuote/g; s/'/_singleQuote/g; s/\$/_dollar_/g; s/\%/_percentage_/g; s/\@/_at_/g; s/;/_semiColumn_/g;
		#s/\W//g;
		#s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g; s/_leftPara/\(/g; s/_rightPara/\)/g; s/_lessThan/</g; s/_greaterThan/>/g;s/_equal/=/g;
		#s/_doubleQuote/"/g; s/_singleQuote/'/g; s/_dollar_/\$/g; s/_percentage_/\%/g; s/_at_/\@/g; s/_semiColumn_/;/g;

		if (($_ !~ /href=\"/) && ($_ =~ /(.+)?($c\S+)\s?(.+)?/i) &&($_ !~ /_url_line_/i)) { # convert c:\abc.txt or c:/efg.txt <a href file= abc.txt </a>
			$_ =~ s/</__lt__/g; $_ =~ s/>/__gt__/g; 
			my $match1 = $1; my $logNameInLog = $2; my $match3=""; if ($3) {$match3 = $3."\n";;}
			if ($logNameInLog =~ /\.txt\s*$/) { 
				$logNameInLog =~ s/\\/\//g;
				my $currentTime  = &UnixDate( "now", "%m-%d-%Y-%H_%M_%S" );
				my $fileFrom = $logNameInLog ; 
				my $fileToFile   = &getTCName()."/".&getRoot_4($logNameInLog); $fileToFile =~ s/\.txt\s*$/_$currentTime\.txt/;
				my $fileToHttp   = &getTCName()."/".&getRoot_4($logNameInLog); $fileToHttp =~ s/\.txt\s*$/_$currentTime\.txt/;
				$_ =~ s/__lt__/&lt;/g; $_ =~ s/__gt__/&gt;/g;
				if ( -e $fileFrom ) { 
					if ( -e &getDir($fileToFile)){ ; } else {mkpath &getDir($fileToFile); }
					copy ($fileFrom, $fileToFile);
					$fileToHttp =~ s/$c\/$_TAF/${ip}${http_port}/;	
					$return = $return.$match1."<a href=\"http://$fileToHttp\"  >(http:$fileFrom)</a> $match3";
					$return = $return.$match1."<a href=\"file:////$fileToFile\">(file:$fileFrom)</a> $match3";
				} else {
					$return = $return.$match1."Warning: Log $fileFrom doesn't exist! $match3";
				}
			} else {
				$return = $return.$_."\n";
			}
#		} elsif (/http:\/\/(.+)\b/) {
#			$_ = "<a href=\"http://$1\">http://$1</a>";
#			$return = $return.$_."\n";
			#
		} else { 
			if ($_ =~ s/_url_line_//i) {; } else {
			$_ =~ s/</__lt__/g; $_ =~ s/>/__gt__/g; 
			$_ =~ s/__lt__/&lt;/g; $_ =~ s/__gt__/&gt;/g;
			}
			$return = $return.$_."\n";
		}
	} 
$return ;
}
sub addURLs_old {
	my $return="";	
	foreach my $each (split "\n", shift ) {

		$_ = $each;
		s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; s/\(/_leftPara/g; s/\)/_rightPara/g; s/</_lessThan/g; s/>/_greaterThan/g;s/=/_equal/g;
		s/"/_doubleQuote/g;
		s/'/_singleQuote/g;
		s/\$/_dollar_/g;
		s/\%/_percentage_/g;
		s/\@/_at_/g;
		s/;/_semiColumn_/g;
		s/\W//g;
		s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g; s/_leftPara/\(/g; s/_rightPara/\)/g; s/_lessThan/</g; s/_greaterThan/>/g;s/_equal/=/g;
		s/_doubleQuote/"/g;
		s/_singleQuote/'/g;
		s/_dollar_/\$/g;
		s/_percentage_/\%/g;
		s/_at_/\@/g;
		s/_semiColumn_/;/g;
		if (($_ !~ /href=\"/) && ($_ =~ /(.+)($c\S+)\s?(.+)?/i)) { # convert c:\abc.txt  <a href file= abc.txt </a>
			my $match1 = $1; my $match2 = $2; my $match3=""; if ($3) {$match3 = $3;}

			if ($match2 =~ /\.txt\s*$/) { 
			my $currentTime  = &UnixDate( "now", "%m-%d-%Y-%H_%M_%S" );
			my $fileFrom = $match2; 
			my $fileTo   = $match2; $fileTo =~ s/\.txt\s*$/_$currentTime\.txt/;
			copy ($fileFrom, $fileTo);
			$return = $return.$match1."<a href=\"file:////$fileTo\">$fileTo</a>$match3\n";
			} else {
			$return = $return.$_."\n";
			}
		} else { 
			$return = $return.$_."\n";
		}
	} 

$return ;
}

sub ps12txt {
	my $return="";	
	foreach my $each (split "\n", shift ) {
		$_ = $each;
		s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; 
		s/\W//g;
		s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g;
		s/^\s*//g;
		$return = $return."\n".$_;
	} 
	$return ;
}

sub addUrl {
	my $return; my $str = shift;
	foreach my $each (split /\n/, $str) {
		if ($each =~ /^\s*(.+\.html)/)  { 
			my $line = $1;
			$line =~ s/^\s*//g;
			$line =~ s/\s*$//g;
			$line =~ s/\\/\//g;
			$line =~ s/HTML:\s*/file:\/\/\//i;
			$line =~ s//file:\/\/\//;
			$return = $return.  "<a href=\"$line\">$each</a>\n";
		} elsif ($each =~ /^\s*(.+\.xml)/)  { 
			my $line = $1;
			$line =~ s/^\s*//g;
			$line =~ s/\s*$//g;
			$line =~ s/\\/\//g;
			$line =~ s/XML:\s*/file:\/\/\//i;
			$line =~ s//file:\/\/\//;
			$return = $return.  "<a href=\"$line\">$each</a>\n";
		} else {
			$return = $return.$each."\n";
		}
	}
	return $return;
}

################################################################################
#	Subroutine Name : getTCLogFname
#		Function: get valid Log (new log) fname 
#	Input Parameters: c:\TC*\_thLog.txt
#	Output/Returns  : noLog or hasWWWLog
################################################################################
sub getTCLogFname	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'/thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'/'.'thProperty.txt');
    }
    my $tcNameLog = $tcName."/_tcLogAppend.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName/_tcLog.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }
    return "noLog"; 
}

sub getTCLogFname_	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'/thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'/'.'thProperty.txt');
    }

    my $tcNameLog = $tcName."/_tcLogAppend_.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName/_tcLog_.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }
    return "noLog"; 
}

sub getTCLogFname__	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'/thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'/'.'thProperty.txt');
    }

    my $tcNameLog = $tcName."/_tcLogAppend__.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName/_tcLog__.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }
    return "noLog"; 
}

sub reportTCSummary {
	$reportHtmlSummaryStr = '';  

	if ( -e "$SvrDrive/$SvrProjName/$reportHtmlHistory" ) {;} else { return; }
	open Fin, "$SvrDrive/$SvrProjName/$reportHtmlHistory" || die "Can't open _tcReportHistory.html";

	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }

	open Fout, "> $SvrDrive/$SvrProjName/$reportHtmlSummary"."_" || die "Can't open _tcReportSummary_.html";

	$reportHtmlSummaryStr = "<html><body><pre>\n"; $reportHtmlSummaryStr = $reportHtmlSummaryStr . "<META http-equiv=\"refresh\" content=\"$htmlRefreshRateWebUI\"> ";
	$reportHtmlSummaryStr = $reportHtmlSummaryStr .  "\n_replace_here_";
 	my $passFail ; my $dateTime; my $date1; my $date2; my %tcResult; my $tcName; my $passCtr=0;
	my $initStartTime = &UnixDate( "Jan 1, 2050", "%m/%d/%Y %H:%M:%S %Z" );
	my $endStartTime  = &UnixDate( "Jan 1, 1900", "%m/%d/%Y %H:%M:%S %Z" );
while ($_ =<Fin>) { 
	chop;
	if (($_ =~ /(testcase\d+)/) &&( $passCtr ==0 )) {
		$tcName = $1;	
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . "\n$tcName: ";
		$_ = <Fin>;
		if ($_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/) { # always skip
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/;
		$passFail = $1; $dateTime= $2; $date1=&ParseDate($dateTime);  my $title=" title=\"$dateTime\"";
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }
		if    ($passFail =~ /pass/i) { $passFail = '<a style="color:green"'.$title.'>*</a>';	} 
		elsif ($passFail =~ /fail/i) { $passFail = '<a style="color:red"'.$title.'>*</a>';} 
		elsif ($passFail =~ /mark/i) {$passFail ="<a style=\"color:black\"$title>$markSymbol<\/a>";}
		elsif ($passFail =~ /Perf/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /null/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /dumy/i) {$passFail ="<a style=\"color:black\"$title> <\/a>";}
		elsif ($passFail =~ /expF/i) {$passFail ="<a style=\"color:black\"$title>*<\/a>";}
		elsif ($passFail =~ /bugF/i) {$passFail ="<a style=\"color:blue\"$title>*<\/a>";}
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
		}
	} elsif (/^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+\s+)/) {
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+(.+)/;
		my $note=$3;
		$passFail = $1; $dateTime= $2; $date2=&ParseDate($dateTime); 
		my $title = " title=\"$dateTime $note\""; 

		if ($passFail =~ /pass/i) { $passFail = '<a style="color:green"'.$title.'>*</a>';	} 
		elsif ($passFail =~ /fail/i)  { $passFail = '<a style="color:red"'.$title.'>*</a>';} 
		elsif ($passFail =~ /null/i) { $passFail = '<a style="color:black"'.$title.'>.</a>';}
		elsif ($passFail =~ /mark/i) {$passFail ="<a style=\"color:black\"$title>$markSymbol<\/a>";}
		elsif ($passFail =~ /Perf/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /null/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /dumy/i) {$passFail ="<a style=\"color:black\"$title> <\/a>";}
		elsif ($passFail =~ /expF/i) {$passFail ="<a style=\"color:black\"$title>*<\/a>";}
		elsif ($passFail =~ /bugF/i) {$passFail ="<a style=\"color:blue\"$title>*<\/a>";}
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }

		my $delta=&DateCalc($date2,$date1); $delta =~ s/\+//g; my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
		my $totalMIN ;
		if ($Y && $M && $D && $H && $MIN && $S && $reportHtmlSummaryScale) {	
		$totalMIN = int ((((($Y*365 + $M * 30 + $D) * 24 + $H) * 60 + $MIN) * 60 + $S)/$reportHtmlSummaryScale) ;
		} else {
		$totalMIN = 0;
		}
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
	}
}

 	my $totalTimeSpan = &DateCalc($initStartTime,$endStartTime);  my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $totalTimeSpan;
	my $NofX          = int ((((($Y*365 + $M * 30 + $D) * 24 + $H) * 60 + $MIN) * 60 + $S)/$reportHtmlSummaryScale) ;
	my $X_Unit = int (3600/$reportHtmlSummaryScale);	

	$reportHtmlSummaryStr = $reportHtmlSummaryStr. "\n_replace_here_\n";
	$reportHtmlSummaryStr = $reportHtmlSummaryStr .  "</pre></body></html>\n";

	my $tmp = "---------- |<marquee width = 50><--</marquee> ".&UnixDate($endStartTime, "%m/%d/%Y %H:%M:%S %Z")." ---------- $SvrDrive/$SvrProjName Test Summary -----...... <marquee width = 50><--</marquee>|". &UnixDate($initStartTime,  "%m/%d/%Y %H:%M:%S %Z" );
	$reportHtmlSummaryStr =~  s/_replace_here_/$tmp/g;
	print Fout $reportHtmlSummaryStr;
	close Fout;
	close Fin;
	move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary);

}
################################################################################
#	Subroutine Name : reportTCHistory
#		Function: append TC result History to htmlLog
#	Input Parameters: Test Case name
################################################################################
sub reportTCHistory_ {
	my $tcname = shift;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---------------------- TestCase: <a name=\"".&getTCName($tcname)."\"> ".&getTCName($tcname)." </a>-----------------------\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, $fileText);
}


sub reportTCHistory {
	my $tcIdCtr_ = $tcIdCtr;
	my $tcname = shift;
	$tcIdCtr=1;
 	&createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body><pre>\n");
find(sub { if (  ($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i)  ) { # fix tcDesc tag related 
			$SvrTCName = $File::Find::name; 
			$SvrTCName =~ s/\/tc.pl//g;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");  if ($fileText =~ /^\s*$/) { $fileText = "";}
	if ($tcDesc[$tcIdCtr]) {;} else { $tcDesc[$tcIdCtr] ="tcDesc is unavailable. It will be updated in next \"list\"";}
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---- TestCase $tcIdCtr: <a name=\"".&getTCName($tcname)."\"> ".&processProperty("",$SvrTCName, "get_tcDesc")."</a>----\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, "$fileText") if ( $fileText !~ /^\s*$/) ;
	$tcIdCtr++;
		}
	 }, "$SvrDrive/$SvrProjName");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"</pre></body></html>\n")				;
	$tcIdCtr = $tcIdCtr_;
}


sub reportTCHistory_old {
	my $tcIdCtr_ = $tcIdCtr;
	my $tcname = shift;
	$tcIdCtr=1;
 	&createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body><pre>\n");
find(sub { if (  ($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i)  ) { # fix tcDesc tag related 
			$SvrTCName = $File::Find::name; 
			$SvrTCName =~ s/\/tc.pl//g;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---------------------- TestCase: <a name=\"".&getTCName($tcname)."\"> ".&getTCName($tcname)." </a>-----------------------\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, $fileText);
	$tcIdCtr++;
		}
	 }, "$SvrDrive/$SvrProjName");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"</pre></body></html>\n")				;
	$tcIdCtr = $tcIdCtr_;
}

################################################################################
#	Subroutine Name : reportTC
#		Function: report TC results on STDOUT and Update TCProj HTML
#	Input Parameters: TC Name
#			  TC PropertyName = tcRunResult
#			  TC Report Type: 0 = latest 1 = historyical
#	Output/Returns  : TC Reports displayed on webUI
################################################################################
sub reportTC() {		# TC Report Function (TH:TC Report)
    my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
    my $cmd=''; $cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
    my $timeSpan  = "2000!now"; 
    my $tcname          = $_[0]; my $propertyPattern = $_[1]; my $reportType = $_[2]; 
    $tcname = &getTCName($tcname);

    my ($timeSpanStart, $timeSpanEnd, $isInSpan, $beautifiedStr, $beautifiedStr4Web); 
    my $returnValue="";
    my ($propertyName, $startTime, $endTime, $comment1, $comment2) ;
    my $passCtr =0; my $failCtr = 0; my $nullCtr = 0 ; my $totalTime=0; my $avgResponseTime; my $propertyValue ='';
    my $totalTimeDummy; my $passFailDisplay=""; my $passFailDisplay_ =""; my $tcTags="";
	&readTestSuitProperty();
    if( $propertyPattern =~ /^\s*$/) {   $propertyPattern = 'tcRunResult';}
    if( $reportType =~ /^\s*$/) {   $reportType = 'lastValue';}

    if ($timeSpan) { $_ = $timeSpan;
 	    ($timeSpanStart, $timeSpanEnd ) = split( /!|\|/, $timeSpan );
 	    $timeSpanStart = &ParseDate($timeSpanStart);
 	    $timeSpanEnd   = &ParseDate($timeSpanEnd);
    }
     my $tcPassFailDisplayWidth = 0; 
#    ############ get maxPassFailDisplayWidth #################
     open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; 	################## Read Property File
#    ############################## Read Property File to update reportHtmlHistory ###########################
     while ( $_ = <Fin> ) { chop;
          if ( $_ =~ /$propertyPattern/i ) {
                 ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
                 my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) );
                 my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) );
                  if   ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; }
                  else                                        { $isInSpan = -1; }
 		my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g;
 		my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
 		my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S;
 		if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";}
              if ( $isInSpan == 1 ) {;
 		 if ( $propertyPattern =~ /tcRunResult/i ) {
     			$tcPassFailDisplayWidth= $tcPassFailDisplayWidth + 1 ;
                 }  
   	     } # endif for InSpan
          }    # endif for /propertyPattern= tcRunResult/
          elsif ($_=~ /^\s*tcTags\s*\|(.+)\|?/) {
                 ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
		$tcTags = $propertyValue;
	  }
     }		
     close Fin;
     if ($tcTags) {
     $tcTags =~ s/_//g; 
     $tcTags =~ s/\t//g;
     $tcTags =~ s/null/    /g;
     } 
    my $passFailDisplayWidth_1st= 0;
    ############ get maxPassFailDisplayWidth #################
    open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; 	################## Read Property File
    ############################## Read Property File to update reportHtmlHistory ###########################
    while ( $_ = <Fin> ) { chop;
         if ( $_ =~ /$propertyPattern/i ) {
                ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
                my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) );
                my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) );
                if   ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; }
                else                                        { $isInSpan = -1; }
		my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g;
		my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
		my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S;
		if ($propertyValue =~ /^\s*([\d|.]+)\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf"; $comment2 = "Perf Test = ${1}s";}
		if ($propertyValue =~ /null/i) 		   {                           ;                        ; $comment2 = "TC returns NULL";}
		if ($propertyValue =~ /pass/i) 		   {                           ;                        ; $comment2 = "Test Passed"  ;}
		if ($propertyValue =~ /fail/i) 		   {                           ;                        ; $comment2 = "Test Failed"  ;}
		if ($propertyValue =~ /bugF/i) 		   {                           ;                        ; $comment2 = "Failed BugID : <TBD>"  ;}
		if ($propertyValue =~ /expF/i) 		   {                           ;                        ; $comment2 = "Expected Fail"  ;}
		if ($propertyValue =~ /expected_f_a_i_l/i) {                           ; $propertyValue = "expF"; $comment2 = "Expected Fail"  ;}

             if ( $isInSpan == 1 ) {
		 if ( $propertyPattern =~ /tcRunResult/i ) {
		      $beautifiedStr = sprintf "%15s %-15s %-25s%-20s Note: %s", $propertyValue, $totalSec.'s', $startTime, $comment1, $comment2; # add comment2 for mouse-over display
		      if ($propertyValue =~ /pass/i) {$passCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."p";}
		      if ($propertyValue =~ /fail/i) {$failCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."f";}
		      if ($propertyValue =~ /mark/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."m";}
		      if ($propertyValue =~ /Perf/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."e";}
		      if ($propertyValue =~ /null/i) {$nullCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."n";}
		      if ($propertyValue =~ /expF/i) {$nullCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."x";}
		      if ($propertyValue =~ /bugF/i) {$nullCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."b";}
		      if ($propertyValue =~ /dumy/i) {$nullCtr++;                                   ; $passFailDisplay = $passFailDisplay."d";}
		      if ($propertyValue =~ /expected_F_a_i_l/i) {; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."x";}

		      if ($propertyValue =~ /pass/i) {                                                $passFailDisplay_ = $passFailDisplay_."p $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /fail/i) {                                                $passFailDisplay_ = $passFailDisplay_."f $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /mark/i) {                                                $passFailDisplay_ = $passFailDisplay_."m $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /Perf/i) {                                                $passFailDisplay_ = $passFailDisplay_."e $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /null/i) {                                                $passFailDisplay_ = $passFailDisplay_."n $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /expF/i) {                                                $passFailDisplay_ = $passFailDisplay_."x $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /bugF/i) {                                                $passFailDisplay_ = $passFailDisplay_."b $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /dumy/i) {                                                $passFailDisplay_ = $passFailDisplay_."d $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /expected_f_a_i_l/i) {  				      $passFailDisplay_ = $passFailDisplay_."x $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /pass|fail|mark|Perf|null|bugF|expF/i) { $passFailDisplayWidth_1st ++ ; }
		 } else {
                 	$beautifiedStr = $_;
             	 }    # endif for /tcRunResult/
                 if ( $reportType =~ /history/i ) {    		# return property history
			 # $returnValue .= "$beautifiedStr\n";
                     $returnValue = "$beautifiedStr\n$returnValue";
                 }
                 elsif ( $reportType =~ /lastValue/i ) {    	# returen last property
                     $returnValue = $beautifiedStr;
                 }
                 elsif ( $reportType =~ /forWeb/i ) {    	# for the web
                         $returnValue .= $beautifiedStr4Web;
                     }
	     } # endif for InSpan
         }    # endif for /propertyPattern/
    }									##################### 

    ############################## Adjust passFailDisplayWidth by _1st and max ###########################
 	if ( $passFailDisplayWidth < $passFailDisplayWidth_1st ) { $passFailDisplayWidth = $passFailDisplayWidth_1st;}
 	if ( $passFailDisplayWidth > $maxPassFailDisplayWidth  ) { $passFailDisplayWidth = $maxPassFailDisplayWidth ;}
    ############################## Read Property File to update reportHtmlHistory ###########################
    	if ($passCtr + $failCtr + $nullCtr == 0) {				##########  Generate TC webUI string 
	$avgResponseTime = 0; } else {
	$avgResponseTime = $totalTime / ($passCtr + $failCtr + $nullCtr); 
	}
	my $qtpHost; my $ATResultFname; my %color; my $color = 'gray'; my @color; my $colorIndex = 0; my $QASvrName; my $expFailure=""; my $bugFailure="";
	if ($propertyValue =~ /pass/i) { $color = "Green"; } elsif ($propertyValue =~ /fail/i) { $color = 'Red'; } elsif ($propertyValue =~ /bugF/i) {$color = "blue";}
	elsif ($propertyValue =~ /expected\s*fail/i) { $expFailure = "_Expected_Failure_ "; }

	$color[0]=1;

	##### testcase Desc #### 
	my $TCDesc_displayTip = "Click to view TC logs";
	my $TCDesc_display ; my $TCDesc_display_ ;
	if ($tsProperty{$tcname}) { 
		###### Handle expected failure 
		if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /fail/i)){ $color = "Green"; }
		if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /pass/i)){ $color = "Red"; }
		###### Handle expected failure 
		$TCDesc_display_ = $expFailure.$tsProperty{$tcname};

		my $TCDesc_display__ = $TCDesc_display_;

		$TCDesc_display__ =~ s/&lt;|&gt;|&amp;|&#37;|&#36;/X/g;

		my $n1 = ()  = $TCDesc_display_ =~ /&lt;|&gt;/g;
		my $n2 = ()  = $TCDesc_display_ =~ /&amp;|&#37;|&#36;/g;
		my $extra = $n1 * 3 + $n2 * 4 ; 

		my $webUI_TCDescWidth_extra = $webUI_TCDescWidth + $extra ;

		if (length($TCDesc_display__) <= $webUI_TCDescWidth ) { 
		$TCDesc_display = sprintf "%-${webUI_TCDescWidth}s", $TCDesc_display_; 
		} else {
		$TCDesc_display = sprintf "%-${webUI_TCDescWidth}s", substr $TCDesc_display_, 0, $webUI_TCDescWidth_extra; 
		$TCDesc_displayTip = $tsProperty{$tcname}; 
		}

	} else { $TCDesc_display = sprintf "%-${webUI_TCDescWidth}s", $tcname; }

	# prHtml3 mark for search

	my $tcSerialN = $TCDesc_display; 
	if ($tcSerialN =~ /^\s*\d+\D+/) {$tcSerialN =~ /^\s*(\d+)\D+/; $tcSerialN = "$1"; if ($tcSerialN) {;} else {$tcSerialN = "";}}
	my $dirRoot = &getRoot($tcname); 
	my $TCCtrToolTip = sprintf "Run Test (Testcase Number == $tcSerialN [%s])", &timeConvert($avgResponseTime); 
	my $TCCtrToolTipMin = sprintf "Run Tests (Testcase Number >= $tcSerialN)" ; 
	my $TCScrollAmount = 0; my $CtrSeparator = "|";
	$passFailDisplay  = &genPassFailDisplay ($passFailDisplay);
	$passFailDisplay = &genPassFailDisplay_ ($passFailDisplay_);

	my $stopTS    = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName Execution_from_cgi=$Execution_from_cgi;Execution_local_only=$Execution_local_only;exitTAFGracefullyString=$tcname;exitTAF')\" title=\"Stop Test (Testcase Number = $tcSerialN)\" >.</a>";
	my $runTS24_7 = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName Execution_from_cgi=$Execution_from_cgi;Execution_local_only=$Execution_local_only;drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;Execution_24_7=y;exec')\"  title=\"Exec Test 24/7 (Testcase Number == $tcSerialN)\"> ,</a>"; 
	my $runTCOnce = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName Execution_from_cgi=$Execution_from_cgi;Execution_local_only=$Execution_local_only;drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;exec')\"  title=\"$TCCtrToolTip\">></a>";
	my $runTSOnce = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName Execution_from_cgi=$Execution_from_cgi;Execution_local_only=$Execution_local_only;drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;tcIdMin=$tcIdCtr;testsuit=$SvrProjName;ExecutionType=runTS;exec')\"  title=\"$TCCtrToolTipMin\"><marquee style=\"border:RED ${borderWidth}px ${borderStyle}\" width=48 direction=right behavior=alternate loop=10000 scrollamount=$scrollAmount>>\|</marquee></a>"; 
	my $html = sprintf( "<span style=\"color:black;\">$passFailDisplay${stopTS}$runTS24_7<font color=\"$color[$colorIndex]\"> $runTCOnce $runTSOnce</font><a href=\"${url}/$SvrProjName/".&getTCNameStr($SvrTCName)."/_tcLog.html\" title=\"$TCDesc_displayTip\">%-${webUI_TCDescWidth}s</a> <a href=\"${url}/$SvrProjName/${reportHtmlHistory}#$tcname\" title=\"Click to see Pass/Fail history\">%5d/%-5d</a> %6d(s)   $tcTags    <font color=\"white\"> %s </font></span>\n",
		    $TCDesc_display,
                    $passCtr,
                    $failCtr,
                    $avgResponseTime,
		    $tcname.'/tc.pl',
                );

	# http

	$stopTS    = "<a href=\"${urlHttp}/$tafCGI?tafArgs=Execution_from_cgi=y;Execution_local_only=$Execution_local_only;exitTAFGracefullyString=$tcname;exitTAF=_null_;tafRedirectory=${urlHttp}/$SvrProjName/$reportHtml_http\" title=\"Stop Test (Testcase Number = $tcSerialN)\" >.</a>";
	$runTS24_7 = "<a href=\"${urlHttp}/$tafCGI?tafArgs=Execution_from_cgi=y;Execution_local_only=$Execution_local_only;SysDrive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;Execution_24_7=y;exec_realSemi_tafRedirectory=${urlHttp}/$SvrProjName/$reportHtml_http\"  title=\"Exec Test 24/7 (Testcase Number == $tcSerialN)\"> ,</a>"; 
	$runTCOnce = "<a href=\"${urlHttp}/$tafCGI?tafArgs=Execution_from_cgi=y;Execution_local_only=$Execution_local_only;SysDrive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;exec_realSemi_tafRedirectory=${urlHttp}/$SvrProjName/$reportHtml_http\"  title=\"$TCCtrToolTip\">></a>";
	$runTSOnce = "<a href=\"${urlHttp}/$tafCGI?tafArgs=Execution_from_cgi=y;Execution_local_only=$Execution_local_only;SysDrive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;tcIdMin=$tcIdCtr;testsuit=$SvrProjName;ExecutionType=runTS;exec_realSemi_tafRedirectory=${urlHttp}/$SvrProjName/$reportHtml_http\"  title=\"$TCCtrToolTipMin\"><marquee style=\"border:RED ${borderWidth}px ${borderStyle}\" width=48 direction=right behavior=alternate loop=10000 scrollamount=$scrollAmount>>\|</marquee></a>"; 

	# $stopTS =~ s/;/_semi_/g; # $stopTS =~ s/_realSemi_/;/g;	# todo: taf.cgi need to handle exitGracefully scenario
	$runTS24_7=~ s/;/_semi_/g; $runTS24_7=~ s/_realSemi_/;/g;
	$runTCOnce=~ s/;/_semi_/g; $runTCOnce=~ s/_realSemi_/;/g;
	$runTSOnce=~ s/;/_semi_/g; $runTSOnce=~ s/_realSemi_/;/g;

	my $html_http = sprintf( "<span style=\"color:black;\">$passFailDisplay${stopTS}$runTS24_7<font color=\"$color[$colorIndex]\"> $runTCOnce $runTSOnce</font><a href=\"${urlHttp}/$SvrProjName/".&getTCNameStr($SvrTCName)."/_tcLog.html\" title=\"$TCDesc_displayTip\">%-${webUI_TCDescWidth}s</a> <a href=\"${urlHttp}/$SvrProjName/${reportHtmlHistory}#$tcname\" title=\"Click to see Pass/Fail history\">%5d/%-5d</a> %6d{s}   $tcTags    <font color=\"white\"> %s </font></span>\n",
		    $TCDesc_display,
                    $passCtr,
                    $failCtr,
                    $avgResponseTime,
		    $tcname.'/tc.pl',
                );


		if ($cmd =~ /noprint/i) {;} else { 
			&appendtoFileUniq_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1, $html 		);
			&updateWeb1_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, $html			);  

			&appendtoFileUniq_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http, $html_http); 
			&updateWeb1Http_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, $html_http	); 
		 } 
     	close Fin;
     	if ($returnValue) {$returnValue =~ s/^\s*//g;} else {$returnValue = "";} 
     	return $returnValue;
}

sub genPassFailDisplay {
	my $str = shift;
	$str = reverse $str;	
	$str = $str. "                                                        ";	 
	$str = substr ($str, 0, $passFailDisplayWidth);
	$str =~ s/p/<a style=\"color:green\">*<\/a>/g;
	$str =~ s/f/<a style=\"color:red\">*<\/a>/g;
	$str =~ s/m/|/g;
	if ($str =~ /^\s*$/) { $str = &genStr($passFailDisplayWidth);}
	return $str; 
}

sub genPassFailDisplay_ {
	my $str = shift; my $str_ =""; my $strLenCtr=0; my $mark4One=0;
	@_ = split /_\|_/, $str; $str="";
	for (my $i=$#_; $i >= 0; $i--) { 
		my $tcResult ; 
		if( $_[$i] =~ s/^\s*(\w)\s+//g) {
			$tcResult = $1; $str_ = $_[$i];  $strLenCtr++;
			if ($tcResult =~ /p/i)    { $str = $str."<a style=\"color:green\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /f/i) { $str = $str."<a style=\"color:red\" title=\"$str_\">*<\/a>";   }
			elsif ($tcResult =~ /m/i) { 
				#if ($mark4One == 2) { ; } else {
				$str = $str."<a style=\"color:black\" title=\"$str_\">$markSymbol<\/a>"; 
				#$mark4One = 0; 
			}

			elsif ($tcResult =~ /b/i) { $str = $str."<a style=\"color:blue\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /e/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
			elsif ($tcResult =~ /n/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
			elsif ($tcResult =~ /x/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /d/i) { $str = $str."<a style=\"color:black\" title=\"$str_\"> <\/a>"; }
			elsif ($tcResult =~ /_/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
		}
			$mark4One++; 
		if ($strLenCtr + 1 > $passFailDisplayWidth) { return $str; }
	} 
	if ($strLenCtr < $passFailDisplayWidth) { for (my $i = $strLenCtr; $i < $passFailDisplayWidth; $i++) { $str = $str . "<a style=\"color:black\"> <\/a>"; } }
	return $str; 
}

sub genPassFailDisplay_old {
	my $str = shift; my $str_ =""; my $strLenCtr=0;
	@_ = split /_\|_/, $str; $str="";
	for (my $i=$#_; $i >= 0; $i--) { 
		my $tcResult ; 
		if( $_[$i] =~ s/^\s*(\w)\s+//g) {
			$tcResult = $1; $str_ = $_[$i];  $strLenCtr++;
			if ($tcResult =~ /p/i)    { $str = $str."<a style=\"color:green\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /f/i) { $str = $str."<a style=\"color:red\" title=\"$str_\">*<\/a>";   }
			elsif ($tcResult =~ /m/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">|<\/a>"; }
		}
		if ($strLenCtr + 1 > $passFailDisplayWidth) { return $str; }
	} 
	if ($strLenCtr < $passFailDisplayWidth) { for (my $i = $strLenCtr; $i < $passFailDisplayWidth; $i++) { $str = $str . "<a style=\"color:blank\"> <\/a>"; } }
	return $str; 
}

sub genStr { my $strLen = shift; my $return=""; for (my $i = 0; $i < $strLen; $i++) { $return  .= " "; } $return; }

sub processTSs{
	shift;
 	my $each = shift;
		if ($each !~ /=/) {
			if ($each =~ /\bmarkblablaaaaa\b/i) { 							;
			} else  {
				; 
 				#print "pd: $SvrProjName,  $each\n"; my $str =  "\&$each();"; my $rst = eval $str; next				;  
			}
		} else {
			$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/; my $varName = $1; my $varValue = $2		;
			if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) {
				if ($varName =~ /\bcreate\b/i) { &createTS($varValue); }
				elsif ($varName =~ /\badd\b/i) 	{ &addTS($varValue); }
				elsif ($varName =~ /\bdelete\b/i) { &deleteTS($varValue); }
				elsif ($varName =~ /\bcheckStatus\b/i) { &checkStatusTS($varValue); }
				else {
					print "Unrecognized Testsuite Command: $varName\n"; 		
				}
			}
		}
}

sub checkStatusTS {
	print "pass a: ".shift."\n";
}
sub processTCs{
	shift;
	my $isBatchProcessing = 1;
	my $tmp = shift;
	@_ = split /;/, $tmp;
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();
		&appendtoFile($commandLogName, "\n".&UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z")."> ");
		&appendtoFile($commandLogName,"$c/$_TAF/$taf ");
	foreach my $each (@_) {
		#### uncomment for debugging   print " cmd> $each\n";
		&appendtoFile($commandLogName,$each.";");
		if ($each !~ /=/) {
			$isBatchProcessing = 0;
			if (($each =~ /\blistVars\b/i) || ($each =~ /\bgetVars\b/i)) { return &printGlobalVars();
			} elsif ($each =~ /\bprintVars\b/i) { print &printGlobalVars(); next 			;
			} elsif ($each =~ /\bexec\b/i) { 							;
				&setGlobalVars("","tcOP=exec")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blistTcFilters|printTcFilters\b/i) { 				;
				&setGlobalVars("","tcOP=listtcfilters")						;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blist\b/i) { 							;
				&setGlobalVars("","tcOP=list")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blistHistory\b/i) { 						;
				&setGlobalVars("","tcOP=listHistory")						;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\bmark\b/i) { 							;
				&setGlobalVars("","tcOP=mark")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blistAll\b/i) { 							;
			 	$SvrTCNamePattern =".*";  &listAll()						; 
				$isBatchProcessing = 0								;		
			} elsif ($each =~ /customer1/i) {
				&customer1();
			} else  {
				my $str =  "\&$each();"; 
				my $rst = eval $str; 
				if ($rst) { print "\`$each\` = \"$rst\"\n"; } else { print "\`$each\` is not a TAF command."; }
				next;  
			}
		} else {
			if ( $each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/ ) {
				$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/; my $varName = $1; my $varValue = $2		;
				if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) {
					if ($varName =~ /propertyOp/) { $isBatchProcessing = 1; } else { $isBatchProcessing = 0;} # 1 for propertyOp
					if (&setGlobalVars ("","$varName=$varValue;") == 1 ) 		{ ; }
					else {
						my $rst = &processTC("",$each) 			;
					}
				}
			} else { next; } 
		}
	if ($isBatchProcessing == 1) { $NofExecutionCtr=0;  &tcLoop();}		# NofExecutionCtr reset for each list/exec
	} 
}

################################################################################
#	Subroutine Name : process Test Case
#		Function: wrapper for Test Case management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyO/proc
################################################################################
sub processTC {
	    my $tcname; my $cmd="";
	    shift; my $tcOP= ''; $tcOP = shift if (@_); 
	    my $prMsg = '' ; $prMsg= shift if @_;
	    $tcOP =~ /\s*([\w|\d]+)\s*(=)?\s*(\w+)?\s*([;|\/])?(\s*\S+\s*)?/;  
	    $tcOP = $1; $tcname = $3; $cmd = $5; $prMsg = $pr2Screen;
		if ($cmd) {$cmd =~ s/\n//g;} else { $cmd ="";}
	    ######## This is for TCs processing (Batching)
		if ($tcOP =~ /\blistAll\b/i) {
			# SvrTCName as a regExp
			if ($tcname =~ /^\s*$/) { $SvrTCNamePattern =".*";} else { $SvrTCNamePattern = $tcname; } 
			&listAll(); 
			return; 
			}
	    ######## The following are for TC processing 	    
 	    if ((defined $tcname) && ($tcname =~ /^.$/) && ($cmd =~ /:[\\|\/]/)) {
 			$tcname = $tcname.$cmd; # handle -s delete=c:\_ts1_
 	    }
	    $tcname =  &getTCName($tcname); 
	    if (-e $tcname) { printf "%-20s %-40s ", "processTC:", $tcname   if (($outputFormat =~ /text/i) && ($pr2Screen ==1)) ; } # print for webUI 1/2
	    # printf "%-20s %-40s ", "processTC:", $tcname   if (($outputFormat =~ /text/i) && ($pr2Screen ==1)) ; # print for webUI 1/2
	    my $tmp = sprintf "%-20s %-40s\n", "processTC: ", $tcname   ;
 	    &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'."_listHistory.txt", "$tmp");
	    my $rst; 

	    if ( $tcOP =~ /^\s*create/i ) {
		    if ($cmd) { $rst = &createTC("cmd=$cmd",$tcname); }
		    else { $rst = &createTC($tcname); }
            } elsif ( $tcOP =~ /^\s*exec\b/i ) {
		    if ($NofExecutionCtr== 1 ) {$rst = &markTC_($tcname);}
		    $rst = &execTC_($tcname);
		    my $rst1 = &mapTC($tcname);
            } elsif ( $tcOP =~ /^\s*mark\b/i ) {
		    $rst = &markTC_($tcname);
            } elsif ( $tcOP =~ /^\s*execAll/i ) {
		    $rst = &tcLoop();
		        return $rst;
            } elsif ( $tcOP =~ /^\s*UpdateWeb/i ) {
		    if (defined $cmd) {;} else { $cmd = 0;}
		    $rst = &updateWeb_($tcname,$cmd);
	    } elsif ( $tcOP =~ /^\s*getWeb_/i ) {
		    $rst = &getWeb_($tcname);
            } elsif ( $tcOP =~ /^\s*log/i ) {
		    $rst = &logTC($tcname);
            } elsif ( $tcOP =~ /^\s*detect/i ) {
		    $rst = &detectTC($tcname, $SvrProjName, $SvrDrive); 
            } elsif ( $tcOP =~ /^\s*getLogName/i ) {
		    $rst = &getTCLogFname(&getTCName($tcname)); 
	    } elsif ( $tcOP =~ /^\s*listTCFilters/i ) {
		    $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest');
	    } elsif ( $tcOP =~ /^\s*printtcFilters/i ) {
		    $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest');
            } elsif ( $tcOP =~ /^\s*listHistory/i ) {
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'history');
            } elsif ( $tcOP =~ /^\s*printResult/i ) {

	    } elsif ( $tcOP =~ /^\s*list|get\b/i ) {
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'last');	   # return last valid TC result
		    my $rst1 = &mapTC($tcname);
            } elsif ( $tcOP =~ /^\s*delete/i ) {
		    $tcOP =~ s/^\s*delete\s*=//g;
		    $tcOP =~ s/\s*$//g;
		    $rst = &deleteTC($tcname);
            } else {
		    if ( -e $tcname ) {
		    print "<- Test suite \n" if $prMsg;
	    		}	
		    #print "<- Test suite \n" if $prMsg;
		return "_noProcessedTC_";
	    }
	     	printf "%s\n",  $rst  if (($outputFormat =~ /text/i)&&($pr2Screen == 1)) ; # print for webUI 2/2
 	        &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'."_listHistory.txt","$rst\n")				;
	 	$rst = sprintf "%-20s %-40s %s", "processTC:", $tcname,  $rst ;
		return $rst;
}


sub listAll { 
	find(\&recursiveSearchListAll, $SvrDrive); }
sub recursiveSearchListAll() { 
	if (($File::Find::name =~ /tc.pl/) && ($File::Find::name =~ /$SvrTCNamePattern/i))
	{	
		print "$File::Find::name\n"; 
	
	}
}

sub createTS {		# Create Testsuite for Testbed 
	my $tsName = $SvrProjName; $tsName = shift if @_;
	$SvrProjName = $tsName;
	if ($SvrProjName =~ s/_powershell_//i)  { 
		my $rst = mkpath $SvrProjName ; print " --> Create Powershell Testsuite: $SvrProjName\n";
		&generatePowershell_ps1_template($SvrProjName); 
	} else { 
		my $rst = mkpath $SvrProjName; print " --> Create Perl Testsuite: $SvrProjName\n";
		&generatePerl_pl_template($SvrProjName); 
	}
1;
}
sub addTS {
	my $tsName = "_testsuite_"; $tsName = shift if @_;
	if (-e $tsName) { print " --> Add Testsuite Hook : $tsName \n"; return 0; } 
	else { print "[Warning] Testsuite ($tsName) doesn't exist. No testsuite hook is added\n";
	return 1;}
}

sub deleteTS {
	my $tsName = "_testsuite_"; $tsName = shift if @_;
	my $rst = rmtree $tsName;
	print " --> Delete Testsuite: $tsName ($rst) \n";
	return $rst;
}
sub updateTS {goto &listTS}
sub listTS   {
	my $tsName = $SvrProjName; $tsName = shift if @_;
	$SvrProjName = $tsName;
	&processTCs ("","tcDelay=0;performanceMode=fast;testcaseNode=$testcaseNode;testsuite=$SvrProjName;AutomationtsName=$SvrProjName;list"); 
	return 1;
}

sub createTC {
	my $tc_pl="tc.pl"; my $cmd=''; $cmd = shift; 
	if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
	my $tcNameRoot = "@_"; my $sleep = 0;
	if ($cmd =~ /sleep\s*=\s*(\d+)/ ) { $sleep = $1; }
	my $tcName = &getTCName("@_");
	if( &detectTC($tcName) =~ /exists/ && ($cmd !~ /Over/i) && ( $overWriteTC =~ /n/i)) { # overwrite
		return "\n\tWarning $tcName already exist! (use -create;cmd=overwrite to overwrite)" ; } 
	else {
		mkpath($tcName);
		######################## tc.hta ##########################

	@_ = split "\/", $tcName;
	my $testsuite = $_[2]; my $testcase  = $_[3]; 
	my $now = &UnixDate(&DateCalc("now","+ 6 seconds") , "%H:%M:%S" );

	if ($testsuite) {;} else { print "[Info] \$testsuite is null. Note \$tcName = $tcName\n"; $testsuite ="";}
	if ($testcase ) {;} else { print "[Info] \$testcase  is null. Note \$tcName = $tcName\n"; $testcase = "";}

	my $tcNameIIS = $tcName; 
	if ($tcNameIIS) {;} else { print "[Info] \$tcName is null, \$tcNameIIS = $c.':/inetpub/wwwroot/'\n"; $tcNameIIS = $c.':/inetpub/wwwroot/';}
	&createFile( $tcNameIIS.'/'.'tc.hta', 
"
<html>
<head>
	<script language=\"JavaScript\">
		function RunFileHTTP(testsuite, testcase) {
//			alert(\"testsuite is \" + testsuite + \" testcase is \" + testcase );
			 WshShell = new ActiveXObject(\"WScript.Shell\");
		    	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
			 cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR \"$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec\" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
    		  	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
		}

	function sleep(milliseconds) {
	  var start = new Date().getTime();
	  for (var i = 0; i < 1e7; i++) {
	    if ((new Date().getTime() - start) > milliseconds){
	      break;
	    }
  	}
}


// <a onclick=\"RunFileHTTP(\'$testsuite\', \'$testcase\')\">Click this to run Run Program</button> <p>
	</script>
</head>
<body onLoad =\"RunFileHTTP(\'$testsuite\', \'$testcase\')\">Run $testsuite\/$testcase\/tc.hta</button> <p>
</body>
</html>
"
 			);

		######################## tc.hta ##########################

		if ($cmd =~ /Perf/i) {  					# PerformanceTC
		&createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"1234567.89\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /ExpectedFail/i) { 				# ExpectedFailedTC
		&createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"Expected_f_a_i_l\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /expF/i) { 					# ExpF for ExpectedFailedTC
		&createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"expF\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /bugF/i) { 					# ExpF for ExpectedFailedTC
		&createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"bugF\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /Fail/i) { 					# FailedTC
		&createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"fail\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /customTC/i) { 				# CustomTC
			$cmd=~ /customTC:\s*(.+)\s*:customTC/; $cmd =$1; $cmd =~ s/_space_/ /;
		if ($cmd =~ /ps1\b/) {									# Powershell plugin
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend__.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend__.txt\", \"".&getDir($cmd)."\/_tcLogAppend__.bak\");}
print `powershell -executionpolicy unrestricted -file $cmd $ps1_args`;  # custom TC tc.pl 
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$tcName\/_tcLogAppend__.txt\");}
"
			);
			###########
			} elsif (($cmd =~ /pyanvil/i) &&( $tc_pl =~ /index_pyAnvil\.pl/i)) { 		# pyAnvil plugin
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend__.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend__.txt\", \"".&getDir($cmd)."\/_tcLogAppend__.bak\");}
print `$cmd $ps1_args`; 	# tc.pl
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$tcName\/_tcLogAppend__.txt\");}
#if (-e \"".&getDir($cmd)."\/_tcLogAppend__.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend__.txt\", \"$tcName\/_tcLogAppend__.txt\");}
"
			);
			###########
			#} elsif  ($cmd =~ /\S+\.pl\s*/) { 						# perl plugin 
			} elsif  ($cmd =~ /\S+\.pl\b/) { 						# perl plugin 
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend__.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend__.txt\", \"".&getDir($cmd)."\/_tcLogAppend__.bak\");}
print `$perl_ $cmd`;  # $c/$_TAF/index.pl
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$tcName\/_tcLogAppend__.txt\");}
#if (-e \"".&getDir($cmd)."\/_tcLogAppend__.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend__.txt\", \"$tcName\/_tcLogAppend__.txt\");}
"
			);
			###########
			} elsif ( $cmd =~ /taftestcase1/) {
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
\$| = 1; 
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`;
if ( \$rst =~ /propertyValue1/) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase2/) {
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
\$| = 1; 
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1A_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`;
if ( \$rst =~ /propertyValue1A/) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase3/) {
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
\$| = 1; 
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property2`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=get_property2`;
if (( \$rst =~ /testcase1/) && (\$rst =~ /testcase2/) && (\$rst =~ /property2\\s*=\\s*propertyValue2/)) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase4/) {
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
\$| = 1; 

\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue1_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2A_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property1_as_propertyValue1A_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;printTcFilters`;
if (( \$rst =~ /property1\\s+propertyValue1A/) && (\$rst =~ /property2\\s+propertyValue2A/))  { print \"pass\\n\";} else {print \"fail\\n\";}

\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
\$rst = `$c/$_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property2_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /powershellTC/) {
			###########
			&createFile( $tcName.'/'.$tc_pl, 
"
"
			);
			###########
				;
			} else {
				;
			}
		} else {
			 &createFile( $tcName.'/'.$tc_pl, "\$| = 1; print \"pass\\n\"; sleep $sleep; ");
		}
        	&createPropertyTemplate($tcName);

		my $tmp =<<EOF;
open Fout, '>$tcName/_tcLogAppend.txt';
print Fout "* This is the content of TC log file\\n";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/_blabla.html\\" >File Archieve</a> _url_line_ \\n";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/_testsuite2_/testcase0002/_tcLog.html\\" >Another TC's Log _url_line_ </a>\\n ";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/index.htm\\" >TAF</a> _url_line_ \\n";
print Fout "* TC Log can has special characters like Dollor \\\$, Percentage \\\% AT \\\@ \\n";
print Fout "* TC Log can URL http://localhost:8080   _ url_line_line	_url_line_	\\n";
print Fout "* TC Log can handle log in log c:/_TAF/_testLog.txt . This is the end of the testcase\\n";
close Fout;
exit;
EOF
		if (($cmd =~ /genLog/i) || ($cmd =~ /addLog/i)) {&appendtoFile( $tcName.'/'.$tc_pl, $tmp) ; undef $tmp; }
	$tcName =~ s/\\\\/\\/g; # todo \\

	return "is created";
	}
}


sub execTC {
	my $tcName = &getTCName(@_); my $timeStart = &getDate(); my $rst=''			; 
	if  ( -e "$tcName/tc.pl" ) {
		my $cmd     = "$tcName/tc.pl"; $rst     = `$cmd`; my $timeEnd= &getDate()	; 
	       $rst =~ /(pass|fail|bugF|expF|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";} 
	       if (($rst =~ /Expected_f_a_i_l/i) || ($rst =~ /null/i)) { sleep 10; }
	       $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart		;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } 
	       else { $rstStr .= "Functional Test ($rst) "; } 
	       $rstStr .= '|comment2'; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       } else {
	       return "tcName: $tcName doesn't exist.\n";
       }
}

sub dumyTC_ {	# create a dumy tc result 
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst = "dump"; 
		my $timeEnd= &getDate(); 
	       $rst = "dumy";
	       if ($rst) {;} else {$rst = "null";}
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       $rstStr .= "Functional Test ($rst) ";
	       $rstStr .= '|'.$tcComment2; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       } else {
		return "tcName: $tcName doesn't exist.\n";
       }
}


sub markTC_ {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst = "mark"; # $rst     = `$cmd`; 
		my $timeEnd= &getDate(); 
	       $rst =~ /(mark|pass|fail|bugF|expF|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";}
	       $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) {
		$rstStr .= "Performance Test ($rst) ";
	       } else {
	       $rstStr .= "Functional Test ($rst) ";
	       } 
	       $rstStr .= '|'.$tcComment2; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       } else {
		return "tcName: $tcName doesn't exist.\n";
       }
}


sub execTC_ {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst     = `$cmd`; my $timeEnd= &getDate(); 

	       	$rst =~ /(pass|fail|todo|bugF|expF|expected_f_a_i_l|task|[\d|.]+)$/i; $rst = $1; 

	       	if ($rst) { if ($rst =~ /expected_f_a_i_l/) { $rst = "expF"; } ;} else {$rst = "null";}

	       	$rst =~ s/^\s*0+//g;

	       	my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart; $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; 

	       	if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } elsif ( $rst =~ /task/i ) { $rstStr .= "Task "; } else { $rstStr .= "Functional Test ($rst) "; } 
	       	$rstStr .= '|comment2PlaceHolder'; 
	       	&addProperty(&getTCName($tcName), "add=$rstStr");
	       	return $rst;
       } else {
		return "tcName: $tcName doesn't exist.\n";
       }
}

sub mapTC {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
	       if (-e "$c/$_TAF/$SvrProjName/_tcMap.txt") {
		       my $tcName_ = &getTCName($tcName); $tcName_ =~ s/$c\/$_TAF\///i;
			&mergethProperty($tcName_,"$c/$_TAF/$SvrProjName/_tcMap.txt");
		       }
	        return $rst;
       } else {
		return "tcName: $tcName doesn't exist.\n";
       }
}

sub mergethProperty {
my $thPropertyString ="_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/testcase0002"; $thPropertyString= shift if @_; 
my $tcMapFName = "_tcMap.txt"; $tcMapFName = shift if @_;
my $propertyName = "tcRunResult";my  %records; my %record_out; my $tag = "tag"; my $content_out=""; my $parent=""; my $child;
open Fin, $tcMapFName;
 	while ($_=<Fin>) { chop;
  		if ($_ =~ /$thPropertyString/) { 
			my $thPropertyFName;
			$content_out = "";
			 ($parent, $child) = split (/\s*=>\s*/, $_);
			if (($parent !~ /^\s*$/) && ($child !~ /^\s*$/)) {	
			$thPropertyFName=$parent."/thProperty.txt"; if ($thPropertyFName !~ /$c\/$_TAF/) {$thPropertyFName =~ s/$c/$c\/$_TAF/;} # TS->TAF TS conversion 
			open Fin1, $thPropertyFName or die "Can't open $thPropertyFName:$!";  
			while ($_ = <Fin1>) { 
				if ($_ =~ /$tags/) { $tag=$1;}	# todo
				if ($_ =~ /^\s*$propertyName\s*\|/) { @_ = split (/\|/, $_); $records{$_[2]}=$_; } 
				else { $content_out = $content_out.$_; }
			} 
			close Fin1;
			$thPropertyFName=$child."/thProperty.txt";    if ($thPropertyFName !~ /$c\/$_TAF/){ $thPropertyFName =~ s/$c/$c\/$_TAF/;} # TS->TAF TS conversion 
			if ( -e $thPropertyFName ) { ; } else { return ;} 
			open Fin1, "$thPropertyFName" or die "Can't open $thPropertyFName:$!";  
			while ($_ = <Fin1>) { 
				if ($_ =~ /$tags/i) { $tag=$1;}	# todo
				if ($_ =~ /^\s*$propertyName\s*\|/) { $_ =~ s/Comment2\s*$/$tag/i; @_ = split (/\|/, $_); $records{$_[2]}=$_; 
				} 
			} 
			close Fin1;
			}
		}
 	} 
close Fin;
	if (-e $parent) {
		open Fout1, ">$parent/thProperty.txt_"; 
		print Fout1 $content_out; 
		foreach my $each (sort keys %records) { print Fout1 "$records{$each}\n"; } 
		close Fout1;
		#### print "\n\t-> $parent/thProperty.txt_ (needs to use copyFile)";
		&copyFile("$parent/thProperty.txt_", "$parent/thProperty.txt");
	}

}
sub deleteTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = &getTCName(@_);
#### 	todo	backup deleted TCs. move ($tcName, $tcName."_".  &UnixDate( "now", "%m_%d_%Y_%H_%M_%S_%Z" ) ."_backup");
	rmtree $tcName;
	return "$tcName is deleted (saved as *_backup)";
}

sub detectTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = '';
	$tcName = &getTCName(@_);
     	if (-e "$tcName/tc.pl" ) { return  "exists"; } else { return 'does not exist';}
}

sub getTSName {
	my $tsname = shift;
	$tsname =~ s/\/testcase\d+.+//g;
	return $tsname;
}

sub getTCName {
	my $SvrProjNameTmp; my $SvrDriveTmp; my $SvrTCNameTmp="" ;  
	$SvrTCNameTmp = shift if @_; 
	if ($notUsegetTCName==1) 	{ return   $SvrTCName;				}	# Do nothing
	if ($SvrTCNameTmp) 		{;} else { $SvrTCNameTmp = $SvrTCName; 		}  	# get current SvrTCName 
	if ($SvrProjNameTmp) 		{;} else { $SvrProjNameTmp = $SvrProjName;	}  	# do nothing
	if ($SvrDriveTmp) 		{;} else { $SvrDriveTmp = $SvrDrive;		}  	# do nothing
	if ($SvrTCNameTmp =~ /[a-z]:/i) { return   $SvrTCNameTmp;			}	# remove c:
	else { return ($SvrDriveTmp.'/'.$SvrProjNameTmp.'/'.$SvrTCNameTmp) ; 		}	# c:/testcase/testsuite
}

sub getTCNameStr{
	my $SvrTCNameStr = shift;
	@_ = split /\\|\//, $SvrTCNameStr; 
	pop;
}

################################################################################
#	Subroutine Name : processProperty
#		Function: wrapper for property management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyOp
################################################################################
sub processProperty {
	shift; my $tcname = shift; my $propertyOP = shift; my $rst=""; my $prMsg=0;
	#### PropertyOp String Translation
	$propertyOP =~ s/^\s*propertyOp\s*=//g; $propertyOP =~ s/^\s*po\s*=//g; $propertyOP =~ s/_doit_//g;
	if ($propertyOP =~ /^\s*_?modify_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; }
	if ($propertyOP =~ /^\s*_?set_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; }
	elsif ($propertyOP =~ /^\s*_?get_history(.+)/)  { $propertyOP = "get_history$1"; }
	elsif ($propertyOP =~ /^\s*_?list_history(.+)/) { $propertyOP = "get_history$1"; }

	elsif ($propertyOP =~ /^\s*_?get_latest(.+)/)  { $propertyOP = "get_latest$1"; }
	elsif ($propertyOP =~ /^\s*_?list_latest(.+)/) { $propertyOP = "get_latest$1"; }

	elsif ($propertyOP =~ /^\s*_?get_last(.+)/)  { $propertyOP = "get_last$1"; }
	elsif ($propertyOP =~ /^\s*_?list_last(.+)/) { $propertyOP = "get_last$1"; }

	elsif ($propertyOP =~ /^\s*_?get_(.+)/) { $propertyOP = "get_$1"; }
	elsif ($propertyOP =~ /^\s*_?list_(.+)/) { $propertyOP = "get_$1"; }
	#### PropertyOp String Translation
	if (defined $propertyOP) {;} else { $rst = "Warning: wrong format. Correct format is -add=prop:value"; return $rst; }
	if ($propertyOP =~ /;\s*pr2Screen\s*/) { $prMsg = 1; $propertyOP =~ s/;\s*pr2Screen\s*(=\s*\d*\s*)?//; }
	if ( $propertyOP =~ /^\s*add/i ) {
                $rst = &addProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*del/i ) {
                $rst = &deleteProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*reset/i ) {
                ;
        }    # copy to a backup and create a property file
        elsif ( $propertyOP =~ /^\s*modify/i ) {
                $rst = &modifyProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*get_history|list_history_/i ) {
		$propertyOP =~ s/^\s*get_history_+\s*//g; $propertyOP =~ s/^\s*list_history_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "history" );
 	}
        elsif ( $propertyOP =~ /^\s*get_latest|list_latest/i ) {
		$propertyOP =~ s/^\s*get_latest_+\s*//g; $propertyOP =~ s/^\s*list_latest_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "latest" );
 	}
        elsif ( $propertyOP =~ /^\s*get_last|list_last/i ) {
		$propertyOP =~ s/^\s*get_last_+\s*//g; $propertyOP =~ s/^\s*list_last_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "last" );
 	}
        elsif ( $propertyOP =~ /^\s*get|list/i ) {
		    $propertyOP =~ s/^\s*get_\s*//g; $propertyOP =~ s/^\s*list_\s*//g;
		if ($propertyOP =~ /;/ ) {
		    @_ = split /;/, $propertyOP ;
		    $rst = &getProperties(&getTCName($tcname), $_[0], $_[1]);
	    	} else {
		    $rst = &getProperties(&getTCName($tcname), $propertyOP, "value" );
		}
       }
       elsif ( $propertyOP =~ /^\s*create/i ) {
        	$rst = &createPropertyTemplate($tcname);
       }
       elsif ( $propertyOP =~ /^\s*match|filter/i ) {
		if ($propertyOP =~ s/^\s*match\s*_//g) {
		    $propertyOP =~ /\s*(\S+)\s*_(as|eq)_\s*(\S+)\s*/; 
        	    $rst = &matchProperty($1, $3, $tcname);
	    }
       } else {
	    	    $rst = sprintf "ProcessProperty (no match OP) %40s %20s", $tcname, $propertyOP;
       }
	    if (($rst) && ($rst =~ /^\s*$/)) { $rst = "_noMatchedPropertyOP_";}
	    if ((defined $prMsg) && ($prMsg ==1)) { print  $rst;}
	    if ($rst) { return $rst; } else { return "doen't exist"; }
}

################################################################################
#	Subroutine Name : matchProperties
#		Function: return true/false 
#	Input Parameters: Property Name in regExp  
#	Output/Returns  : True/False
################################################################################
sub matchProperty { # &matchProperty("QAOwner","ywang", "TC_tc1");
	my $propertyName = ".*"; my $propertyPattern = ".*"; my %array; my $tcname = "TC_tc1";
	$propertyName = shift if (@_);
	$propertyPattern= shift if (@_);
	$tcname = shift if (@_);

	 if (&getProperties(&getTCName($tcname), "" ) =~ /info:There is no/ ) {
		 return "False";
	 }

	foreach my $each (split /\n/,  &getProperties(&getTCName($tcname), "", "_all_")) {
		$each =~ /^\s*(\w+)\s+(\w+)\s*$/;
		$array {$1}  = $2;
	}
	foreach my $each (sort keys %array) {
		if (($array{$each} =~ /$propertyPattern/) && ( $each =~ /$propertyName/)) { 
			 return "True\n$each:$array{$each}"; }
	}
	return 'False';
}

################################################################################
#	Subroutine Name : getProperties
#		Function: return Test Case Property
#	Input Parameters: Property Name (regExp)  (tcName, tcPattern, value)
#	Output/Returns  : Property Value
################################################################################
sub getProperties() { 	# get TC Property Names	(TH:TC Managements)
	    	my %array; my $returnValue;
		my $tcname 		; $tcname 		= shift if @_ ;
		my $propertyOp		; $propertyOp  		= shift if @_ ;
		my $returnType= 'latest'; $returnType 		= shift if @_ ;

    		if ($propertyOp =~ s/^\s*add\s*=\s*//ig) {;}
		elsif ($propertyOp =~ s/^\s*_eq_\s*//g) {;}
		elsif ($propertyOp =~ s/\s*_eq_\s*/=/g) {;}
		elsif ($propertyOp =~ s/_column_/:/g) {;}

		if ($propertyOp =~ /_all_/) { $returnType = "_all_"; $propertyOp =~ s/_all_//g; }

		# if ( -e  "$tcname/thProperty.txt" ) { ; } else { return "info:There is no $_[0]/thProperty.txt here";}
    if ( -e  "$tcname/thProperty.txt" ) { ; } else { return "info:There is no $tcname/thProperty.txt here";}
    open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!";
    while ( $_ = <Fin> ) {
	    @_= split /\|/, $_;

	    my $propertyName_ = $_[0]; my $propertyValue_ = $_[1]; $propertyName_ =~ s/^\s*//g; $propertyName_ =~ s/\s*$//g; my $propertyStartTime = $_[2];
	    if (($propertyName_ !~ /^\s*$/) && ( $propertyValue_ !~ /^\s*$/)) {   

 	      	if (($propertyName_ =~ /$propertyOp/i) || ( $propertyOp eq '')) { # PropertyPattern Filter
		   	if ($returnType =~ /^\s*$/) { $returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; 
			} elsif ($returnType =~ /values/i) { 
				$returnValue .= sprintf "%s\n", $propertyValue_;
			} elsif ($returnType =~ /_all_/i) { 
				$propertyValue_ =~ s/^\s*//g;
				$propertyValue_ =~ s/\s*$//g;
				$returnValue = sprintf "\t%s\n", $propertyValue_;
			} elsif ($returnType =~ /history/i) { 
				$returnValue .= sprintf "%-20s=%s \@ $propertyStartTime\n",$propertyName_, $propertyValue_;
			} elsif ($returnType =~ /\blatest\b/i) {
				$returnValue = "$propertyValue_\n";
			} elsif ($returnType =~ /\blast\b/i) {
				if ($propertyValue_ !~ /dumy/) { $returnValue = "$propertyValue_\n"; }
			} elsif ($returnType =~ /\bvalue\b/i) {
				$returnValue = sprintf "%s\n", $propertyValue_;
		   	}
		}
		$array{$propertyName_} = $returnValue;
	}
    }
    close Fin;
	$returnValue = "\n";
	if ($returnType =~ /_all_/i) {
		foreach my $each (sort keys %array) { 
			$returnValue .= sprintf "%20s%s", $each, $array{$each}; }
		return $returnValue;
	} else {
		$returnValue =  $array{$propertyOp} ; 
		if ($returnValue ) { $returnValue =~ s/\s*\n\s*$//g; if ($returnValue =~ /^\s*$/) { $returnValue = "_noMatch_";} ; return $returnValue; }
		else { return ""; }
    	}
}

################################################################################
#	Subroutine Name : modfyProperty
#		Function: modify Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
#	Subroutine Name : 
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub modifyProperty() { 	# modify TC Property (TH:TC Managements)
    my $tcname       = $_[0];
    my $propertyName = $_[1];
    my $propertyValue       ; 
    if ($propertyName =~ s/^\s*modify\s*_\s*//g) {
    $propertyName =~ /(\w+)\s*_as_\s*(\w+)\s*/;
    $propertyName = $1; $propertyValue = $2;
    }
    my $cmdStr        = "delete=$propertyName";
    &deleteProperty( $tcname, $cmdStr );
    $cmdStr = "add_${propertyName}_column_${propertyValue}"; # todo
    &addProperty( $tcname, $cmdStr );
    return "$propertyName is modified to $propertyValue for $tcname";
}

################################################################################
#	Subroutine Name : deleteProperty
#		Function: delete Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : update c:\TC_*\thProperty.txt
################################################################################
sub deleteProperty() {	# delete TC Property	(TH:TC Managements)
    my $fname = "$_[0]/thProperty.txt";
    my $fout  = $fname; $fout =~ s/\.txt/_Dumpster\.txt/;

    my $propertyName = $_[1]; 
    if ($propertyName !~ /\s*del\S*\s*_\s*/) { return "Warning: wrong format  -del=prop1;pr2Screen";} else {
    $propertyName =~ s/^\s*del\S*\s*_\s*//g; $propertyName =~ s/:\s*\S*//; }
    my %array ;
    open Fin, "$fname"; @_ = <Fin>; close Fin;

    open Fout, ">>$fout";
    foreach my $each (@_) {
        if ( $each =~ /^\s*$propertyName\s*\|/i ) { print Fout "$each"; }
    }
    close Fout;

    open Fout, ">${fname}" || die "Can't open $fname:$!";
    foreach my $each (@_) {
        if ( $each !~ /^\s*$propertyName\s*\|/i ) {
            print Fout "$each";
        }
    }
    close Fout;
    return "$propertyName is deleted from $fname";
}

################################################################################
#	Subroutine Name : createPropertyTemplate
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub createPropertyTemplate() { 	# create TC Property File (TH:TC Managements)
    my $timeStr = getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|Comment1|Comment2";
    my $tcDesc = "@_"; 
    my $fname = "@_/thProperty.txt";
    if (-e $fname) { open Fout, ">>$fname"; } else { open Fout, ">$fname";} 
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcDesc',$tcDesc,$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSCR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'QA','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'modolID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'priority','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'openSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcOwner','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'resultN','null',$timeStr;
    close Fout;
}

################################################################################
#	Subroutine Name : addProperty
#		Function: add Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
################################################################################
sub addProperty() { 	# add TC Property (TH:TC Managements)
    my $timeStr = &getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|comment1|comment2";
    my $fname        = "$_[0]/thProperty.txt";
    my $propertyName = $_[1];
    $propertyName =~ s/^\s*add\s*=//g;
    $propertyName =~ s/^\s*add\s*_eq_\s*//g;
    open Fout, ">>$fname";
    	if ($propertyName =~ /\|/) { # for tcRunResult 
		$propertyName =~ /^\s*(\S+)\s*\|\s*(\S+)\s*\|(.+)\s*$/; 
		my $propName = $1		;
		my $propValue = $2		;
		my $propComment = $3		;
		$propValue =~ s/_space_/ /g	;
		$propValue =~ s/_eq_/=/g	;
		$propValue =~ s/_column_/:/g	;
        	printf Fout "%20s|%10s|%s\n",$propName, $propValue,$propComment;
	} else {
		$propertyName =~ /^\s*(\S+)_column_(\S+)\s*/; 
		my $propName = $1		;
		my $propValue = $2		;
		$propName = &match1stRegexp($propertyName, "_column_");
		$propValue= &matchRestRegexp($propertyName, "_column_");
		if ($propName && $propValue) {
		$propValue =~ s/_column_/:/g	;
		$propValue =~ s/_space_/ /g	;
		$propValue =~ s/_eq_/=/g	;
		$propValue =~ s/___/ /g		;
		$propName =~ s/^\s*add\s*=//g	;
		$propName =~ s/_space_/ /g	;
        	printf Fout "%20s|%10s%s\n",$propName, $propValue,$timeStr;
		}
	}
    close Fout;
    return "$propertyName is added to $fname";
}

sub printGlobalVars {
my $return=<<EOF;
##################### Frequently Used Setting ####################
web_ui_title                  =$web_ui_title                  
tags                          =$tags                          
ps1_args                      =$ps1_args                      
Execution_24_7                =$Execution_24_7                
Execution_24_7_title          =$Execution_24_7_title
Execution_local_only          =$Execution_local_only 
outputFromat                  =$outputFormat  (text,noOutput -todo ,html-todo)
htmlRefreshRate               =$htmlRefreshRate
htmlRefreshRateWebUI          =$htmlRefreshRateWebUI
htmlRefreshRateLogUI          =$htmlRefreshRateLogUI
##################### WebUI Setting           ####################
excelReportColumnWidth        =$excelReportColumnWidth        
pr2Screen                     =$pr2Screen                     
webUI_TCDescWidth             =$webUI_TCDescWidth             
scrollAmount                  =$scrollAmount                  
borderWidth                   =$borderWidth                   
borderStyle                   =$borderStyle                   
passFailDisplayWidth          =$passFailDisplayWidth          
maxPassFailDisplayWidth       =$maxPassFailDisplayWidth       
tsPropertyWidth               =$tsPropertyWidth               
##################### TAF  Default  Settings   ####################
ip                            =$ip                             
c                             =$c                             
taf                           =$taf                           
_TAF                          =$_TAF                          
overWriteTC                   =$overWriteTC
reportHtmlSummaryScale        =$reportHtmlSummaryScale        
reportHtmlSummaryScaleMajor   =$reportHtmlSummaryScaleMajor   
testcaseNode                  =$testcaseNode
NofExecution                  =$NofExecution                  
ExecutionLength               =$ExecutionLength               
tsFilter                      =$tsFilter                      
tcComment1                    =$tcComment1                    
tcComment2                    =$tcComment2                    
MaxTCExecTime                 =$MaxTCExecTime                 
TSHookName                    =$TSHookName                    
TSHookNameGenerated           =$TSHookNameGenerated           
TSHookIsPerl                  =$TSHookIsPerl                  
interact                      =$interact                      
tcPropertyPatternName         =$tcPropertyPatternName         
tcPropertyPatternPattern      =$tcPropertyPatternPattern      
tcPropertyPatternName1        =$tcPropertyPatternName1        
tcPropertyPatternPattern1     =$tcPropertyPatternPattern1     
tcPropertyPatternName2        =$tcPropertyPatternName2        
tcPropertyPatternPattern2     =$tcPropertyPatternPattern2     
tcPropertyPatternName3        =$tcPropertyPatternName3        
tcPropertyPatternPattern3     =$tcPropertyPatternPattern3     
tcPropertyName                =$tcPropertyName                
tcNamePattern                 =$tcNamePattern                 
tcOp                          =$tcOp                          
tcCtr                         =$tcCtr                         
tcDelta                       =$tcDelta                       
markSymbol                    =$markSymbol                    
tsFilterDefault               =$tsFilterDefault               
tcFilterDefault               =$tcFilterDefault               
SvrDrive                      =$SvrDrive                      
SvrProjName_ignore            =$SvrProjName                   
SvrTCName_ignore  	      =$SvrTCName                     
SvrTCNamePattern              =$SvrTCNamePattern              
SvrPropNamePattern            =$SvrPropNamePattern            
SvrPropValuePattern           =$SvrPropValuePattern           
SvrTCNameExecPattern          =$SvrTCNameExecPattern          
exitTAFGracefullyLock         =$exitTAFGracefullyLock         
performanceMode               =$performanceMode               
resetTSFileName               =$resetTSFileName               
externalLogName               =$externalLogName               
commandLogName                =$commandLogName                
commandLogLifeSpan            =$commandLogLifeSpan            
testType                      =$testType                      
AutomationtsName              =$AutomationtsName              
tsProperty                    =$tsProperty                    
sleep4Display		      =$sleep4Display
createOrAppendTS	      =$createOrAppendTS
EOF
}
################
 

sub printTSGlobalVars {
my $return=<<EOF;
##################### Frequently Used Setting ####################
Execution_24_7                =$Execution_24_7                
Execution_24_7_title          =$Execution_24_7_title
Execution_local_only          =$Execution_local_only 
htmlRefreshRate               =$htmlRefreshRate
htmlRefreshRateWebUI          =$htmlRefreshRateWebUI
htmlRefreshRateLogUI          =$htmlRefreshRateLogUI
##################### WebUI Setting           ####################
EOF
}

sub printTCGlobalVars {
my $return=<<EOF;
##################### Frequently Used Setting ####################
Execution_24_7                =$Execution_24_7                
Execution_24_7_title          =$Execution_24_7_title
Execution_local_only          =$Execution_local_only 
htmlRefreshRate               =$htmlRefreshRate
htmlRefreshRateWebUI          =$htmlRefreshRateWebUI
htmlRefreshRateLogUI          =$htmlRefreshRateLogUI
##################### WebUI Setting           ####################
EOF
}



###############

# sub readTAFTCVars     { open Fin, "$c/$_TAF/$SvrProjName/$SvrTCName/_tafGlobalVars.txt"		; while (<Fin>) { chop; if ($_ =~ /(.+)=(.+)/ ) { &readTAFGlobalVars1($1, $2); } }; close Fin; }
sub readTAFTCVars     { open Fin, "$SvrTCName/_tafGlobalVars.txt"		; while (<Fin>) { chop; if ($_ =~ /(.+)=(.+)/ ) { &readTAFGlobalVars1($1, $2); } }; close Fin; }
sub readTAFTSVars     { open Fin, "$c/$_TAF/$SvrProjName/_tafGlobalVars.txt"			; while (<Fin>) { chop; if ($_ =~ /(.+)=(.+)/ ) { &readTAFGlobalVars1($1, $2); } }; close Fin; }
sub readTAFGlobalVars { open Fin, "$c/$_TAF/_tafGlobalVars.txt"					; while (<Fin>) { chop; if ($_ =~ /(.+)=(.+)/ ) { &readTAFGlobalVars1($1, $2); } } close Fin; }
sub readTAFGlobalVars1 {
	my $varName  = shift;
	my $varValue = shift;
	$varName  =~ s/^\s*//g; $varName  =~ s/\s*$//g;
	$varValue =~ s/^\s*//g; $varValue=~ s/\s*$//g;
if ($varName eq "web_ui_title"                ) { $web_ui_title                   = $varValue; }
if ($varName eq "tags"                        ) { $tags                           = $varValue; }
if ($varName eq "ps1_args"                    ) { $ps1_args                       = $varValue; }
if ($varName eq "excelReportColumnWidth"      ) { $excelReportColumnWidth         = $varValue; }
if ($varName eq "testcaseNode"                ) { $testcaseNode                   = $varValue; }
if ($varName eq "pr2Screen"                   ) { $pr2Screen                      = $varValue; }
if ($varName eq "webUI_TCDescWidth"           ) { $webUI_TCDescWidth              = $varValue; }
if ($varName eq "scrollAmount"                ) { $scrollAmount                   = $varValue; }
if ($varName eq "borderWidth"                 ) { $borderWidth                    = $varValue; }
if ($varName eq "borderStyle"                 ) { $borderStyle                    = $varValue; }
if ($varName eq "passFailDisplayWidth"        ) { $passFailDisplayWidth           = $varValue; }
if ($varName eq "maxPassFailDisplayWidth"     ) { $maxPassFailDisplayWidth        = $varValue; }
if ($varName eq "reportHtmlSummaryScale"      ) { $reportHtmlSummaryScale         = $varValue; }
if ($varName eq "reportHtmlSummaryScaleMajor" ) { $reportHtmlSummaryScaleMajor    = $varValue; }
if ($varName eq "tsPropertyWidth"             ) { $tsPropertyWidth                = $varValue; }
if ($varName eq "c"                           ) { $c                              = $varValue; }
if ($varName eq "taf"                         ) { $taf                            = $varValue; }
if ($varName eq "_TAF"                        ) { $_TAF                           = $varValue; }
if ($varName eq "Execution_24_7"              ) { $Execution_24_7                 = $varValue; }
if ($varName eq "Execution_24_7_title"        ) { $Execution_24_7_title           = $varValue; }
if ($varName eq "Execution_local_only"        ) { $Execution_local_only           = $varValue; }
if ($varName eq "Execution_from_cgi"          ) { $Execution_from_cgi             = $varValue; }
if ($varName eq "NofExecution"                ) { $NofExecution                   = $varValue; }
if ($varName eq "ExecutionLength"             ) { $ExecutionLength                = $varValue; }
if ($varName eq "tsFilter"                    ) { $tsFilter                       = $varValue; }
if ($varName eq "tcComment1"                  ) { $tcComment1                     = $varValue; }
if ($varName eq "tcComment2"                  ) { $tcComment2                     = $varValue; }
if ($varName eq "MaxTCExecTime"               ) { $MaxTCExecTime                  = $varValue; }
if ($varName eq "TSHookName"                  ) { $TSHookName                     = $varValue; }
if ($varName eq "TSHookNameGenerated"         ) { $TSHookNameGenerated            = $varValue; }
if ($varName eq "interact"                    ) { $interact                       = $varValue; }
if ($varName eq "tcPropertyPatternName"       ) { $tcPropertyPatternName          = $varValue; }
if ($varName eq "tcPropertyPatternPattern"    ) { $tcPropertyPatternPattern       = $varValue; }
if ($varName eq "tcPropertyPatternName1"      ) { $tcPropertyPatternName1         = $varValue; }
if ($varName eq "tcPropertyPatternPattern1"   ) { $tcPropertyPatternPattern1      = $varValue; }
if ($varName eq "tcPropertyPatternName2"      ) { $tcPropertyPatternName2         = $varValue; }
if ($varName eq "tcPropertyPatternPattern2"   ) { $tcPropertyPatternPattern2      = $varValue; }
if ($varName eq "tcPropertyPatternName3"      ) { $tcPropertyPatternName3         = $varValue; }
if ($varName eq "tcPropertyPatternPattern3"   ) { $tcPropertyPatternPattern3      = $varValue; }
if ($varName eq "tcPropertyName"              ) { $tcPropertyName                 = $varValue; }
if ($varName eq "tcNamePattern"               ) { $tcNamePattern                  = $varValue; }
if ($varName eq "tcOp"                        ) { $tcOp                           = $varValue; }
if ($varName eq "tcCtr"                       ) { $tcCtr                          = $varValue; }
if ($varName eq "tcDelta"                     ) { $tcDelta                        = $varValue; }
if ($varName eq "markSymbol"                  ) { $markSymbol                     = $varValue; }
if ($varName eq "tsFilterDefault"             ) { $tsFilterDefault                = $varValue; }
if ($varName eq "tcFilterDefault"             ) { $tcFilterDefault                = $varValue; }
if ($varName eq "SvrDrive"                    ) { $SvrDrive                       = $varValue; }
if ($varName eq "SvrProjName"                 ) { $SvrProjName                    = $varValue; }
if ($varName eq "SvrTCName"                   ) { $SvrTCName                      = $varValue; }
if ($varName eq "SvrTCNamePattern"            ) { $SvrTCNamePattern               = $varValue; }
if ($varName eq "SvrPropNamePattern"          ) { $SvrPropNamePattern             = $varValue; }
if ($varName eq "SvrPropValuePattern"         ) { $SvrPropValuePattern            = $varValue; }
if ($varName eq "SvrTCNameExecPattern"        ) { $SvrTCNameExecPattern           = $varValue; }
if ($varName eq "exitTAFGracefullyLock"       ) { $exitTAFGracefullyLock          = $varValue; }
if ($varName eq "performanceMode"             ) { $performanceMode                = $varValue; }
if ($varName eq "tsFrom"                      ) { $tsFrom                         = $varValue; }
if ($varName eq "tsTo"                        ) { $tsTo                           = $varValue; }
if ($varName eq "resetTSFileName"             ) { $resetTSFileName                = $varValue; }
if ($varName eq "externalLogName"             ) { $externalLogName                = $varValue; }
if ($varName eq "commandLogName"              ) { $commandLogName                 = $varValue; }
if ($varName eq "commandLogLifeSpan"          ) { $commandLogLifeSpan             = $varValue; }
if ($varName eq "testType"                    ) { $testType                       = $varValue; }
if ($varName eq "AutomationtsName"            ) { $AutomationtsName               = $varValue; }
if ($varName eq "tsProperty"                  ) { $tsProperty                     = $varValue; }
if ($varName eq "TsHookIsPerl"                ) { $TSHookIsPerl                   = $varValue; }
if ($varName eq "createOrAppendTS"            ) { $createOrAppendTS               = $varValue; }
if ($varName eq "testcaseNode"                ) { $testcaseNode                   = $varValue; 
# &updateTAFGlobalVars(); 
if ($testcaseNode =~ /_null_/) { $testcaseNode = "";} 
}
}

sub getGlobalVars_old { 
	my $return = <<EOF;
	\$ip        		= $ip
	\$c        		= $c
	\$_TAF        		= $_TAF
	\$SvrDrive 		= $SvrDrive
	\$SvrProjName 		= $SvrProjName
 	\$SvrTCName 		= $SvrTCName
 	\$SvrTCNamePattern 	= $SvrTCNamePattern
 	\$SvrTCNameExecPattern	= $SvrTCNameExecPattern
	\$tcOp			= $tcOp
	\$SvrPropNamePattern 	= $SvrPropNamePattern
	\$SvrPropValuePattern 	= $SvrPropValuePattern
	\$pr2Screen           	= $pr2Screen            
	\$tc_pl               	= $tc_pl
	\$tsDriver            	= $tsDriver
	\$web_ui_title        	= $web_ui_title
	\$workingDir          	= $workingDir		
	\$tcIdMin             	= $tcIdMin   
	\$tcPropertyPatternPattern     = $tcPropertyPatternPattern
	\$tcPropertyPatternName = $tcPropertyPatternName
	\$ps1_args              = $ps1_args
	\$sleep4Display         = $sleep4Display
	\$Execution_24_7	= $Execution_24_7
	\$NofExecution		= $NofExecution
	\$ExecutionLength 	= $ExecutionLength
	\$ExecutionType   	= $ExecutionType   
	\$performanceMode 	= $performanceMode
	\$testcaseNode    	= $testcaseNode
	\$testType        	= $testType
	\$tsTo            	= $tsTo         
	\$tsFrom          	= $tsFrom
	\$sleep4Display 	= $sleep4Display
	\$makeMark      	= $makeMark
	\$externalLogName	= $externalLogName
	\$tags			= $tags
	
EOF
	return $return;
} 
sub setGlobalVars {
	shift;
	@_ = split /;/, shift;
	my $foundMatch = 0;
	foreach my $each (@_) {
		$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/;
		my $varName = $1; my $varValue = $2;
		if ($varName =~ /SysDrive/i) 			{ $SvrDrive = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrDrive/i) 			{ $SvrDrive = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrProjName/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCName\b/i) 		{ $SvrTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCNamePattern\b/i) 	{ $SvrTCNamePattern = $varValue; $SvrTCNameExecPattern = $SvrTCNamePattern; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCNameExecPattern/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrPropNamePattern\b/i) 	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrPropValuePattern/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bDrive\b/i) 		{ $SvrDrive = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bProjName\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCName\b/i) 		{ $SvrTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCNamePattern\b/i) 	{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCNameExecPattern/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcOp\b/i) 		{ $tcOp= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropNamePattern\b/i)  	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropValuePattern\b/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bTestSuit\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1; $SvrProjName =~ s/\\/\//g; $SvrProjName =~ s/$c\/$_TAF\///;}
		elsif ($varName =~ /\bTestSuite\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1; $SvrProjName =~ s/\\/\//g; $SvrProjName =~ s/$c\/$_TAF\///;}
		elsif ($varName =~ /\bTCNameFilter\b/i) 	{ $SvrTCNamePattern = $varValue;$foundMatch = 1;}
		elsif ($varName =~ /\bTCNameExecFilter\b/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTestCaseExec\b/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTestCase\b/i) 		{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropNameFilter\b/i)  	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropValueFilter\b/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcPropertyName\b/i)  	{ $tcPropertyName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsuit\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btname\b/i) 		{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpname\b/i)  		{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpvalue\b/i)  		{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btop\b/i) 			{ $tcOp= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bts\b/i) 			{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btn\b/i) 			{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btc\b/i) 			{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btne\b/i) 			{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bop\b/i) 			{ $tcOp= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bpr2Screen\b/i)  		{ $pr2Screen= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bnotUsegetTCName\b/i)  	{ $notUsegetTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btc_pl\b/i)     		{ $tc_pl= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcDriver\b/i)  		{ $tc_pl= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsDriver\b/i)  		{ $tsDriver = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bweb_ui_title\b/i)  	{ $web_ui_title= $varValue; $foundMatch = 1; $web_ui_title =~ s/___/ /g;}
		elsif ($varName =~ /\bworkingDir\b/i)  		{ $workingDir= $varValue; $foundMatch = 1; $workingDir =~ s/\\/\//g;}
		elsif ($varName =~ /\btcIdMin\b/i)  		{ $tcIdMin = $varValue; $foundMatch = 1;}

		elsif ($varName=~/\btcPropertyPatternPattern\b/i){ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btcPropertyPatternName\b/i){ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName=~/\btcFilterFilter\b/i)		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;} 
		elsif ($varName =~ /\btcFilterName\b/i)		{ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp\b/i)  		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn\b/i)			{ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp1\b/i)  		{ $tcPropertyPatternPattern1= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn1\b/i)		{ $tcPropertyPatternName1= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp2\b/i)  		{ $tcPropertyPatternPattern2= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn2\b/i)		{ $tcPropertyPatternName2= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp2\b/i)  		{ $tcPropertyPatternPattern3= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn2\b/i)		{ $tcPropertyPatternName3= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bkeyValue\b/i)  		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\bkey\b/i)			{ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btcFilters\b/i)  		{ 
			$varValue =~ /(.+)_matches_(.+)/; 
			$tcPropertyPatternName    = $1;
			$tcPropertyPatternPattern = $2;
			$foundMatch = 1;
		}

		elsif ($varName =~ /\bps1_args\b/i)		{ $ps1_args             = $varValue; $foundMatch = 1; $ps1_args =~ s/___/ /ig;}
		elsif ($varName =~ /\bsleep4Display\b/i)  	{ $sleep4Display 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcDelay\b/i)  		{ $sleep4Display 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bc\b/i)  			{ $c		 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\b_TAF\b/i)  		{ $_TAF		 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecution_24_7\b/i)  	{ $Execution_24_7	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bNofExecution\b/i)  	{ $NofExecution  	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecutionLength\b/i)  	{ $ExecutionLength 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecutionType\b/i)  	{ $ExecutionType   	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bperformanceMode\b/i)  	{ $performanceMode 	= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpm\b/i)  			{ $performanceMode = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpropertyOp\b/i)  		{ $propertyOp	   = $varValue; $foundMatch = 1; $propertyOp =~ s/_null_//ig;}
		elsif ($varName =~ /\bpo\b/i)  			{ $propertyOp	   = $varValue; $foundMatch = 1; $propertyOp =~ s/_null_//ig;}
		elsif ($varName =~ /\btsFilter\b/i)  		{ $tsFilter	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bSUTSymbol\b/i)  		{ $SUTSymbol       = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsFilterDefault\b/i)  	{ $tsFilterDefault = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bnotUsegetTCName\b/i)  	{ $notUsegetTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTSHookName\b/i)  		{ $TSHookName      = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTSHookNameGenerated\b/i)  { $TSHookNameGenerated  = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btestcaseNode\b/i)  	{ $testcaseNode    = $varValue; $foundMatch = 1; if ($testcaseNode =~ /_null_/) {$testcaseNode = "";}; }
		elsif ($varName =~ /\btestType\b/i)  		{ $testType        = $varValue; $foundMatch = 1; 
			#if ($testcaseNode !~ /^\s*$/) {
				if ($testType =~ /tc/i) { $testcaseNode = ".*";}
				if ($testType =~ /ts/i) { $testcaseNode = "testcase";}
				#}
		} 
		elsif ($varName =~ /\btsFrom\b/i)  		{ $tsFrom          = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsTo\b/i)  		{ $tsTo            = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bmakeMark\b/i)  		{ $makeMark        = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexitTAFGracefullyString\b/i) { $exitTAFGracefullyString = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bAutomationtsName\b/i)     { $AutomationtsName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bresetTSFileName\b/i)      { $resetTSFileName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexitTAFTCId\b/i)          { $exitTAFTCId 	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcComment1\b/i)            { $tcComment1	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcComment2\b/i)            { $tcComment2	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexternalLogName\b/i)       { $externalLogName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexternalLogName\b/i)       { $externalLogName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\boutputFormat\b/i)          { $outputFormat   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bhtmlRefreshRate\b/i)       { $htmlRefreshRate= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bhtmlRefreshRateWebUI\b/i)  { $htmlRefreshRateWebUI= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bhtmlRefreshRateLogUI\b/i)  { $htmlRefreshRateLogUI= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bip\b/i)       		 { $ip		   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\boverWriteTC\b/i)       	 { $overWriteTC    = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTSHookIsPerl\b/i)       	 { $TSHookIsPerl   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bcreateOrAppendTS\b/i)      { $createOrAppendTS=$varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btitleStatus\b/i)      	 { $titleStatus     =$varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bNofPropertyExec\b/i) 	 { $NofPropertyExec =$varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btags\b/i)       		 { $tags	    =$varValue; $foundMatch = 1;
		my $tmp = ""; foreach my $each (split (/_,_/, $tags)) { $tmp=$tmp."|".$each; } $tmp =~ s/\|_/_(/g; $tmp =~ s/_\s*$/)_/g; $tags =  $tmp;	
		}
	$url 			= 'file:///'.$SvrDrive;  		# will be updated in the sub-processTCs. Update derived Global Variable
	$urlHttp		= 'http://'.$ip.$http_port;		# will be updated in the sub-processTCs. Update derived Global Variable
	}
	$foundMatch;
	#### &printTAFGlobalVars(); todo Non-volatile GlobalVars
}


sub runPowershell {
	my $cmd = shift;  my $return; if ($cmd =~ /.ps1\s+/) { $cmd = "$cmd"; $return = `$cmd`;} else { $return = `$perl $cmd`; }
	$return =~ s/\@/&amp;/g; $return =~ s/\%/&#37;/g; $return =~ s/\$/&#36;/g;
 	$return =~ s/\s+<\s+/ &lt; /g; $return =~ s/\s+>\s+/ &gt; /g;	# improvement : handle < > in tcDesc
	return $return;
}

sub generateIndex_pyAnvil_pl {
	my $cwd = $SvrProjName; my $cmd = $SvrProjName. "\/index.ps1";
	open Fout, "> ".$cwd."/index_pyAnvil.pl";
print Fout<<EOF_;
############################ index_pyAnvil.pl ###################################
use strict;
&execTC(\$ARGV[0]);

sub execTC {
	my \$passFail='FAIL'; my \$logHtml; my \$logXml	;
	my \$pyAnvil= $c.'/pyAnvil/pyAnvil -s '		;
	my \$tcDir  = "$cwd\/"		;
	my \$testsuiteHook = "index.pl"			; 
	my \$tcId   = -1				; \$tcId   = shift if \@_;
	my \$tcDesc = "Testcase \$tcId Demo"		; \$tcDesc = shift if \@_;
	my \$tsDesc = "pyAnvil Testsuite Demo"		; \$tsDesc = shift if \@_; 

	\$testsuiteHook = \$tcDir.\$testsuiteHook		; 
	my \$tcScenario = "_tc.xml"			; \$tcScenario = \$tcDir."_tc.xml"	; 
	my \$tcLog_pyAnvil = "_tcLogAppend_.txt"         ; \$tcLog_pyAnvil = \$tcDir."\$tcLog_pyAnvil";
	if (\$tcId =~ /^\\s*\$/) { print `\$testsuiteHook`; return 0; }
my \$str=<<EOF;
<?xml version="1.0" encoding="utf-8"?>
<XMLTestCollection>
    <TestList TestCases="\$tcDesc">
	<ToolCase>
	    <Name>\$tcDesc</Name>
	    <Executable>C:/strawberry/perl/bin/perl.exe</Executable>
	    <Parameters>\$testsuiteHook \$tcId</Parameters>
	    <StdoutContains>PASS</StdoutContains>
	</ToolCase>
    </TestList>
</XMLTestCollection>
EOF
	open Fout, ">\$tcScenario"; print Fout \$str; close Fout; my \$cmd = \$pyAnvil."\$tcScenario"; my \$rst = `\$cmd`; 
	foreach my \$each (split /\n/, \$rst) { 
		if (   \$each =~ /^\\s+PASS\\s+/)     { \$passFail = "PASS";}
		elsif (\$each =~ /^\\s+FAIL\\s+/)     { \$passFail = "FAIL";}
		elsif (\$each =~ /^\\s+XML:\\s+(.+)/) { \$logXml   = \$1;}
		elsif (\$each =~ /^\\s+HTML:\\s+(.+)/){ \$logHtml  = \$1;}
	}
open Fout, "> \$tcLog_pyAnvil "; print Fout "\$rst\n"; close Fout;  print "- > \$tcLog_pyAnvil\n"; 
	print "\$passFail\n"; 
}
############################ index_pyAnvil.pl ###################################
EOF_
	close Fout; print    "  -->".$cwd."/index_pyAnvil.pl\n";

}
sub generateExcelReport {
	my $key; my %listHistory; my %tcDesc; my @tcExecDateTime; my $tcExecDateTimeCtr=0; my $isPassFail = "n"; my $tsName= "MVSDK_OCSP"; my @columnWidth;
	#  Todo: todo: need some variable initialization 
	#&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;propertyOp=list_tcDesc"); 
	#&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;propertyOp=list_history_tcRunResult");
	#&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;propertyExecCtrEqZero=y;propertyOp=list_tcDesc;propertyOp=_null_"); 
	#&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;propertyExecCtrEqZero=y;propertyOp=list_history_tcRunResult;propertyOp=_null_");

	# bug: _tc_Desc.txt and _list_history_tcRunResult are not genreated 
	#   my $rst=  &processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;NofPropertyExecCtr=0;propertyOp=list_tcDesc;"); 
	#      $rst   =	&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;NofPropertyExec=0;propertyOp=list_history_tcRunResult;");
	
	my $cmd ="$c/$_TAF/taf.pl testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;propertyOp=list_tcDesc"; my $rst = `$cmd`;
	$cmd ="$c/$_TAF/taf.pl testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;propertyOp=list_history_tcRunResult"; $rst = `$cmd`;

	my $tcDescMax=40; my $tcIdMax=10;
	if ( -e "$SvrDrive/$SvrProjName/_list_tcDesc.txt") {
		##### print " <- $SvrDrive/$SvrProjName/_list_tcDesc.txt\n";
		open Fin, "$SvrDrive/$SvrProjName/_list_tcDesc.txt" || die "Can't open file $!"; 
		while( $_ = <Fin>) {
		chop; 
		$_ =~ s/(list_)?tcDesc\s*=\s*(\d+\.)?//; 
		if ($_ =~ /testcase\d+(_)?\s+/) { @_ = split (/\t/, $_); 
			my $key = $_[0]; my $value = $_[1];	
			if ($_ =~ /\/_/)  {;} else { # exclude directory like /_ 
				## $value =~ s/_.+_//g; # remove property
				$value = &removeTags($value);
					}
			$tcDesc{$key} = $value; 
			if (length($value) > $tcDescMax) { $tcDescMax = length ($value); }
			if (length($key) > $tcIdMax) { $tcIdMax = length ($key); }
		} 
		} 
	close Fin;	
	;} else { 
	print "Info: $SvrDrive/$SvrProjName/_list_tcDesc.txt doesn't exist. Proceed ... (generateExcelReport won't work. Run -propertyOp=list_tcDesc)\n"; return 0 ;}

	$columnWidth[0]=$tcIdMax; $columnWidth[1]=$tcDescMax;

	if ( -e "$SvrDrive/$SvrProjName/_list_history_tcRunResult.txt") {
	####		print " <- $SvrDrive/$SvrProjName/_list_history_tcRunResult.txt\n";
	open Fin, "$SvrDrive/$SvrProjName/_list_history_tcRunResult.txt" || die "Can't open file $!"; 
	while($_ = <Fin>) { chop; s/\s*=\s*/ /g;
		if ($_ =~ /list_history_tcRunResult/) { 
			if ($_ =~ /list_history_tcRunResult/) { $tcExecDateTimeCtr ++ ;}
			@_ = split (/\s+/, $_); 
			$_ =~ /(.+)\s+(.+)/;
			$key 	= $_[0]; my $value 	= $_[1];
			if ($_ =~ s/^.+list_history_tcRunResult//) {
				my $passFail=""; my $date="";
				if ($_ =~ /tcRunResult\s*(\S+)\s+\@\s+(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d:\d\d)/ ) {
				$passFail = $1; $date = $2; }
			if ($passFail =~ /pass|fail|\d+/i) { 
				my $tmp = $listHistory{$key};	# remove the unreasable error - concat undefined variables
				if ($tmp) {;} else { $tmp="";}
				$listHistory{$key} = $tmp."$passFail\t"; 
				$isPassFail = 'y';
			} else {$isPassFail = 'n'; }
			if (($isPassFail =~ /y/i) && ($tcExecDateTimeCtr == 1)) { push (@tcExecDateTime, $date) ;} 
;
			}
		} elsif ($_ =~ /tcRunResult/i) {
			my $passFail = ""; my $date = "";
			if ($_ =~ /tcRunResult\s*(\S+)\s+\@\s+(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d:\d\d)/) {
			$passFail = $1; $date = $2; }
			if ($passFail =~ /pass|fail|\d+/i) { 
				my $tmp = $listHistory{$key};	# remove the unreasable error - concat undefined variables
				if ($tmp) {;} else { $tmp="";}
				$listHistory{$key} = $tmp."$passFail\t"; 
				$isPassFail = 'y';
			} else {$isPassFail = 'n'; }
			if (($isPassFail =~ /y/i) && ($tcExecDateTimeCtr == 1)) { push (@tcExecDateTime, $date) ;} 
		} else {
			;
		}
	} 
	close Fin;
	} else { print "Info: $SvrDrive/$SvrProjName/_list_history_tcRunResult.txt doesn't exist. Proceed ... (generateExcelReport won't work. Run propertyOp=list_history_tcRunResult)\n"; return 0 ;}

open Fout, "> $SvrDrive/$SvrProjName/_generateExcelReport.txt";
open Fout1, "> $SvrDrive/$SvrProjName/_generateExcelReport.html"; print Fout1 "<html><body><pre>\n";
my $currentDate ="";
for (my $i = 0; $i <= $#tcExecDateTime; $i++) { 
	$tcExecDateTime[$i] =~ /(\d\d\d\d-\d\d-\d\d)\s+(\d\d:\d\d:\d\d)/; my $date = $1; my $time = $2;
	if ($currentDate eq $date) { $tcExecDateTime[$i] = $time; $columnWidth[$i+2] = length ($time); } elsif ($currentDate ne $date) { $currentDate = $date; $columnWidth[$i+2] = length ("$date $time"); }
} 

printf Fout "Test Suite Name: $AutomationtsName\n";
printf Fout1 "Test Suite Name: $AutomationtsName\n";
printf Fout "%-${tcIdMax}s\t%-${tcDescMax}s\t", "tcId", "Description"; for (my $i = 0; $i <= $#tcExecDateTime; $i++) { print Fout "($tcExecDateTime[$i])\t"; } print Fout "\n";
printf Fout1 "%-${tcIdMax}s %-${tcDescMax}s", "tcId", "Description"; for (my $i = 0; $i <= $#tcExecDateTime; $i++) { print Fout1 "($tcExecDateTime[$i])"; } print Fout1 "\n";


foreach my $each (sort keys %listHistory) { 
	my $each_ = $each; 

	if ($tcDesc{$each}) {
		printf Fout "%-$columnWidth[0]s\t%-$columnWidth[1]s\t", $each_, $tcDesc{$each};
		printf Fout1 "%-$columnWidth[0]s %-$columnWidth[1]s ", $each_, $tcDesc{$each};
	} else {	# for Test-AutomationFramework.t  
		printf Fout "%-$columnWidth[0]s\t%-$columnWidth[1]s\t", $each_, "";
		printf Fout1 "%-$columnWidth[0]s %-$columnWidth[1]s ", $each_, "";
	}

	my @fields = split (/\t/, $listHistory{$each}); 
	for (my $i=0; $i <= $#fields; $i++) {
		my $tmp;
		if ($columnWidth[$i + 2]) {;} else { $columnWidth[$i+2] = 10;}
		$tmp = $columnWidth[$i + 2] + 1;
		if ($tmp) {;} else { $tmp = $excelReportColumnWidth;} 
		printf Fout "%-${tmp}s\t", $fields[$i];
		printf Fout1 "%-${tmp}s ", $fields[$i];
	}
	print Fout "\n";
	print Fout1 "\n";
}

close Fout;
print Fout1 "</pre></body></html>\n";
close Fout1;
#### uncomment for debugging    print " -> $SvrDrive/$SvrProjName/_generateExcelReport.html\n";
1;
}

sub generateGenerateTestsuite {
	my $cwd = $workingDir; $cwd = shift if @_;
	open Fout, "> ".$workingDir."/generateTestsuite.pl";
print Fout<<EOF;
\$cmd = "$c/$_TAF/taf.pl web_ui_title=MV___SDK___PROXY___(Please___connect___to___Intel___Network);tsDriver=$cwd/index.pl;printVars;generateTestsuite"; `\$cmd`;
EOF
	close Fout;
}

sub generateIndex_pl {
	my $cwd = $workingDir; $cwd = shift if @_;
	open Fout, "> ".$cwd."/index.pl";
	my $ps1_args_ = $ps1_args;
	$ps1_args_ =~ s/\\/\//g;

print Fout<<EOF_;

##################### index.pl for pyAnvil ############################

my \$testsuiteHook = "powershell -executionpolicy unrestricted -file $cwd/index.ps1 ";
my \$testsuiteHookPartB = " \$ps1_args_";


if    (\$ARGV[1]) { print &call_index(\$ARGV[0], "noExec") ;	}  
elsif (\$ARGV[0]) { print &call_index(\$ARGV[0], "yesExec");    }
else             { print &call_index();                         }


sub call_index { 		my \$return ; my \$recordCtr=1;
	if (\@_) {;} else {; return `\$testsuiteHook \$testsuiteHookParkB`;}
	my \$indexCtr = 9999	; \$indexCtr = shift if \@_; 		 
	my \$execYN   = 'noExec' ; \$execYN   = shift if \@_; 
	\@_ = (split /\\n/, `\$testsuiteHook`) ;


	foreach \$each (\@_) { 
		if ((\$each) && (\$each =~ /^\\s*_/)) { \$return = \$return .\$each."\n";
		} elsif ((\$each) && (\$each !~ /^\\s*_/)) {
			\$return = \$return . sprintf "TC [%04s] %s\\n",\$recordCtr,\$each; 
			if ((\$recordCtr == \$indexCtr ) && ( \$execYN =~ /noExec/i )) { return "TC [\$recordCtr]       \$each"; } 
			if ((\$recordCtr == \$indexCtr ) && ( \$execYN =~ /yesExec/i)) { return `\$testsuiteHook \$indexCtr \$testsuiteHookPartB`  ; } 
			\$recordCtr++;
	  	} 
 	} 
	if (\$return =~ /pass/i) { return 0;} 
	if (\$return =~ /fail/i) { return 1;} 
}

##################### index.pl for pyAnvil ############################
EOF_
	close Fout; print    "  -->".$cwd."/index.pl\n";


}

sub generatePerl_pl_template {
	my $cmd = $SvrProjName; 
	if (-e $cmd) {;} else { mkdir $cmd; }
	mkpath $cmd;
	open Fout, "> $cmd/index.pl";
	my $tsNameTmp =	&getRoot($cmd);
print Fout<<EOF_;
if (\$ARGV[0]) { 
	if (\$ARGV[0] == 1) { print "pass"; } # <<< plug in the test case 1 here e.g. print `index.pl 1` ; >>>
	if (\$ARGV[0] == 2) { print "pass"; } # <<< plug in the test case 2 here e.g. print `index.pl 2`>>>
	if (\$ARGV[0] == 3) { print "pass"; } # <<< plug in the test case 3 here e.g. print `index.pl 3`>>>
	if (\$ARGV[0] == 4) { print "pass"; } # <<< plug in the test case 4 here e.g. print `index.pl 4`>>>
	if (\$ARGV[0] == 5) { print "pass"; } # <<< plug in the test case 5 here e.g. print `index.pl 5`>>>
	if (\$ARGV[0] == 6) { print "pass"; } # <<< plug in the test case 6 here e.g. print `index.pl 6`>>>
} else {
print \<\<EOF;
1. Test case description 1 for < > \\\$ \\\% @ testing the function 1 --- Please modifyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa _smoke_ _regression_
2. Test case description 2 for testing _smoketest__regressiontest_the function 2 --- Please modifybbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb _smoke_
3. Test case description 3 for testing _smoketest_the function 3 --- Please modifycddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd _regression_
4. Test case description 4 for testing _regressiontest_the function 4 --- Please modify _smoke_
5. Test case description 5 for testing _regressiontest_the function 5 --- Please modify
6. Test case description 6 for testing the function 6 --- Please modify
EOF
;
}

EOF_
	close Fout;
	print "\n[Warning] Creating Temporial testsuite hook --> [".$SvrProjName."/index.pl]\n"; ; 
}

sub generatePowershell_ps1_template {
	my $cmd = $SvrProjName; 
	open Fout, "> $cmd/index.ps1";
	my $tsNameTmp =	&getRoot($cmd);
	my $tmpWorkingDir = $tsNameTmp; $tmpWorkingDir =~ s/\\/\//g;
print Fout<<EOF_;

###########################
param([INT]\$index = "-1", \$buildpath="")

if(\$verbose -eq \$true) { cls }

\$subHtml = "/auto_html/LBP_automation.html"
\$index = \$index -1 		
######################################################################################
# Dictionary for pre-canned test scenarios.
######################################################################################
\$testDictionary = \@()

\$testDictionary += \@( `
		\@{	"desc" = "Testcase1 description $SvrProjName"; 
			"result" = "PASS";
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase2 description $SvrProjName _smoketest_ _regression_ _regressiontest_"; 
			"result" = "FAIL"; 
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase3 Description $SvrProjName _smoketest_ _regression"; 
			"result" = "FAIL"; `
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase4 Description $SvrProjName _smoketest_"; `
			"result" = "PASS"; `
		} `
)


################################################################################################

\$idx = [Int32]::Parse(\$index)
\$testDictionaryCount =  \$testDictionary.length - 1
\$count = 1
if((\$idx -lt 0) -or (\$idx -gt \$testDictionaryCount)) 
{
	foreach(\$dictionaryDesc in \$testDictionary) 
	{
		Write-Host "\$count :"\$dictionaryDesc.desc
		\$count++
	}
	exit
}

write-host \$testDictionary[\$idx].result;



###########################

EOF_
	close Fout;
	print "\n[Warning] Creating Temporial testsuite hook --> [".$SvrProjName."/index.ps1]\n"; ; 
}

sub generateTAFTestsuite {goto &generateTestsuite}
sub generateTestsuite { 						# Generating 1. index.pl 2. index.pl + index_pyAnvil.pl 
	my $cmd = $SvrProjName ;  $cmd = shift if @_;
	if ($cmd !~ /:/) { $cmd = $c.'/'.$_TAF.'/'.$cmd; }
	my $cwd = $cmd;
	if (-e "$cmd\/index.ps1") { $cmd = $cmd . "\/index.ps1";	#### pre-existing testsuiteHook is index.ps1 
		&generateIndex_pl ($cwd)			  ; 	# --> generate index.pl 
		}
	elsif (-e "$cmd\/index.pl")     { 
		$cmd = $cmd . "\/index.pl";}				#### pre-existing testsuiteHook is index.pl 
	else  { 							####  No pre-existing index.pl 
		if ($tsDriver =~ /null/i) { $tsDriver = "$cmd\/index.pl"; }	
		&generatePerl_pl_template();
	}								
	##############################################  subroutine Main ###########################################
	$cmd = shift if @_; my $testsuiteName="_default_testsuiteblas_"; my $testsuitePropertyFName='tsProperty.txt'; my $testDriverName = $cmd; 
	my $tsPropertyStr = "web_ui_title: "; my $tcCtr=1; my $TAF= $SvrDrive ;

 	$testsuiteName = &getRoot_4($cwd);  			############ $testsuiteName = &getRoot(&getcwd());  

	if (($TSHookIsPerl =~ /y/i) && ($cmd =~ /index\.ps1\s*$/))    { $cmd =~ s/index\.ps1\s*$/index\.pl /g;}	 

	############ Generate Property file for webUI tc description
	if ($ps1_args =~ /^\s*$/) { $ps1_args = "-ps1_args powershell_args";}
 	if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file ". $cmd. " $ps1_args"; }

	foreach my $each (split "\n", &runPowershell($cmd)) {	# get testsuiteName _testsuitename_: (\w+)and _testdrivername_: (\w+)
		if    ($each =~ /_testsuitename_/i)  { $each =~ /_testsuitename_\s*:\s*(.+)\s*$/i;  $testsuiteName  = $1; if ($testsuiteName =~ /\s/) { print "white space in testsuitename\n";exit; }}
		elsif ($each =~ /_testdrivername_/i) { $each =~ /_testdrivername_\s*:\s*(.+)\s*$/i; $testDriverName = $1; }
		else { ; }
	}

####  <--$cmd       _testsuitename_ : [$testsuiteName] 
####  <--$cmd       _testdrivername_: [$testDriverName] 
print<<EOF;
  <--$cmd 
  --> $c/$_TAF/$testsuiteName ...... (Can take several minutes)
EOF

	if ($web_ui_title =~ /Test Automation Framework/) {$tcCtr=1; $tsPropertyStr = $tsPropertyStr . " $testsuiteName : web_ui_title\n";} # overwrite web_ui_title 
	else {$tcCtr=1; $tsPropertyStr = $tsPropertyStr . " $web_ui_title: web_ui_title\n";}

	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { 
			if ($each =~ /^\s*\d/) { 		#### Fix duplicated serial # problem  - double serial # problem
			$tsPropertyStr = $tsPropertyStr . sprintf "$c/$_TAF\/$testsuiteName\/testcase%04d\|%s\n", $tcCtr, $each; $tcCtr++;
	  		} else {	
			$tsPropertyStr = $tsPropertyStr . sprintf "$c/$_TAF\/$testsuiteName\/testcase%04d\|%4d  %s\n", $tcCtr, $tcCtr, $each; $tcCtr++;
			}
		} 
	}
	############ Generate Property file for webUI tc description

	############ add tcDesc Property #############

	my $tcCtr_ = 0;
	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { 
			$each =~ s/\s/_space_/g;
			$each =~ s/:/_column_/g;
			$each =~ s/=/_eq_/g;
			$tcDesc[$tcCtr_] = $each ; $tcCtr_ ++; 
			$propertyOp = "tcDescAuto";
		} 
	}
	############ add tcDesc Property #############
	############ Generate Tags Property ################

	my @tcDescPropertyList; my $ctr=0; my $maxPropertyNameLength=1; my %propertyList;

	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		$each =~ s/__/_ _/g; @_ = ($each =~ /_\w+_/gi ) ; 
		for (my $i=0; $i <= $#_;$i++) { $propertyList{$_[$i]}=$_[$i];
			if ($maxPropertyNameLength < length($propertyList{$_[$i]})) { $maxPropertyNameLength = length($propertyList{$_[$i]}); }
		}
	}
	############ Generate Tags Property ################

	############ Create Testsuite/Testcase
	$tcCtr=1;
	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { 
			if ($tsDriver !~ /null/) { $testDriverName = $tsDriver; } # tsDriver overwrite testDriverName
			#### todo: need to decide to generate pl or ps1 
		
			my $ps1_args_; my $cmd_; 	
			if (    $cmd =~ /index\.ps1\s*$/) {
				$ps1_args_ = $ps1_args; $ps1_args_ =~ s/ /___/g; $ps1_args_ =~ s/\\/\//g; # ps1_args 
				$cmd_ = sprintf "ps1_args=$ps1_args_;testsuite=$testsuiteName;create=testcase%04d/customTC:${testDriverName}_space_${tcCtr}:customTC\n", $tcCtr  ; 
			} elsif ( $cmd =~ /index\.pl\s*$/) {
				$cmd_ = sprintf "testsuite=$testsuiteName;create=testcase%04d/customTC:${testDriverName}_space_${tcCtr}:customTC\n", $tcCtr  ; 
			}

			&processTCs("",$cmd_);
			my $tcnameTmp = sprintf "$c/$_TAF/$testsuiteName/testcase%04d", $tcCtr++;
			my $propertyTmp = $each;
			$propertyTmp =~ s/ /_space_/g; 
			$propertyTmp =~ s/:/_column_/g; 
			$propertyTmp =~ s/=/_eq_/g; 
			$propertyTmp =~ s/ /__/g; 
			&processProperty("",$tcnameTmp, "set_tcDesc_as_$propertyTmp");
			foreach $each (split (",", $tags)) { if ($propertyTmp =~ /$each/i) { &processProperty("",$tcnameTmp, "_add_${each}_as_y"); } }

			$propertyTmp=""; #### reuse the variable
			foreach my $propertyName (sort keys %propertyList) {
				if ($each=~ /\b$propertyName\b/i) {
					$propertyTmp = sprintf "$propertyTmp%-${maxPropertyNameLength}s",$propertyName;
				} else {
					$propertyTmp = sprintf "$propertyTmp%-${maxPropertyNameLength}s","_null_";
				}
			}
			$propertyTmp =~ s/ /_space_/g; 
			$propertyTmp =~ s/:/_column_/g; 
			$propertyTmp =~ s/=/_eq_/g; 
			$propertyTmp =~ s/ /__/g; 
			&processProperty("",$tcnameTmp, "set_tcTags_as_$propertyTmp");

		}
	}

	$tcCtr = 1;
	############ Create Testsuite/Testcase

	open Fout, ">>$c/$_TAF/$testsuiteName/$testsuitePropertyFName" || die "Can't create file\n"; print Fout $tsPropertyStr; close Fout;
	print    "  -->$c/$_TAF/$testsuiteName/$testsuitePropertyFName\n";
	&generateGenerateTestsuite(); 
	#### print    "  -->$c/$_TAF/$testsuiteName/generateTestsuite.pl\n";

	if ( -e "$c/$testsuiteName/_tcMap.txt" ) { 
		open Fin2, "$c/$testsuiteName/_tcMap.txt" ;
		open Fout2, ">$c/$_TAF/$testsuiteName/_tcMap.txt"; 
		while ($_=<Fin2>) { $_ =~ s/$c/$c\/$_TAF/ig; print Fout2 $_; }
		close Fout2; 
		close Fin2;
		print    "  -->$c/$_TAF/$testsuiteName/_tcMap.txt\n";
	}
	$testsuiteName = $testsuiteName;
			if ($testcaseNode =~ /^\s*$/) { $testcaseNode = "_null_"; }
			#$cmd = sprintf "$c/$_TAF/taf.pl tcDelay=0;performanceMode=fast;testcaseNode=$testcaseNode;testsuite=$testsuiteName;list"; 
			#print "\nlist: todo> $cmd\n". `$cmd`;
			#### !!!!!!!!!! the processTCs works !!!!!!!!!!!!!!!
			$cmd = sprintf "tcDelay=0;testcaseNode=$testcaseNode;testsuite=$testsuiteName;list";  &processTCs("",$cmd); # todo
			&generateRootIndex();
	if ($interact =~ /\by\b/) {system ("C:/Program Files/Internet Explorer/iexplore.exe", "$c/$_TAF/$testsuiteName/index.htm");}

	print "\n";
	1;
}


sub generateTAFChildTestsuites { 						# Generating 1. index.pl 2. index.pl + index_pyAnvil.pl 
	my $cmd = $SvrProjName ;  $cmd = shift if @_;
	if ($cmd !~ /:/) { $cmd = $c.'/'.$_TAF.'/'.$cmd; }
	my $cwd = $cmd; my $testsuiteName = &getRoot_4($cwd);  			############ $testsuiteName = &getRoot(&getcwd());  
	if (-e "$cmd\/index.ps1") { $cmd = $cmd . "\/index.ps1";		#### pre-existing testsuiteHook is index.ps1 
		}
	elsif (-e "$cmd\/index.pl")     { 
		$cmd = $cmd . "\/index.pl";}					#### pre-existing testsuiteHook is index.pl 
	else  { 								####  No pre-existing index.pl 
		print "generateChildTestsuites: The parentTestsuite doesn't exist! \n"; exit; 
	}								

	open FOUT, ">$c/$_TAF/_generateChildTestsuite.bat"; 

 	if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file ". $cmd. " $ps1_args"; }
	foreach my $each (split "\n", &runPowershell($cmd)) {	# get testsuiteName _testsuitename_: (\w+)and _testdrivername_: (\w+)
		 $each = " _full_ ".$each;
		@_ = $each =~ /_(\w+)_/g; 
		if ($#_ > 0) {	
			foreach my $each1 (@_) { 
				if ($recordTags{$each1}) { $recordTags{$each1} = $recordTags{$each1} + 1; } else { $recordTags{$each1} = 1;}
			} 
		}
	}

		#$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_full_;generateTestsuiteByDesc\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd"; 	# todo  \\
		#$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_full_;generateTestsuite\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd"; 			# todo  \\
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_full_;generateTestsuiteByDesc\n"; 		print FOUT "$cmd"; 			# todo5 \\
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_full_;generateTestsuite\n";  				print FOUT "$cmd"; 			# todo6 \\
		
	foreach my $key (sort hashValueDescendingNum (keys(%recordTags))) { 
		if ($key !~ /\bfull\b/i) {
		#$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_${key}_;generateTestsuiteByDesc\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd"; 	# todo \\
		#$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_${key}_;generateTestsuite\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd"; 			# todo \\
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_${key}_;generateTestsuiteByDesc\n"; 	print FOUT "$cmd"; 	# todo7 \\
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_${key}_;generateTestsuite\n"; 				print FOUT "$cmd"; 			# todo8 \\
		}
	
	}
	close FOUT;
	print " -> $c/$_TAF/_generateChildTestsuite.bat\n --.....-> Running $c/$_TAF/_generateChildTestsuite.bat to generate _smoke_, _regression_ sub Testsuite\n";    
	
	##############################################################################################

	1;
}
sub hashValueDescendingNum { $recordTags{$a} <=> $recordTags{$b}; }


sub help4install {
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; }
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION

	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reportings with *ONE* mouse-click. No programming and no manual Reading.

        ---------------------------------------------------------------------------------------------------------------
	$c/$_TAF/index.htm	         WebAccess TAF-Testbed
	$c/$_TAF/taf.pl -help4intro      TAF Introduction
	$c/$_TAF/taf.pl -help4install    Command_line usages 
	$c/$_TAF/taf.pl -help4cmd        Command_line usages 
	$c/$_TAF/taf.pl -help4developer  Historical and under-development Functions
        ---------------------------------------------------------------------------------------------------------------

	TAF Test Case integration - $c/$_TAF/[test_suite]/[test_case]/tc.pl
				
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : print Pass|fail|number to STDOUT
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : geneate TC Log as cwd()/_appendLog.txt 

	TAF Test Suite integration - $c/$_TAF/[test_suite]/index.pl or index.ps1

			* $c/$_TAF/index.[pl|ps1]             : print one TC Description per line
			* $c/$_TAF/index.[pl|ps1] Index       : exec Index-th TC

  	[Web Access: http://$c/$_TAF/index.htm]
	1. Install StrawberryPerl 
	2. Install TAF from CPAN                 (Perl -MCPAN -e "install Test::AutomationFramework)
	3. Install TAF Testbed                           (Perl -MTest::AutomationFramework -e "help"   
	4. *One* mouse click to execute and view test results in the Test Bed

	[Web examples]
	5. Add test suite by modifying $c/$_TAF/taf.bat 
	6. Add test case by modifying $c/$_TAF/[test_suite]/[test_case]/tc.pl 
	7. Run $c/$_TAF/taf.bat to create user's test suite structure and start its webUI
	
	webUI TAF usages scenarios:  	
		List Test cases:		
			* list test pass|fail                                     (click Pass|Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;list
			* list Passed test cases                               (click title's Pass)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_pass 
			* list Failed test cases                             (click title's Failed)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_fail
			* list non-Pass|Failed test cases          (click \| between Pass and Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_null
		Exec Test cases:		
			* Exec test cases 		      	  	  (click pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase0001;exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1,2,3,4];exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1-9];exec
			* Exec test suite 		            (click title pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;exec
		View Test Results
			* View historical pass/fail 	                           (click Pass|Fail) 
			* View historical logs		                           (click Test Desc) 
			* View historical pass/fail in graphics 		(click title Result)
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	1;
}

sub help {
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; }
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION
		TAF manages automated test cases regarding test setup, test query, test execution and 
		test reportings with *ONE* mouse-click. No programming and no manual Reading.
-----------------------------------------------------------------------------------------------------------------------

	$c/$_TAF/taf.pl helpmore                TAF Usage Samples
	$c/$_TAF/taf.pl testsuite=_testsuit3_   Frequently Used Command line


	$c/$_TAF/index.htm	       WebAccess TAF-Testbed
	$c/$_TAF/taf.pl help4intro      TAF Introduction
	$c/$_TAF/taf.pl help4install    Command_line usages 
	$c/$_TAF/taf.pl help4cmd        Command_line usages 
	$c/$_TAF/taf.pl help4dev        Historical and under-development Functions

-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	sleep $outputPause;
	1;
}


sub help4intro {
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; }
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION

	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reportings with *ONE* mouse-click. No programming and no manual Reading.

	TAF Test Case integration - $c/$_TAF/[test_suite]/[test_case]/tc.pl
				
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : print Pass|fail|number to STDOUT
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : geneate TC Log as cwd()/_appendLog.txt 

	TAF Test Suite integration - $c/$_TAF/[test_suite]/index.pl or index.ps1

			* $c/$_TAF/index.[pl|ps1]             : print one TC Description per line
			* $c/$_TAF/index.[pl|ps1] Index       : exec Index-th TC

  	[Web Access: http://$c/$_TAF/index.htm]
	1. Install StrawberryPerl 
	2. Install TAF from CPAN                 (Perl -MCPAN -e "install Test::AutomationFramework)
	3. Install TAF Testbed                           (Perl -MTest::AutomationFramework -e "help"   
	4. *One* mouse click to execute and view test results in the Test Bed

	[Web examples]
	5. Add test suite by modifying $c/$_TAF/taf.bat 
	6. Add test case by modifying $c/$_TAF/[test_suite]/[test_case]/tc.pl 
	7. Run $c/$_TAF/taf.bat to create user's test suite structure and start its webUI
	
	webUI TAF usages scenarios:  	
		List Test cases:		
			* list test pass|fail                                     (click Pass|Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;list
			* list Passed test cases                               (click title's Pass)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_pass 
			* list Failed test cases                             (click title's Failed)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_fail
			* list non-Pass|Failed test cases          (click \| between Pass and Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_null
		Exec Test cases:		
			* Exec test cases 		      	  	  (click pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase0001;exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1,2,3,4];exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1-9];exec
			* Exec test suite 		            (click title pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;exec
		View Test Results
			* View historical pass/fail 	                           (click Pass|Fail) 
			* View historical logs		                           (click Test Desc) 
			* View historical pass/fail in graphics 		(click title Result)
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
}

sub helpmore {
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; }
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION

	[TAF Execution Controls]
	$c\\$_TAF\\taf.pl -help 
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=\\d+_pipe_null;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_  rem list tcRunResult =~ /performance|null/
	$c\\$_TAF\\taf.pl -processTSs [create|delete|add]=$c/_testsuite1/_testsuite2
	$c\\$_TAF\\taf.pl Execution_24_7=y;NofExecution=5;Execution=24hour;testsuite=_MV_SDK_OCSP;[list|exec]
	$c\\$_TAF\\taf.pl testsuit=CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0057/_MV_SDK_OCSP;list
	$c\\$_TAF\\taf.pl exitTAF
	$c\\$_TAF\\taf.pl ExecutionType=[runTC|runTS]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;performanceMode=fast;list
	$c\\$_TAF\\taf.pl [SUTSymbol|tsFilterDefault]=_;tsFilter="2.2.0.217[_doit_];scanTestsuites 
	$c\\$_TAF\\taf.pl generateRootIndex
	$c\\$_TAF\\taf.pl -processTCs create=tc1/fail,overwrite
	$c\\$_TAF\\taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list
		
	#####################  Powershell Testsuite Exmaples     ##################################
	$c\\$_TAF\\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_
	$c\\$_TAF\\generatePyAnvilTestsuite.pl -buildpath c:/_CRB_/AppBuildpath -genTAF y

	#####################  get/set tc [Property|Filter]      ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=set_property1_[as|eq]_propVal1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get_property1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get__all_[_doit]

	##################### TC [list|exec] based on TC Filters ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;listTcfilters
		taf.pl testsuite=_testsuite2_;pm=fast;tcOp=listtcfilters
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tcFilters=testproperty_matches_tsetProperValue1;[list|exec]		
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tppp1=;tppn1=;tppp2=;tppn2=....

	$c\\$_TAF\\taf.pl tcPropertyName=smoke;tsFilterDefault=c:\\_CRB_\\AppBuildpath;generateTestsuiteByDesc
	e.g. 
		1. taf.pl testsuite=_testsuite2_;[list|print]Tcfilters
		2. taf.pl testsuite=_testsuite2_;propertyOP=_set_property1_[as|eq]_propVal1_doit_
		3. taf.pl testsuite=_testsuite2_;propertyOP=_get_property1
		4. taf.pl testsuite=_testsuite2_;tcFilters=property1_matches_PropertyValue1;[list|exec]		
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	1;
}

sub help4cmd{
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY now.\n"; exit; }
	&genDriver_taf_pl ();
	&genDriver_taf_cgi ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION

	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reportings with *ONE* mouse-click. No programming and no manual Reading.

	[Programmer's Usage: from command line. see TAF commands cmd> and taf cmds in $c/$_TAF/taf.bat>]

		Create Testcases		
			* c:\\_TAF\\taf.pl -processTSs create=c:/_TAF/_testsuiteTestBed/_testsuite4_
		Create Testsuites
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase2_/overwrite,perf,sleep=3
			* c:\\_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase1_/overwrite,sleep=20
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase6_/overwrite,genLog,sleep=10
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase9_/overwrite,expectedFail,genLog,sleep=1
		Copy Testsuite 
			taf.pl tsFrom=e.txt;tsTo=ee.txt;copyTS
		TS/TC Management by _tcGlobal.txt
			taf.pl testsuite=_testsuite2;printTAFTSVars
			taf.pl testsuite=_testsuite2;testcase=testcase0002;printTAFTCVars
			
		TC Execution controls
		
			* tcIdMin			: start TC Id for Testsuite Execution (default = 0)
			* printVars			: Print Global Variables
			* printTCFilters		: print TC Filters 
			* setTCFilter			: set_property1_as_value1[_doit_]
			* getTCFilter			: get_property
			* tcFilters			: =property_match_propertyvalue
			* tsDriver			: Testsuite Driver|hook
			* web_ui_title			: set webUI title
			* Execution_24_7		: Continuous execution [y|n]
			* NofExecution			: Number of Executions
			* ExecutionDuration		: Execution Longivity
			* exitTAF			: exitTAF gracefully
			* executionType			: TC|TS
			* performanceMode		: 'slow' for webUI & 1st time execution. 'fast' for command line exec 

-----------------------------------------------------------------------------------------------------------------------

	[Examples]
	$c\\$_TAF\\taf.pl -help 
	$c\\$_TAF\\taf.pl genDriver
	$c\\$_TAF\\taf.pl generateIndex_pl | generateIndex_pyAnvil_pl
	$c\\$_TAF\\taf.pl generateTestsuite
	$c\\$_TAF\\taf.pl generateRootIndex
	taf.pl testsuite=_testsuite1_;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;resetTSFile


	#####################  TS/TC Management (Create/List/Exec) ##################################
		
	$c\\$_TAF\\taf.pl -processTCs create=tc1/fail,overwrite
	$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;createOrAppendTS=create;generateTAFTestsuite
	$c\\$_TAF\\taf.pl -processTSs [create|delete|add]=$c/_testsuite1/_testsuite2
	$c\\$_TAF\\taf.pl [SUTSymbol|tsFilterDefault]=_;tsFilter="2.2.0.217[_doit_];scanTestsuites 
	$c\\$_TAF\\taf.pl tsDriver=$c/TAF_pyAnvil/index_pyAnvil.pl;web_ui_title=Test___Automation___Framework;printVars;generateTestsuite 	Generate pyAnvil Testsuite

	$c\\$_TAF\\taf.pl tcIdMin=5;printVars;testsuite=_testsuite3_;list 
	$c\\$_TAF\\taf.pl testsuit=CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0057/_MV_SDK_OCSP;list
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;performanceMode=fast;list
	$c\\$_TAF\\taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=\\d+_pipe_null;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_  rem list tcRunResult =~ /performance|null/
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=fail;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_

	$c\\$_TAF\\taf.pl tcIdMin=5;printVars;testsuite=_testsuite3_;exec
	$c\\$_TAF\\taf.pl ExecutionType=[runTC|runTS]
	$c\\$_TAF\\taf.pl exitTAF
	$c\\$_TAF\\taf.pl Execution_24_7=y;NofExecution=5;Execution=24hour;testsuite=_MV_SDK_OCSP;[list|exec]

	#####################  Powershell Testsuite Exmaples     ##################################
	$c\\$_TAF\\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_
	$c\\$_TAF\\generatePyAnvilTestsuite.pl -buildpath c:/_CRB_/AppBuildpath -genTAF y

	#####################  get/set/list/list_history tc [Property|Filter]      ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=set_property1_[as|eq]_propVal1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get_property1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get__all_[_doit]

        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;propertyOp=list_tcDesc 
        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;propertyOp=list_history_tcRunResult
        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;generateExcelReport

	##################### TC [list|exec] based on TC Filters ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;listTcfilters
		taf.pl testsuite=_testsuite2_;pm=fast;tcOp=listtcfilters
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tcFilters=testproperty_matches_tsetProperValue1;[list|exec]		
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tppp1=;tppn1=;tppp2=;tppn2=....

	e.g. 
		1. taf.pl testsuite=_testsuite2_;[list|print]Tcfilters
		2. taf.pl testsuite=_testsuite2_;propertyOP=_set_property1_[as|eq]_propVal1_doit_
		3. taf.pl testsuite=_testsuite2_;propertyOP=_get_property1
		4. taf.pl testsuite=_testsuite2_;tcFilters=property1_matches_PropertyValue1;[list|exec]		
	
	##################### MISC   Maintenance info ###########################	
	  	1. ......titleStatus=(UnderMaint);list  
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	1;
}


sub help4dev{
my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------

---------------- This help is for historical and under-development functions -----------------
taf.pl testsuit=_ts1_;list 
taf.pl testsuit=_ts1_;testcase=_tc1_;list 
taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\Automation_MVSDK\\_full_;propertyOp=list_tcDesc
taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\Automation_MVSDK\\_full_;listHistory
taf.pl testsuite=generateReport

taf.pl  -processTC or -tc arg=[tcName;cmd] create=tc1|list|get|exec=tc1|detect|delete|log|getLogName|printResult;all

	# e.g.  taf.pl -tc create=tc1;fail,overwrite
	        taf.pl -tc create=tc1;fail,genLog;pr2Screen
	        taf.pl -tc create=tc1;performanceTC,genLog;pr2Screen
	        taf.pl -tc delete=tc1;pr2Screen

	-processTCs or -s  arg=[TCOP=list;...]  # e.g.  taf.pl -s TCNamePattern=tc.*
	                                 	#       taf.pl -s list
		Drive=c:;			# c: d: e: ...
		TestSuite=_testSuit_;		# directory 
		TCOp=list;			# List test cases that matches the TCNameFilter and PropertyFilter
		TCName=_testCase_;		# test case name 
		TCNamePattern=*;		# Test Case Name Filter 
		TCNameFilter=*;			# Test Case Name Filter 
		PropNameFilter=.*;		# Property_Name Filter
		PropValueFilter.=.*;		# Property_Value Filter
		pr2Screen;			# Results will be displayed on screen 
		getVars|listVars|printVars	# get or print TAF settings

        -processTSs [create|delete|add]=c:/... 
	-processProperty or -prop arg=[add=prop1:val1]  add|delete|list|get|modify|match|filter

	# e.g   taf.pl -prop list=tc;pr2Screen
	        taf.pl -prop add=prop1:val1;pr2Screen
	        taf.pl -prop match=.*:.*;pr2Screen
	        taf.pl -prop match=propNameFilter:propValFilter

	To create driver (taf.pl): perl.pl -MTest::AutomationFramework -e "help" 

	taf.pl -processTCs create=tc1/fail,overwrite
	taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list
	$c\\$_TAF\\taf.pl  tsDriver=index_pyAnvil.pl;printVars;generateTestsuite
	$c\\$_TAF\\taf.pl  web_ui_title=testtitle;printVars;generateTestsuite
	cwd/taf.pl generateTestsuite 
	taf.pl generateRootIndex
	$c\\$_TAF\\taf.pl workingDir=c:/_MahoBby_/CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0062/_MV_SDK_OCSP;web_ui_title=c:/_MahoBby_/CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0062/_MV_SDK_OCSP;ps1_args=-buildpath___c:/_MahoBay_/CPD_QA_Tests/BATTests/MVTests/Bat/;generateTestsuite
	$c\\$_TAF\\taf.pl -scanTestsuites Tests/BATtests/MVtests/Bat/2.2.0.217_doit_
	$c\\$_TAF\\taf.pl testsuite=_testsuite1_;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;resetTSFile

	########################## Property add/get ##################################
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=set_property1_[as|eq]_propVal1_doit_
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get_property1_doit_
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get__all__doit

		taf.pl testsuite=_testsuite3_;testcase=testcase1;propertyOp=add_eq_prop1_column_val1[_doit_]
		taf.pl testsuite=_testsuite3_;testcase=testcase1;propertyOp=add_eq_tcDesc_column_TCDescription___Test[_doit_]
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOp=get_eq_prop1_doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOp=get_eq_tcDesc_doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=get_eq_.*_all__doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=get_eq_tcOwner_doit_

	##################### TC Property Filter for TC Execution ##################################
	taf.pl testsuite=_testsuite2_;pm=fast;listTcfilters
		taf.pl testsuite=_testsuite2_;pm=fast;tcOp=listtcfilters
	taf.pl testsuite=_testsuite2_;pm=fast;tcFilters=testproperty_matches_tsetProperValue1;[list|exec]		
		taf.pl testsuite=_testsuite2_;pm=fast;tcPropertyPatternName=prop1;tcPropertyPatternPattern=val1;list
		taf.pl testsuite=_testsuite2_;pm=fast;tppn=prop1;tppp=val1;list
		taf.pl testsuite=_testsuite2_;pm=fast;key=prop1;keyValue=val1;list

	e.g. 
		1. taf.pl testsuite=_testsuite2_;listTcfilters
		2. taf.pl testsuite=_testsuite2_;propertyOP=_set_property1_[as|eq]_propVal1_doit_
		3. taf.pl testsuite=_testsuite2_;propertyOP=_get_property1
		4. taf.pl testsuite=_testsuite2_;tcFilters=property1_matches_PropertyValue1;[list|exec]		


	taf.pl install (obsoleted)


-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	1;
}
sub genDriver_taf_pl {
	if (-e "$c/$_TAF/taf.pl") {;} else { mkpath "$c/$_TAF"; open Fout, ">$c/$_TAF/taf.pl"; print Fout &prDriver(1); close Fout; print " --> $c/$_TAF/taf.pl\n"; }
	1;
}
sub genDriver_taf_cgi {
	if (-e "$c/$_TAF/taf.cgi") {;} else { mkpath "$c/$_TAF"; open Fout, ">$c/$_TAF/taf.cgi"; print Fout &prDriverCGI(1); close Fout; print " --> $c/$_TAF/taf.cgi\n"; }
	1;
}
sub genDriver {	# Testbed/testbed
#here 	if ($workingDir =~ /\w+:[\/|\\]\s*$/) { print 'Please do *NOT* run perl -MTest::AutomationFramework -e "install" from rootDir. Run it from non-root directory.'; exit}
	mkpath  "$c/$_TAF";
	if (-e "$c/$_TAF/taf.pl") { ;} else { open Fout, ">$c/$_TAF/taf.pl"; print Fout &prDriver(1); close Fout; print " --> $c/$_TAF/taf.pl\n"; }
	if (-e "$c/$_TAF/taf.bat") {;} else {

my $str =<<EOF;

REM ------------- Create TC/TS under c:\\$_TAF -----------------------------------
REM * Create Functional test case, which returns Pass with different execution time. 
REM * Create Functional test case, which returns Fail with different execution time. 
REM * Create Performance test case, which returns number of seconds
REM * Create Functional test case, with logs and links in the logs (_tcLogAppend.txt)
REM * Create Functional test case, with expected failure (expF)
REM * Create Functional test case, with expected failure (bugF)
REM * Test case  execution  testcase=string : (testType=tc or ts: what does it mean?) 
REM * Test case  execution  testcase=regExp : (testType=tc or ts: what does it mean?) 
REM * Test suite execution  testsuite=string : (testType=tc or ts: what does it mean?) 
REM * Test suite execution  testsuite=regExp : (testType=tc or ts: what does it mean?) 
REM * Test case  status : moving ">"
REM * Test case  24/7 execution
REM * Test suite 24/7 execution
REM * Test case  "stop" 
REM * Test suite "stop"
REM * Test suite title tsProperty.txt
REM * Test case  title tcProperty.txt
REM create test_suite (_test_suite?_)/_test_case?_  under c:\\$_TAF
REM * Modify 
REM * Delete TC/TS
REM * Update TS/TC Status
REM ------------- Create TC/TS in directory $c\\$_TAF...... -----------------------------------

$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0001/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0002/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0003/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0004/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0005/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0006/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0001/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0002/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0003/overwrite,sleep=40
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0004/overwrite,sleep=30
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0005/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0006/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0001/overwrite,sleep=2
REM create performance test 
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0002/overwrite,perf,sleep=3
REM create Failed Functional test 
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0003/overwrite,fail,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0004/overwrite,sleep=2
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0005/overwrite,fail,sleep=4
REM create functional test /w log
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0006/overwrite,genLog,sleep=10
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0007/overwrite,fail,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0008/overwrite,pass,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0009/overwrite,expectedFail,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0010/overwrite,expF,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0011/overwrite,bugF,genLog,sleep=1

REM create customrized TAF test cases for property operation test (TC contents are hardcoded in TAF)
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0001/overwrite,sleep=1,customTC:taftestcase1:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0002/overwrite,sleep=1,customTC:taftestcase2:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0003/overwrite,sleep=1,customTC:taftestcase3:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0004/overwrite,sleep=1,customTC:taftestcase4:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;exec

REM $c\\$_TAF\\taf.pl testsuite=_testsuite1_;printTAFTSVars
REM $c\\$_TAF\\taf.pl testsuite=_testsuite1_;testcase=testcase0003;printTAFTCVars

REM _TAF\\_testsuite\\TAFTSVars.txt that overwrite _TAF\\TAFGlobalVARS.txt
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;printTAFTSVars
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;updateTAFTSVars
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;testsuite=testsuite0002;updateTAFTCVars



REM ************ Make _testsuite1_/testcase0001 Execution_local_only (no remote exectuion)
REM _TAF\\_testsuite\\TAFTSVars.txt that overwrite _TAF\\TAFGlobalVARS.txt
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;printTAFTSVars
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;updateTAFTSVars

REM ************ Make _testsuite2_/testcase0002 Execution_local_only (no remote exectuion)
rem $c\\$_TAF\\taf.pl testsuite=_testsuite2_;testcase=testcase0002;clearTAFTCVars
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;testcase=testcase0002;printTAFTCVars
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;testcase=testcase0002;updateTAFTCVars
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;list



REM exec all test_suite (testsuite!= Regexp; testcase=RegExp)

$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;testcase=.*;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;testcase=testcase.1*;exec

$c\\$_TAF\\taf.pl testsuite=_testsuite2_;testType=tc;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;testType=tc;exec

REM test execution status (1. moving symbol = test-in-prog 2. Current execution status = getWeb_ 3. delete TS
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase1_/2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase2_/1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase3_/3
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;getWeb_=_testcase1_
$c\\$_TAF\\taf.pl testType=tc;delete=$c/$_TAF/_test_suit1_

REM TS Property update 
REM *Verification* _test_suit1_ is removed from disk and webUI
REM
   

REM ------------- Create TC/TS in c:/_testsuite5_/...... ------
REM generate test suite from TS Hook (index.pl)
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;createTS

REM ------------- generate TAF testsuite (c:/_testsuite5_/... -> c:/_TAF/_testsuite5_/...)
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;generateTAFTestsuite 

REM *Verification* TC_TAF $c/$_TAF/_TAF/_testsuiteTestBed/_testsuite?_ should be created and executable
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;exec



REM ------------- Generate Perl testsuite with different tags (_smoketest_, _regression_ ) -----------------------------------

$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl;createTS

$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl;generateTAFTestsuite

REM ------------- Generate sub-Testsuites (_smoketest_, _regression_ ) -----------------------------------
$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite

REM ------------- Generate sub-Testsuies' TAF testsuite ---------------------------------------------------
$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

REM ------------- Generate Summary of Original Testsuite and its TAG Testsuites by testcaseNode=_null_ ---------------------------------------------------

c:\\_TAF\\taf.pl testcaseNode=_null_;testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;generateTAFTestsuite
c:\\_TAF\\taf.pl testcaseNode=_null_;testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl;generateTAFTestsuite

REM ------------- Create Perl-Testsuite Hook and its Test suites /w Tag-based sub-Testsuites (_smoketest_, _regression_ )
REM                  (make sure the ts ends with _powershell_, which indicate a powershell testsuite)


REM ------------- Create Powershell-Testsuite Hook and its Test suites    -  Generate Tag-based sub-Testsuites -------------
$c\\$_TAF\\taf.pl testsuite=c:/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_;createTS

REM ------------- Generate sub-Testsuites (_smoketest_, _regression_ ) -----------------------------------
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite


$c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generateTAFTestsuite	
rem  For powershell only : use index.pl over index.ps1
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_regressiontest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testcaseNode=_null_;TSHookIsPerl=y;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generateTAFTestsuite		
rem combine all the property testsuites
REM ------------- Create Powershell-Testsuite Hook and its Test suites    -  Generate Tag-based sub-Testsuites -------------

REM Demo for generating daily excel report 

REM ------------- Scabiality Test: multi-testsuites and testing scanTestsuite  --------------------------
REM
REM HelloWorld-testbed powershell-Hook (property = _full_, _smoketest_, _regressiontest_)  	Note: _powershell_ indicate the testsuite hook is index.ps1, in stead of index.pl
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4__powershell_;createTS

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite


REM Generate index.ps1 -> index.pl for the original TC

rem $c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1__doit_;generateTAFTestsuite
rem $c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2__doit_;generateTAFTestsuite
rem $c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3__doit_;generateTAFTestsuite
rem $c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4__doit_;generateTAFTestsuite

REM scanTestsuites from testsuite directory  - generate root index.html 

$c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1__doit_;scanTestsuites
$c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2__doit_;scanTestsuites
$c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3__doit_;scanTestsuites
$c\\$_TAF\\taf.pl TSHookIsPerl=y;testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4__doit_;scanTestsuites

REM ------------- Scabiality Test: multi-testsuites and testing scanTestsuite  --------------------------


REM ------------- Update testbed' s _thProperties.txt[s] by generateRootIndex

$c\\$_TAF\\taf.pl printTestBedProperties;generateRootIndex 

REM ------------- TS execution
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0001/2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0002/1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0003/3


rem Mark TS with comments
rem taf.pl testsuite=_testsuite1_;tcComment2=abcd;mark 
\@start "" /b "C:\\Program Files\\Internet Explorer\\iexplore.exe" "$c\\$_TAF\\_testsuite3_\\index.htm"

rem  mark3
rem todo: --------------------- property operation and property filter
rem add/set, createTemplate, del, modify, match/filter, get/list (values,_all_, history, latest, last, value, filters), 
REM Property Operation: add a property
REM Property Operation: set/modify a property
REM Property Operation: get/list a property
REM Property Operation: print TC properties
REM Property Operation: propertyFilter 
REM 
REM	copy testsuites			taf.pl tsFrom=e.txt;tsTo=ee.txt;copyTS   

REM Test the tcFilter functions
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1b_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1c_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1d_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1e_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1f_doit_

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1b_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1c_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1d_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1e_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1f_doit_

REM get TC properties 
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_history_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_last_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_latest_property1

REM del TC properties (remove all the property-values)
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property2_eq_value2a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=del_property2_doit_

REM Modify TC properties (same as add properties - append to thProperty.txt)
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=modify_property3_eq_value3f_doit_

REM print TS/TC tcFilters 
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTCFilters		
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;printTCFilters

REM property match (might need regExp in the future)

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=match_property2_as_value1h_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=match_property1_as_value1h_doit_

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTCFilters

rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOp=set_propverty1_as_value1_doit_
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;propertyOp=set_property1_as_value2_doit_
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;printTCFilters

rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTcFilters
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOp=get_property1
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2 propertyOp=get_property1

REM Old memories 
rem taf.pl 'testsuit=_test_suit1_;create=_testcase1_/overwrite,customTC:c:/tmp/purge.pl_space_1:customTC'
rem taf.pl 'testsuit=_test_suit1_;create=_testcase1_/overwrite,pyAnvil,customTC:c:/tmp/indexPyAnvil.pl_space_1:customTC'

EOF
	open Fout, "> $c/$_TAF/taf.txt"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.txt\n"; my $cmd = "$c/$_TAF/taf.txt"; 
	open Fout, "> $c/$_TAF/taf.bat"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.bat\n";    $cmd = "$c/$_TAF/taf.bat"; 
	if ( &enterY("Execute $c/$_TAF/taf.bat (y/n)? ") =~ /y/) {system $cmd;}
	}
	1;
}



sub enterY { print shift ; $_ = &getYorN(); if (($_ =~ /n/i) || ($_ =~ /^\s*$/)) { return "n"; } if ($_ =~ /y/i) { return "y"; } }

sub timed_input {
    my $end_time = time + shift;
    my $default = "timed_input_default"; $default = shift if (@_);
    my $string ; 
    do {
        my $key = ReadKey(1);
        print $key if defined $key;
        $string .= $key if defined $key;
    } while (time < $end_time);
	return $string;
};

sub getYorN { my $input = &timed_input(6); if ($input) { return $input ; } else { return "n";} }

sub install 		{ &genDriver(); 1; } 	#### install is replaced by genDriver () . it is kept for backwards compatible


sub printTestBedProperties {
	############ Generate taf Property file for _testsuite1_
	mkpath "$c/$_TAF/_testsuite1_";
open Fout, ">$c/$_TAF/_testsuite1_/tsProperty.txt";
my $str = <<EOF;
There is no $c/$_TAF/_testsuite1_/tsProperty.txt for c:/_TAF/_testsuite1_. This is as designed.
EOF
print Fout $str;
close Fout; 
	############ Generate taf Property file for _testsuite1_

	############ Generate taf Property file for _testsuite2_
	mkpath "$c/$_TAF/_testsuite2_";
open Fout, ">$c/$_TAF/_testsuite2_/tsProperty.txt";
$str = <<EOF;
There is no $c/$_TAF/_testsuite2_/tsProperty.txt for $c/$_TAF/_testsuite2_. This is as designed.
EOF
print Fout $str;
close Fout; 
	############ Generate taf Property file for _testsuite2_



	############ Generate taf Property file for _testsuite3_
	mkpath "$c/$_TAF";
open Fout, ">$c/$_TAF/_blabla.html";
$str=<<EOF;
<html><body><pre>
This is a demo for URL link in log 
</pre></body></html>
EOF
print Fout $str;
close Fout; 

open Fout, ">$c/$_TAF/_testLog.txt";
$str=<<EOF;
This is a demo for Log in Log (Recursive Log) 
EOF
print Fout $str;
close Fout; 

	mkpath "$c/$_TAF/_testsuite3_";
open Fout, ">$c/$_TAF/_testsuite3_/tsProperty.txt";
$str = <<EOF;
web_ui_title: Test Automation Framework : web_ui_title
$c/$_TAF/_testsuite3_/testcase0001| 1  Test case 1 description                            Manual edit please     
$c/$_TAF/_testsuite3_/testcase0002| 2  Test case 2 Perform TC  for tsProperty.txt         Manual edit please     
$c/$_TAF/_testsuite3_/testcase0003| 3  Test case 3 Fail TC     for .. tsProperty.txt      Manual edit please     
$c/$_TAF/_testsuite3_/testcase0004| 4  Test case 4 Pass TC     for ... tsProperty.txt     Manual edit please     
$c/$_TAF/_testsuite3_/testcase0005| 5  Test case 5 Fail TC     for .... tsProperty.txt    Manual edit please     
$c/$_TAF/_testsuite3_/testcase0006| 6  Test case 6 TC /w Log   for ..... tsProperty.txt   Manual edit please     
$c/$_TAF/_testsuite3_/testcase0007| 7  Test case 7 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/testcase0008| 8  Test case 8 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/testcase0009| 9  Test case return Expected_f_a_i_l   for ... tsPro  Manual edit please     
$c/$_TAF/_testsuite3_/testcase0010| 10 Test case return expF               for ... tsPro  Manual edit please     
$c/$_TAF/_testsuite3_/testcase0011| 11 Test case return bugF               for ... tsPro  Manual edit please     
EOF
print Fout $str;
close Fout; 

	############ Generate taf Property file for _testsuite3_
	
	mkpath "$c/$_TAF/_testsuite4_";
open Fout, ">$c/$_TAF/_testsuite4_/tsProperty.txt";
$str = <<EOF;
web_ui_title: Testcase/Testsuite Property Operation Test Suite : web_ui_title
$c/$_TAF/_testsuite4_/testcase0001| 1  Test case 1 add testcase Property1 = propertyValue1                       
$c/$_TAF/_testsuite4_/testcase0002| 2  Test case 2 get testcase Property1 = propertyValue1A                      
$c/$_TAF/_testsuite4_/testcase0003| 3  Test case 3 add testsuite Property                                        
$c/$_TAF/_testsuite4_/testcase0004| 4  Test case 4 get testsutie Property
EOF
print Fout $str;
close Fout; 

	############ Generate taf Property file for webUI tc description
	mkpath "$c/$_TAF";
open Fout, ">$c/$_TAF/tsProperty.txt";
print Fout<<EOF;
web_ui_title: Test Automation Framework : web_ui_title
$c/$_TAF/_testsuite1_|001  TAF Testbed 1 : Test Case  Management: TC list, TC execution, TC Reporting /o TC Description
$c/$_TAF/_testsuite2_|002  TAF Testbed 2 : Test Case  Management: TC list, TC execution, TC Reporting /o TC Description 
$c/$_TAF/_testsuite3_|003  TAF Testbed 3 : Test Case  Management: Concurrency, Performance TCs, TC Logging, TC Description 
$c/$_TAF/_testsuite4_|004  TAF Testbed 4 : Test Case  Management: Property operations : add/get properties 

$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1|007  TAF Testbed 7 : Test Suite Management: Multiple test suite coexistence (testsuite1)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1|008  TAF Testbed 8 : Test Suite Management: Multiple test suite coexistence (testsuite2)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1|009  TAF Testbed 9 : Test Suite Management: Multiple test suite coexistence (testsuite3)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1|010  TAF Testbed 10: Test Suite Management: Multiple test suite coexistence (testsuite4)

$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl|011  TAF Testbed 11: ts1: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl|012  TAF Testbed 12: ts2: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl|013  TAF Testbed 13: ts3: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl|014  TAF Testbed 14: ts4: perl testsuite hook /o tags _smoketest_, _regressiontest_

$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl|015  TAF Testbed 15: Test Suite Management: Perl Script Automation    Test Suite 1 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_full_|016  TAF Testbed 16: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_regressiontest_|017  TAF Testbed 17: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_smoketest_|018  TAF Testbed 18: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl|019  TAF Testbed 19: Test Suite Management: Perl Script Automation    Test Suite 2 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_full_|020  TAF Testbed 20: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_regressiontest_|021  TAF Testbed 21: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_smoketest_|022  TAF Testbed 22: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl|023  TAF Testbed 23: Test Suite Management: Perl Script Automation    Test Suite 3 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_full_|024  TAF Testbed 24: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_regressiontest_|025  TAF Testbed 25: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_smoketest_|026  TAF Testbed 26: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl|027  TAF Testbed 27: Test Suite Management: Perl Script Automation    Test Suite 4 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_full_|028  TAF Testbed 28: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_regressiontest_|029  TAF Testbed 29: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_smoketest_|030  TAF Testbed 30: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_|031  TAF Testbed 31: Test Suite Management: Powershell Script Automation Test Suite(_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_full_|032  TAF Testbed 32: Test Suite Management:                                        (_full_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_smoketest_|033  TAF Testbed 33: Test Suite Management:                                        (_smoketest_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_regressiontest_|034  TAF Testbed 34: Test Suite Management:                                        (_regressiontest_) 

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_|035  TAF Testbed 35: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_full_|036  TAF Testbed 36: Test Suite Management: Test Suite Hook (testsuite1/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_regressiontest_|037  TAF Testbed 37: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_smoketest_|038  TAF Testbed 38: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_|039  TAF Testbed 39: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_full_|040  TAF Testbed 40: Test Suite Management: Test Suite Hook (testsuite2/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_regressiontest_|041  TAF Testbed 41: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_smoketest_|042  TAF Testbed 42: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_|043  TAF Testbed 43: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_full_|044  TAF Testbed 44: Test Suite Management: Test Suite Hook (testsuite3/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_regressiontest_|045  TAF Testbed 45: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_smoketest_|046  TAF Testbed 46: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_|047  TAF Testbed 47: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_full_|048  TAF Testbed 48: Test Suite Management: Test Suite Hook (testsuite4/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_regressiontest_|049  TAF Testbed 49: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_smoketest_|050  TAF Testbed 50: Test Suite Management:                                        (_smoketest_)


EOF
close Fout;
1;
}

sub prDriver {
	my $driver=<<EOF;
use Test::AutomationFramework;
use Getopt::Long;
	GetOptions(
	    'processTSs=s'         	      => \\\$processTSs,			
	    'processTCs|settings|s=s'         => \\\$processTCs,			
	    'processTC|tc=s'                  => \\\$processTC,		
	    'processProperty|property=s'      => \\\$processProperty,		
	    'help'                  	      => \\\$help,	
	);
\$TAF = new Test::AutomationFramework;
if (\$help) 		{\$TAF->help();}
if (\$prDriver) 	{\$TAF->prDriver();}
if (\$processTSs) 	{ \$TAF->processTSs(\$processTSs);}
if (\$processTCs) 	{ \$TAF->processTCs(\$processTCs);}
if (\$processProperty) 	{ \$TAF->processProperty(\$processProperty);}
if (\$processTC) 	{ \$TAF->processTC(\$processTC);}
if (\$scanTestsuites) 	{ \$TAF->scanTestsuites();}
\$cmdLine = \$TAF->getTAFArgsFromFile();
if (\$cmdLine) {;} else {foreach \$each (\@ARGV) {\$cmdLine =\$cmdLine.\$each.';'; } }
\$TAF->processTCs(\$cmdLine) if \$cmdLine;
EOF
if (@_) { return $driver;} else { print $driver;}
}


sub prDriverCGI {
	my $driver=<<EOF;
#!c:/strawberry/perl/bin/perl.exe
use strict;
use warnings;
use CGI ":all";
my \$q = new CGI;
my \$tafArgs = "help";
   \$tafArgs = \$q->param("tafArgs");  \$tafArgs =~ s/_semi_/;/g;
my \$tafRedirectory = \$q->param("tafRedirectory");
my \$refreshRate = 5;

print \$q->header(); print \$q->start_html(); print "<pre>";

# ################## add Remove_or_local_execution variable here and in TAF
if ((\$tafArgs =~ /Execution_local_only=y/i) && (\$tafArgs =~ /Execution_from_cgi=y/i)) {
	print "This test can NOT be executed over the network. Pleae execute the test from $hostname/$ip. \\n" ;
} else {
if ((\$tafArgs =~ /exitTAFGracefullyString/i) && (\$tafArgs !~ /;exitTAF/i)) { \$tafArgs = \$tafArgs.";exitTAF";}
#if (\$tafArgs =~ /Again/) { \$refreshRate = 50000000; }
my \$cmd = "start c:/_TAF/taf.pl \$tafArgs";
#print \$q->param("tafArgs"); print "\\n-----------\\n";
#print \$q->param("tafRedirectory"); print "\\n-----------\\n";
print "Running at IP=$ip: \$cmd\\n";
system \$cmd;
}

print<<EOF1;
</pre>
<meta http-equiv="refresh" content="\$refreshRate; url=\$tafRedirectory">
EOF1
print \$q->end_html ;

EOF
if (@_) { return $driver;} else { print $driver;}
}

################################################################################
#	Subroutine Name : getDate
#		Function: get current Datetime 
#	Input Parameters: 
#	Output/Returns  : currentDate in the format of 2010-10-02 12:11:22
################################################################################
sub getDate ( ) {	# 	TH:Generic Functions: get current Time (TH:Generic Functions)
    my ( $y, $m, $d, $hh, $mm, $ss ) = (localtime)[ 5, 4, 3, 2, 1, 0 ];
    $y += 1900;
    $m++;
    my $iso_sale_time =
      sprintf( "%d-%02d-%02d %02d:%02d:%02d", $y, $m, $d, $hh, $mm, $ss );
    $iso_sale_time;
}


sub sortCmdLog {
my %record;
open Fin, "$c/$_TAF/_cmdLogs.txt"; 
while (<Fin>) { if ($_ =~ /(.+)>\s+/) { if ( &Date_Cmp (&DateCalc("now", "+0 day"), &DateCalc("now", $commandLogLifeSpan))  >= 0  ) {$record{$1} = $_;} } } close Fin;
open Fout, "> $c/$_TAF/_cmdLogs.txt_"; foreach my $each (reverse sort keys %record) { $record{$each} =~ s/\s*\n$//g; if ($record{$each}) {print Fout "$record{$each}\n";} } close Fout;
copy ("$c/$_TAF/_cmdLogs.txt_", "$c/$_TAF/_cmdLogs.txt");
}

################################################################################
#	Subroutine Name : appendtoFile
#		Function: append text to a file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFile() {  	# TH:Generic Functions: append to file (TH:Generic Functions)
    my $fname = $_[0];
    open Fout, ">>$fname";
    print Fout "$_[1]";
    close Fout;
}

sub appendtoFileStart() {  	# TH:Generic Functions: append to file (TH:Generic Functions)
    my $fname = $_[0];
    if (-e $fname ) { open Fin, $fname; @_=<Fin>; close Fin;}
    open Fout, ">>$fname";
    print Fout "$_[1]\n";
    print Fout @_;
    close Fout;
}


################################################################################
#	Subroutine Name : appendtoFileFile
#		Function: append file1 to file2
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFileFile() {  	# TH:Generic Functions: append file to file (TH:Generic Functions)
    my $fname = $_[0]; my $fnameOUT = $_[1];
    open Fin, "$fname" || die "Can't open $fname:$!";
    while ($_ = <Fin>) {
    	&appendtoFile($fnameOUT, $_) if ($_ !~ /^\s*$/);
    }
    close Fin;
}


sub appendtoFileUniq_ { # fname, fileContent, maxTCExecTime 
    my $fname         = "e.txt"    ; $fname     = shift if @_; 
    my $content         = ""         ; $content     = shift if @_;
    my $MaxTCExecTime     = 10          ; $MaxTCExecTime= shift if @_; 
    my $fname_         = $fname."_"    ;
    my %record;
    while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
    open Fin ,  "$fname"; while ($_ = <Fin>) { if ($_ =~ /exitTAFGracefullyString=(.+)\s*;\s*exitTAF/) { $record{$1} = $_; } } close Fin;
	if ( $content  =~ /exitTAFGracefullyString=(.+)\s*;\s*exitTAF/) {$record{$1} = $content;}
    open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout $record{$each} } close Fout;
    move ($fname_, $fname);
}

sub appendtoFileUniqly { # fname, fileContent, maxTCExecTime 
     my $fname           = "e.txt"    ; $fname     = shift if @_; 
     my $content         = ""         ; $content     = shift if @_;
     my $MaxTCExecTime     = 10          ; $MaxTCExecTime= shift if @_; 
     my $fname_         = $fname."_"    ;
     my %record;
     while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if (-e $fname) {
     	open Fin ,  "$fname"; while ($_ = <Fin>) { $_ =~ s/\s*\n//g; $record{$_} = $_;  } close Fin; $record{$content}=$content;
     	open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout "$record{$each}\n" if ($record{$each} !~ /^\s*$/); } 
	close Fout;
	move ($fname_, $fname);
     } else {
 	    open Fout , ">$fname" || die "Can't open $fname:$!";
 		print Fout $content;
 	    close  Fout;
     }
}

sub write2File{ # fname, fileContent, maxTCExecTime 
     my $fname           = "e.txt"    ; $fname     = shift if @_; 
     my $content         = ""         ; $content     = shift if @_;
     my $MaxTCExecTime     = 10          ; $MaxTCExecTime= shift if @_; 
     my $fname_         = $fname."_"    ;
     my %record;
     while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	open Fout, ">$fname_"; print Fout $content; close Fout; move ($fname_, $fname);
}


sub copyFile { # fname, fileContent, maxTCExecTime 
     my $fnameFrom         = "e.txt"    ; $fnameFrom     = shift if @_; 
     my $fnameTo           = "e.txt"    ; $fnameTo     = shift if @_; 
     my $MaxTCExecTime     = 10          ; $MaxTCExecTime= shift if @_; 
     # my $fname_         = $fname."_"    ;
     # my %record;
     #while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	copy ($fnameFrom, $fnameTo);
}

################################################################################
#	Subroutine Name : createFile
#		Function: create a new file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub createFile() {  	# TH:Generic Functions: create to file (TH:Generic Functions)
    my $fname = $_[0];
    $fname =~ s/\\/\//g;
    if (-e &getDir($fname)) {;} else {mkpath &getDir($fname);}
    open Fout, ">$fname";
    print Fout "$_[1]\n";
    close Fout;
}

################################################################################
#	Subroutine Name : readFile
#		Function: Read a file
#	Input Parameters: Filename 
#	Output/Returns  : String
################################################################################
sub readFile() {  	# TH:Generic Functions: read file (TH:Generic Functions)
    my $fname = $_[0];
    if ( -e $fname ) {
    open Fin, "$fname";
    @_ = <Fin>;
    close Fin;
    return " @_";
    } else { return "";}
}


################################## STOP TAF Gracefully  ############################################
sub getExitTAFGracefullyLock  { 
	if ( -e $exitTAFGracefullyLock) { 
		open Fin, $exitTAFGracefullyLock || die "Can't open $exitTAFGracefullyLock:$!";
		$_ = <Fin>;
		close Fin;
		if ($_ =~ /exitTAFGracefullyString\s*=\s*(.+)/) {
		return $1;
		}
	} else { return "unlocked"; } 
}
sub detectExitTAFGracefullyLock  { if ( -e $exitTAFGracefullyLock) { return "locked"; } else { return "unlocked"; } }
sub setExitTAFGracefullyLock     { open Fout, ">$exitTAFGracefullyLock"; print Fout "exitTAFGracefullyString=$exitTAFGracefullyString"; close Fout; }
sub releaseExitTAFGracefullyLock { unlink $exitTAFGracefullyLock; } 
sub exitTAF			 { open Fout, ">$exitTAFGracefullyLock"; print Fout "exitTAFGracefullyString=$exitTAFGracefullyString"; close Fout; sleep $outputPause;}
################################## concurrency file log ############################################

sub updateWeb_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
 	my $scrollamount 	= 0 		; $scrollamount = shift if @_;
	my $borderwidth  	= 0 		; $borderwidth  = shift if @_;
	my $borderstyle  	= 'SOLID' 	; $borderstyle  = shift if @_;
	my $movingString 	= '>' 	 	; $movingString = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	@_ = split (/,/ , $scrollamount);
	if ($_[0]) { $scrollamount = $_[0];}
	if ($_[1]) { $borderwidth= $_[1];} 
	if ($_[2]) { $borderstyle= $_[2];} 

	if ($movingString =~ /runTC/i) { $movingString = '>'; }
	if ($movingString =~ /runTS/i) { $movingString = '>>'; }

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	############ BEGIN #############
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  />(\S+)<\/marquee>/;  my $movingString_ = $1; 
				if ($movingString_) {;} else { $movingString_ = '>>'; }
 				$_ =~ s/>$movingString_<\/marquee>/>$movingString<\/marquee>/;
 				$_ =~  /scrollamount=\s*(\d+)\s*/;  my $scrollamount_ = $1; if ($scrollamount_) {;} else { $scrollamount_ = 0; }
 				$_ =~ s/scrollamount=\s*$scrollamount_\s*/scrollamount=$scrollamount/;

				$_ =~  /border:RED\s+(\d+)\s*px/;  my $borderwidth_ = $1;  if ($borderwidth_) {;} else { $borderwidth_ = 0; }
 				$_ =~ s/border:RED\s*$borderwidth_\s*px/border:RED ${borderwidth}px/;

				$_ =~  /(border:RED\s+\d+\s*px\s+)(DASHED|SOLID|DOTTED)"/;  my $borderstyle_= $2;  if ($borderstyle_) {;} else { $borderstyle_ = 'SOLID'; }
				$_ =~ s/(border:RED\s+\d+\s*px\s+)$borderstyle_"/${1}${borderstyle}"/ ; 
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;
		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	} ############ END ###############

	############ BEGIN #############
	my $fname_http =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_") { my $mtime = ( stat $fname_http)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  /scrollamount=\s*(\d+)\s*/;  my $scrollamount_ = $1; if ($scrollamount_) {;} else { $scrollamount_ = 0; }
 				$_ =~ s/scrollamount=\s*$scrollamount_\s*/scrollamount=$scrollamount/;

				$_ =~  /border:RED\s+(\d+)\s*px/;  my $borderwidth_ = $1;  if ($borderwidth_) {;} else { $borderwidth_ = 0; }
 				$_ =~ s/border:RED\s*$borderwidth_\s*px/border:RED ${borderwidth}px/;

				$_ =~  /(border:RED\s+\d+\s*px\s+)(DASHED|SOLID|DOTTED)"/;  my $borderstyle_= $2;  if ($borderstyle_) {;} else { $borderstyle_ = 'SOLID'; }
				$_ =~ s/(border:RED\s+\d+\s*px\s+)$borderstyle_"/${1}${borderstyle}"/ ; 
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http);
	} ############ END ###############

#	move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	return "tcCtr_Dynamics=$scrollamount";
}

sub mergeFile_ {
 	my $indexFName = "index.htm"		; $indexFName   = shift if @_; 
 	my $reportFName = "_tcReport_.html"	; $reportFName  = shift if @_;
        my $MaxTCExecTime     = 10          	; $MaxTCExecTime= shift if @_; 

	$indexFName =~ s/\\/\//g; # todo10 \\
	$reportFName =~ s/\\/\//g; # todo11 \\

 	my %index; my $indexFName_ = $indexFName."_"; 
        while (-e $indexFName_) { my $mtime = ( stat $indexFName)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if ( -e $indexFName)  {open Fin, $indexFName ; while ($_ = <Fin> ) { if ($_ =~ /$_TAF\/(.+)\/_tcLog.html/) { $_ =~ /$_TAF\/(.+)\/_tcLog.html/; $index{$1} = $_; } } close Fin; }
 	if ( -e $reportFName) {open Fin, $reportFName; while ($_ = <Fin> ) { if ($_ =~ /$_TAF\/(.+)\/_tcLog.html/) { $_ =~ /$_TAF\/(.+)\/_tcLog.html/; $index{$1} = $_; } } close Fin; }
}

sub updateWeb1_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
	my $tcHtml        	= "" 	 	; $tcHtml = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1");

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	my $findMatch = 'n';
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
				$_ = $tcHtml;
				$findMatch ='y';
 			} 

			# Update Testsuite properties on Test case level
			if ( $_ =~ /\(Avg Time is\s+(\d+:\d+:\d+)\)/) { $_ =~ s/Avg Time is $1/Avg Time is $testsuiteTotalExecTime/; }
 			print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	}
	return 1;
}

sub updateWeb1Http_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
	my $tcHtml        	= "" 	 	; $tcHtml = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1");

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	my $findMatch = 'n';
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
				$_ = $tcHtml;
				$findMatch ='y';
 			} 

			# Update Testsuite properties on Test case level
			if ( $_ =~ /\(Avg Time is\s+(\d+:\d+:\d+)\)/) { $_ =~ s/Avg Time is $1/Avg Time is $testsuiteTotalExecTime/; }
 			print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http);
	}
	return 1;
}

sub resetTSFile { # fname, fileContent, maxTCExecTime 
	my $fname = "$SvrDrive/$SvrProjName/$resetTSFileName";   $fname = shift if @_; 
	my $content = "";
 	my $MaxTCExecTime 	= 10 	 	; $MaxTCExecTime= shift if @_; 
 	my $fname_ 		= $fname."_"	;
 	while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
 	open Fout, ">$fname_" or die $!;
 	print Fout $content; 
 	close Fout;
 	move ($fname_, $fname);
	print " <-> Reset $SvrDrive/$SvrProjName/$resetTSFileName - Done\n"; 
	1;
}

sub createFile_ { # fname, fileContent, maxTCExecTime 
	my $fname 		= "e.txt"	; $fname 	= shift if @_; 
	my $content 		= ""	 	; $content 	= shift if @_;
	my $MaxTCExecTime 	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $fname_ 		= $fname."_"	;
	while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	mkpath &getDir($fname_); 
	open Fout, ">$fname_" or die $!;
	print Fout $content; 
	close Fout;
	move ($fname_, $fname);
	1;
}

sub appendtoFile_ { # fname, fileContent, maxTCExecTime 
	my $fname 		= "e.txt"	; $fname 	= shift if @_; 
	my $content 		= " "	 	; $content 	= shift if @_;
	my $MaxTCExecTime 	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $fname_ 		= $fname."_"	;
	if (-e $fname) {;} else { &createFile($fname,"");}

	while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }

	copy ($fname, $fname_);
	open Fout, ">>$fname_" or die $!;
		if ($content) {;} else { $content = "";}
	print Fout $content; 
	close Fout;
	move ($fname_, $fname);
}

sub appendtoFileFile_ {  	# TH:Generic Functions: append file to file (TH:Generic Functions)
    my $fname = $_[0]; my $fnameOUT = $_[1];
    open Fin, "$fname" || die "Can't open $fname:$!";
    my $content;
    while ($_ = <Fin>) {
	    if ($_ !~ /^\s*$/) {$content = $content .$_; } 
    }
    close Fin;
    	&appendtoFile_($fnameOUT, $content) ;
}

################################## concurrency file log ############################################
sub getRoot   { my $string = shift; @_ = split /\\|\//, $string; 			return $_[$#_]; }	# return tc.pl
sub getRoot_1 { my $string = shift; @_ = split /\\|\//, $string; 			return $_[$#_-1]; }	# remove tc.pl
sub getRoot_2 { my $string = shift; $string =~ s/\\/\//g; $string =~ s/\/$tc_pl//; 	return $string;   }	# remove c:\
sub getRoot_3 { my $string = shift; @_ = split /\\|\//, $string; 			# remove c:\
	if    ($#_ == 1) { return $_[$#_]; }
	elsif ($#_ == 2) { my $tmp = $#_ -1; return $_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 3) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  return $_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 4) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  my $tmp2 = $#_ - 3; return $_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 5) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  my $tmp2 = $#_ - 3; my $tmp3 = $#_ - 4; return $_[$tmp3].'/'.$_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
}
sub getRoot_4 { my $string = shift; $string =~ s/\w:[\/|\\]//; $string =~ s/\s*\/\s*$//; return $string;  }	# remove c:\ yw remove last /

sub getDir  { my $string = shift; my $root =&getRoot($string); $string =~ s/([\\|\/])?$root//i; return $string;  }

sub prJScript {
	
my $indexHtml =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="$htmlRefreshRateLogUI"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR "$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
</head>
<body><pre>
EOF
# <!-script type="text/javascript"> if (navigator.appName != "Microsoft Internet Explorer") alert("Please use IE to access TAF's webUI") </script>
return $indexHtml; 
}
sub prHtml1_strGen() {
	my $localUrl = $url; $localUrl = shift if @_;	
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); 
	my $tcDescTitle 	= "<a href=\"${localUrl}/$SvrProjName/_generateExcelReport.html\" title=\"Link to Daily Report. Below link to TC Logs\">"; 
	   $tcDescTitle 	= sprintf "$tcDescTitle%-${webUI_TCDescWidth}s</a>","   ------------------Testcase Description------------------";
	my $TCCtrToolTip 	= sprintf "Run Test Suite 24/7 (Avg Time is $testsuiteTotalExecTime)"; 
	if ($Execution_24_7_title =~ /n/i) { $TCCtrToolTip = sprintf "Run Test Suite (Avg Time is $testsuiteTotalExecTime)";} 
	my $execTS 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;Execution_24_7=$Execution_24_7_title;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;exec')\" title=\"$TCCtrToolTip\"> Exec</a>");
	my $stopTS 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName exitTAFGracefullyString=exitTAF;exitTAF')\" title=\"Stop Test Execution gracefully\" >.</a>");
	my $markTS 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;Execution_24_7=n;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;mark')\" title=\"Make the beginning of a execution by \|\"> \|</a>");
	my $listTSUnderTest     = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=$testcaseNode;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseNode=testcase;titleStatus=(UnderTestDontUse);list')\" title=\"Display UnderTestDontUser\">    </a>");
	my $listTS 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=$testcaseNode;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseNode=testcase;list')\" title=\"Update webUI /o Tags (default)\">S</a>");
	my $listTSAll 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=_null_;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;list')\" title=\"Update webUI /w Tags\">U</a>");
	my $updateTS  		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=$testcaseNode;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;createOrAppendTS=append;testsuit=$c/$SvrProjName;generateTAFTestsuite')\" title=\"Update webUI /o Tags (default)\">S</a>");
	my $listTAFTestBed   	= sprintf("<a href=\"${localUrl}/taf.txt\" title=\"Display TAF Testbed scripts\">E</a>");
	my $indexthProperty 	= sprintf("<a href=\"${localUrl}/$SvrProjName/tsProperty.txt\" title=\"Display TS property\">L</a>");
	my $tafGlobalVars 	= sprintf("<a href=\"${localUrl}/_tafGlobalVars.txt\" title=\"Display TAF Global Variables\">T</a>");
	my $indexCmdLog   	= sprintf("<a href=\"${localUrl}/_cmdLogs.txt\" title=\"Display TAF Cmd History\">S</a>");
	my $indexFailed 	= sprintf("<a href=\"${localUrl}/$SvrProjName/index_failed.htm\" title=\"Display *Failed* TCs\">Fail</a>");
	my $indexPassed 	= sprintf("<a href=\"${localUrl}/$SvrProjName/index_passed.htm\" title=\"Display *Passed* TCs\">Pass</a>");
	my $indexOthers		= sprintf("<a href=\"${localUrl}/$SvrProjName/index_others.htm\" title=\"Display *others* TCs\">/</a>");
	my $indexUrlIIS 	= sprintf("<a href=\"${url}/$SvrProjName/index_http.htm\" title=\"$web_ui_title_tip\"> <font color=\"white\">TC Manual Command</font></a>");
	my $indexSeconds 	= "<a title=\"Total TS Execution time = $testsuiteTotalExecTime (s) \">(sec)</a>";
	my $indexTitle 		= sprintf("<a href=\"${localUrl}/index.htm\" title=\"View *all* Testsuites\">$web_ui_title</a>");
	my $indexResult 	= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"testofUpdate\">".substr ("Result                                                                                                                                               ", 0, $passFailDisplayWidth-7)."</a>");
	my $tmp10 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"$reportHtmlSummaryStr\">");
	my $passFailDisplay = &genPassFailDisplay("");

	if ( $localUrl =~ /^\s*http:/) {
	$indexTitle  = sprintf("<a href=\"${localUrl}/index_http.htm\" title=\"$web_ui_title_tip\">$web_ui_title</a>");
	$indexFailed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_failed.htm\" title=\"Display *Failed* TCs\">Fail</a>");
	$indexPassed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_passed.htm\" title=\"Display *Passed* TCs\">Pass</a>");
	$indexOthers = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_others.htm\" title=\"Display *others* TCs\">/</a>");
	}
	
my $indexHtml =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="$htmlRefreshRate"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR "$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
</head>
<script type="text/javascript"> if (navigator.appName != "Microsoft Internet Explorer") alert("Please use IE to access TAF's webUI") </script>
<body>
<pre>
<p>
<h2> ${titleStatus}${indexTitle}$listTSUnderTest</h2>
${indexResult}${listTAFTestBed}${updateTS}${listTSAll}${indexthProperty}${tafGlobalVars}${indexCmdLog} ${stopTS}${markTS}${execTS} <a title=\"Click Testcase Desc to view TC logs\">$tcDescTitle      ${indexPassed}${indexOthers}${indexFailed}       ${indexSeconds}       ${indexUrlIIS}  </span>
EOF
	return $indexHtml; 
	}

sub prHtml1_strGen_CGI() {
	my $localUrl = $url; $localUrl = shift if @_;	
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); 
	my $tcDescTitle = "<a href=\"${localUrl}/$SvrProjName/_generateExcelReport.html\" title=\"Link to Daily Report. Below link to TC Logs\">"; 
	   $tcDescTitle = sprintf "$tcDescTitle%-${webUI_TCDescWidth}s</a>","   ------------------Testcase Description------------------";
	my $TCCtrToolTip = sprintf "Run Test Suite 24/7 (Avg Time is $testsuiteTotalExecTime)"; 
	if ($Execution_24_7_title =~ /n/i) { $TCCtrToolTip = sprintf "Run Test Suite (Avg Time is $testsuiteTotalExecTime)";} 
	my $execTS =  sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=Execution_from_cgi=y;Execution_local_only=$Execution_local_only;SysDrive=$SvrDrive;performanceMode=fast;Execution_24_7=$Execution_24_7_title;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;exec_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"$TCCtrToolTip\"> Exec</a>");
	my $stopTS =  sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=exitTAFGracefullyString=exitTAF;exitTAF_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Stop Test Execution gracefully\" >.</a>");
	my $markTS =  sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=SysDrive=$SvrDrive;performanceMode=fast;Execution_24_7=n;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;mark_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Make the beginning of a execution by \|\"> \|</a>");
	my $listTSUnderTest =  sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=$testcaseNode;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseNode=testcase;titleStatus=(UnderTestDontUse);list_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Display (UnderTestDontUse)\">    </a>");
	my $listTS =  sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=$testcaseNode;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseNode=testcase;list_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Update webUI /o Tags (default)\">S</a>");
	my $listTSAll=sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=SysDrive=$SvrDrive;performanceMode=fast;testcaseNode=_null_;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;list_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Update webUI /w Tags\">U</a>");
	my $updateTS =sprintf("<a href=\"${localUrl}/$tafCGI?tafArgs=SysDrive=$SvrDrive;performanceMode=fast;tcPropertyPatternPattern=$tcPropertyPatternPattern_;createOrAppendTS=append;testsuit=$c/$SvrProjName;generateTAFTestsuite;list_realSemi_tafRedirectory=${localUrl}/$SvrProjName/$reportHtml_http\" title=\"Update webUI /o Tags (default)\">S</a>");

	$execTS =~ s/;/_semi_/g; $execTS =~ s/_realSemi_/;/g;
	$stopTS =~ s/;/_semi_/g; $stopTS =~ s/_realSemi_/;/g;
	$markTS =~ s/;/_semi_/g; $markTS =~ s/_realSemi_/;/g;
	$listTSUnderTest =~ s/;/_semi_/g; $listTSUnderTest =~ s/_realSemi_/;/g;
	$listTS =~ s/;/_semi_/g; $listTS =~ s/_realSemi_/;/g;
	$listTSAll =~ s/;/_semi_/g; $listTSAll =~ s/_realSemi_/;/g;
	$updateTS  =~ s/;/_semi_/g; $updateTS=~ s/_realSemi_/;/g;

	my $listTAFTestBed      = sprintf("<a href=\"${localUrl}/taf.txt\" title=\"Display TAF Testbed scripts\">E</a>");
	my $indexthProperty 	= sprintf("<a href=\"${localUrl}/$SvrProjName/tsProperty.txt\" title=\"Display TS property\">L</a>");
	my $tafGlobalVars 	= sprintf("<a href=\"${localUrl}/_tafGlobalVars.txt\" title=\"Display TAF Global Variables\">T</a>");
	my $indexCmdLog   	= sprintf("<a href=\"${localUrl}/_cmdLogs.txt\" title=\"Display TAF Cmd History\">S</a>");
	my $indexFailed 	= sprintf("<a href=\"${localUrl}/$SvrProjName/index_failed.htm\" title=\"Display *Failed* TCs\">Fail</a>");
	my $indexPassed 	= sprintf("<a href=\"${localUrl}/$SvrProjName/index_passed.htm\" title=\"Display *Passed* TCs\">Pass</a>");
	my $indexOthers		= sprintf("<a href=\"${localUrl}/$SvrProjName/index_others.htm\" title=\"Display *others* TCs\">/</a>");
	my $indexUrlIIS		= sprintf("<a href=\"${url}/$SvrProjName/index_http.htm\" title=\"$web_ui_title\"> <font color=\"white\">TC Manual Command</font></a>");
	my $indexSeconds 	= "<a title=\"Total TS Execution time = $testsuiteTotalExecTime (s) \">(sec)</a>";
	my $indexTitle 		= sprintf("<a href=\"${localUrl}/index.htm\" title=\"$web_ui_title_tip\">Test Automation </a>");
	my $indexResult		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"Latest TC pass/fail (Gree/Red) Click to Display Test Suite Summary\">".substr ("Result                                                                                                                                               ", 0, $passFailDisplayWidth-7)."</a>");
	my $tmp10 		= sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"$reportHtmlSummaryStr\">");
	my $passFailDisplay 	= &genPassFailDisplay("");

	if ( $localUrl =~ /^\s*http:/) {
	$indexTitle  = sprintf("<a href=\"${localUrl}/index_http.htm\" title=\"$web_ui_title_tip\">$web_ui_title</a>");
	$indexFailed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_failed.htm\" title=\"Display *Failed* TCs\">Fail</a>");
	$indexPassed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_passed.htm\" title=\"Display *Passed* TCs\">Pass</a>");
	$indexOthers = sprintf("<a href=\"${localUrl}/$SvrProjName/index_http_others.htm\" title=\"Display *others* TCs\">/</a>");
	}
	
my $indexHtml =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="$htmlRefreshRate"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR "$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
</head>
<body>
<pre>
<p>
<h2> ${titleStatus}${indexTitle}($hostname/$ip)$listTSUnderTest</h2>
${indexResult}${listTAFTestBed}${updateTS}${listTSAll}${indexthProperty}${tafGlobalVars}${indexCmdLog} ${stopTS}${markTS}${execTS} <a title=\"Click Testcase Desc to view TC logs\">$tcDescTitle      ${indexPassed}${indexOthers}${indexFailed}       ${indexSeconds}       ${indexUrlIIS}  </span>
EOF

	return $indexHtml; 
	}


sub prHtml1 {		# print index.htm beginnings
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); 
&createFile_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, '' );
&createFile_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, '' );
my $str =<<EOF;
taf.pl       : TAF Driver    
taf.bat      : TAF testbed setup
tc.pl        : TC hook       
_tcAppend.txt: TC log  hook 
EOF

&readTestSuitProperty();
my $indexHtml = &prHtml1_strGen($url); 
&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, $indexHtml);

my $indexHtml_http = &prHtml1_strGen_CGI($urlHttp); 
&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, $indexHtml_http);
}

sub prHtml2 {	# print index.htm endings
my $html =<<EOF;
</pre></body>
</html>
<style type="text/css"> a { text-decoration:none} </style> 
EOF
 &appendtoFile_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, $html );
 &appendtoFile_( $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, $html );
}



__END__
		TAF Function Requirement Summary  (Sept 27, 2011)
------------------------------------------------------------------------------------------
TH Function Category     Function Name            Function Description
------------------------------------------------------------------------------------------
TH:TC Managements        logIsValid               Verify if a log is valid by comparing TC created T and log create T Commented Done 
TH:TC Managements        tcRunningYN              get the TC result Pass/Fail                                         Commented Done
TH:TC Managements        getProperty              get TC Property Names                                               Commented Done
TH:TC Managements        getPropertyValues        get TC Property Values                                              Commented Done
TH:TC Managements        deleteProperty           delete TC Property                                                  Commented Done
TH:TC Managements        addProperty              add TC Property                                                     Commented Done
TH:TC Managements        modifyProperty           modify TC Property                                                  Commented Done
TH:TC Managements        appendPropFile           append to TC Property File                                          Commented Done
TH:TC Managements        createPropFile           create TC Property File                                             Commented n/a
TH:TC Managements        readProperty             Read TC Property                                                    Commented n/a
TH:TC Managements        updateTCResultProperty   Update TC Property                                                  Commented n/a
TH:TC Managements        genTC                    Generate a HelloWorld TC                                            Commented Done

TH:TC Report             Report                   TC Report Function                                                  Commented Done
TH:TC Report             reportUpdateOnWeb        update TC Report on webUI                                           Commented 
TH:TC Report             logExist                 Determine if a log exists                                           Commented Done

TH:TC Execution          ReportAvgResponseTime    report TC Average Response Time                                     Commented n/a
TH:TC Execution          lastPassFail             get the latest TC Pass/Fail Result                                  Commented Done
TH:TC Execution          longivityPeriod          If the TC in LongivityPeriod                                        Commented 

TH:WebUI                 thWebUIUpdate            Update the webUI based on thProperty.txt                            Commented v2
TH:WebUI                 tcStatusHtmlSync         synchrinize the HTML with with TC Result                            Commented v2
TH:WebUI                 tcStatusHtml             Display the TCStatuse in Html format                                Commented v2
TH:WebUI                 rearrangeWebUI           Update webUI based on thProperty.txt                                Commented v2
TH:WebUI                 tcLog2Web                Update TC Log on webUI                                              Commented v2

TH:Concurrency Control   tcRunningYNOther         get the running TC Status for Concurrency Control.                  Commented v2          
TH:Concurrency Control   tcScheduledYNOther       get the scheduled TC for Concurrency Control.                       Commented v2
TH:Concurrency Control   tcQueue                  TC Queue function for Concurrency Control.                          Commented v2
TH:Concurrency Control   tcDeQueue                TC deQueue for Concurrency Control                                  Commented v2

TH:Email Notification    emailNotification        Process the Outlook email Notification Commands                     Commented v3  
TH:Conti. Integration    thBuzRule                Handle Continuous Integration                                       Commented v3

TH:Assist Functions      genTimeStr               time format function                         			      Commented	                                   
TH:Assist Functions      getIP                    TH:Generic Functions: get IP of local machine                       Commented 
TH:Assist Functions      genThProperty            generate TH property file                                           Commented  
TH:Assist Functions      printLibraryFun          print QTP Library Functions                                         Commented 
TH:Assist Functions      readTestHarnessCmdLine   read Test Harness Cmd Line args                                     Commented 
TH:Assist Functions      genQTPInputs             generate QTP Input files                                            Commented 
TH:Assist Functions      thPropertyUpdate         update TH property                                                  Commented 
TH:Assist Functions      prHelp_short             Print the short Help                                                Commented todo
TH:Assist Functions      prHelp                   print lengthy Help                                                  Commented 
TH:Assist Functions      genQTPDriver             Generic qtpDriver                                                   Commented 
TH:Assist Functions      genQTPLibrary            Generate QTP Library                                                Commented 
TH:Assist Functions      genCmd                   Generate the Test Harness ASP files                                 Commented 

TH:Generic Functions     appendtoFile             TH:Generic Functions: append to file                                Commented Done
TH:Generic Functions     createFile               TH:Generic Functions: create a file                                 Commented Done
TH:Generic Functions     getDate                  TH:Generic Functions: get current Time                              Commented Done
TH:Generic Functions     reverse                  TH:Generic Functions: reverse a Associate Array                     Commented            
TH:Generic Functions     strLen                   Generic Functon: return Str len                                     Commented            
TH:Generic Functions     decrCtr                  Decrease Ctr                                                        Commented            
TH:Generic Functions     incrCtr                  Increase Ctr                                                        Commented            
TH:Generic Functions     getCtr                   Get Ctr                                                             Commented 
TH:Generic Functions     getCurrentTime           TH:Generic Functions: getCurrentTime                                Commented 
TH:Generic Functions     getHost                  getHost function done by SZ Team Charlie and David                  Commented 
TH:Generic Functions     getHostFromIP            Get Host done by SZ Team Charlie and David                          Commented               

------------------------------------------------------------------------------------------


=head1 NAME
Test::AutomationFramework - Test Automation Framework  (TAF)

=head2 SYNOPSIS
	1. Download and install Test::AutomationFramework from CPAN
	2. DOS>perl -MTest::AutomationFramework -e "help"
	3. A WebUI is created, which can display and execute, as well as view test case by *ONE* mouse click
	3. Modify taf.bat for the automated test suit structures 
	4. Modify c:\[test_suit]\[test_case]\tc.pl to plug-in the customer test case
	5. Execute taf.bat to get the webUI
	6. Run test cases, view test result, view test logs with mouse click only. - Enjoy TAF
	7. Please email ywangperl@gmail for questions/suggestions/bugs 

=head2 DESCRIPTION
	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reult reportings without any programming nor reading user manual. 

	TAF defines a automated test case as [c:]\[test_suite]\[test_case]\tc.pl
		tc.pl returns Pass|fail|numerical number
		tc.pl creates tc's log file as [c:]\[test_suite]\[test_case]\tc.pl
		tc.pl creates test suite's webUI at [c:]\[test_suite]\index.htm 

=head1  LICENSE
	This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=head1 AUTHOR
    	Yong Wang (ywangperl@gmail.com)

=cut;


1;



taf.pl 'testsuit=_default_testsuite_;create=testcase01/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_1:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase02/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_2:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase03/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_3:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase04/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_4:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase05/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_5:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase06/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_6:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase07/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_7:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase08/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_8:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase09/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_9:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase10/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_10:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase11/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_11:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase12/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_12:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase13/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_13:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase14/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_14:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase15/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_15:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase16/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_16:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase17/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_17:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase18/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_18:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase19/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_19:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase20/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_20:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase21/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_21:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase22/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_22:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC'


-- history/good memory --

taf.pl testsuit=propertyChangedEvent;list
rem taf.pl testsuit=propertyChangedEvent;exec
rem taf.pl testsuit=propertyChangedEvent;updateWeb=_testcase2_/1
* using the directory recursive for searching testcases
* CustomTC:....:CustomTC

__END__

#################### Todo list: Functional Requirements ################################
# * Improvement: AutomationFramework.t won't work with dmake 
# * Bug: Execution_24_7 won't update the historical &reportTCSummary () -done 04/20/2013
# * Bug: Testsuite <- Testsuite displays default. Not real TS 		-done 04/20/2013
# * Bug:  Variable is treated as testsuite ( if -e $tcname ) 		-done 04/20/2013
# * Improvement: treat c:\_TAF ($c/$_TAF) is a global variable 		-done 04/20/2013
# * Improvement: self-identify local-execution or Execution_from_cgi    -done 04/17/2013
#   TC Variables should overwrite TS variables (TC over TS when no TS	-done 04/17/2013
# * Improvement: Testsuite/Testcase local execution only (taf.cgi) 	-done 04/17/2013
#   updateTAFTSVars, updateTAFTCVars, updateTAFVars                 	-done 04/1y/2013
#   clearTAFTSVars, clearTAFTCVars, clearTAFTSVars, readTAFTCVars 	-done 04/1y/2013
#   printTAFTSVars, printTAFTCVars, readTAFTSVars, readTAFTCVars 	-done 04/15/2013
# * bug: taf.pl ts=_ts_  create a invalid c:\_TAF\_ts_			-done 04/13/2013
# * Request: disable Execution_24_7 on the title line (sub readTAFTSVar)-done 04/10/2013 <- TestBed:_testsuite1_->title.Exec won't run 24/7
# * Improvement: Testsuite search won't take regexp (as testcase does) 
# * bug: generateTestsuiteByDesc uses wrong index.pl # 	(_tcMap.txt)    -doen 04/03/2013
# * add sub runFromGmailService for gmail interaction			-done 03/30/2013 <-
# * add sub runFromGmail        for gmail interaction			-done 03/30/2013
# * add sub getTSNameFromTSDesc for gmail interaction			-done 03/30/2013
# * Add a service of fetchmail and triger behind webUI is good     	
# * sub fetchGmail	as a place holder
# * improve: exit status = manl for manual test 
# * Bug see Todo: &processTCs won't gernerate _list_tcDesc.txt 
# * improvement: propertyExecCtrEqZero (24_7 & propertyOp won't exit) 	-obsolete
# * add <body OnLoad function to getGamil and create c:\_TAF\_TAFArgs.txt -replaced by the following
# * improvement: the c:\_TAF\index.htm and index_http is not updated 	-deon 03/30/2013 (generateRootIndex after updateWeb)
# * sub getTAFArgsFromFile (c:\_TAF\_tafArgs.txt) 			-done 03/27/2013
#   modify the genDrive_taf_pl to show the change 			-done 03/27/2013
# * improvmemt: no more taf.pl recursive call				-done 03/27/2013
# * bug: fixing special character bug introduce < in &lt; broke loglink -done 03/21/2013 (add _url_link_)
# *    : should create http for http.htm                                                                    
# * remote installation? or create c:\_TAF from installation 
# * add titleStatus for maintenance info titleStatus=(UnderMaint);list  -done 03/19/2013
# * add sub listTS aka updateTS 					-done 03/19/2013
#   Technical point: reDirect variable is passed to taf.cgi		-done 03/19/2013	
# * add Global createOrAppendTS  to handle append TC to TS 		-done 03/19/2013
#   append new TC in the webUI sub createPropertyTemplate() 		-done 03/18/2013  	
# * tcDesc display special characters  < > will dis-align the webUI (work around < lessThan > greaterThan see        #### special character -> Conversion  in progress. Testbed is done with _testsuite5_
#          modify sub runPowershell and sub                             -done 03/14/2013
# * improvement: delete TS/TC by clicing webUI component
# * test delete TS/TC scenario
# * bug? htmlRefreshRate is not read from _tafGlobal.txt 
# * bug? webUI_tcDescWidth is not read from _tafGlobal.txt 
# * todo: need do a mass copy/replace commands from linux sed ? 
# * Improvement: a TS with 100 testcases to test the performance   
# * check _url_line_ for _logTC is treated as URL no < replace		-done 03/14/2013
# * improvement: htmlRefreshRate for webUI (fast) and for logUI (slow) 	-done 03/14/2013
# * Req: tcDesc can't have xml tags from the tcDesc for property display-done 03/12/2013
# * bug # bug: parsing tcSerialN failed	- sprintf error			-done 03/12/2013
# * todo: test different $c/$_TAF scenarios (work around available) 	-postponed
# * improvement: Title of TS + propertyTS needs retrunHtml ...	    	-postponed
# * _generateExcelReport.html (alignment for , )		    	-postponed
# * improvement: tcDesc width can be self-adjusted		    	-postponed
# * bug sometimes TS has not testcases (*U*pdate is the workaround) 	-postponed
# * href> in the _tcLogAppend.txt (sub addURL) 				-done 03/07/2013 
# * improvement: add bugF return state					-done 03/07/2013 
# * bug: < > @ in _tcLogAppend.txt to tcLog.htm sub addURL()a		-done 03/06/2013 <more char # ...>
# * bug: <a> </a> in _tcLogAppend.txt should be &lt; &gt; 	  	-done 03/06/2013
# * todo: remove javascripts in the html title 		invalid		-ign  03/04/2013
# * Improvement: add a exec URL in tc_log and tc_log_http.htm 		-done 03/04/2013
# * improvement: tcDesc has c:\_TAF too short by removeTags/match1stReg -done 03/02/2013
# * bug: tcDesc = _..._ should not remove '/' by removeTags 		-done 03/02/2013
# * improvement: add performanceMode=fast to webUI cmds			-done 03/01/2013
# * improvement: add performanceMode=fast to generateTestsuiteAgain	-done 03/01/2013
# * improvement: add nullCtr to display total execution time for null 	-done 03/01/2013
# * performance improvement move updateTCPassFAil to Post 		-done 02/28/2013
# * performance improvement move reportHistory to tcPost		-done 02/28/2013
# * performance improvement ping -n 1 localhost 			-done 02/28/2013
# * overWriteTC = 'y'  ***Default is overwrite***			-done 02/28/2013
# * bug: duplicated serial # in the tcDesc  #### Fix duplicated serial  -done 02/27/2013
# * improment: combine tags with the tcDesc			 	-done 02/28/2013
# * bug: command history is not updated by HTA, only by Httpd (No BUG) 	-done 02/24/2013
# * bug (sec)-Tip is total time Work-around: use Total TS Exec Time. 	-done 02/24/2013
# * improvement: test hook color grey->white				-done 02/24/2013
# * add testcaseNode commandline 					-done 02/24/2013
# * improvement: Title of TS + propertyTS needs testcaseNode=_null_ for *U*  -done 02/24/2013
# * update the _tafGlobal_txt after setGlobal (testcaseNode) outdated   -done 02/23/2013
# * bug "Use uniniatialize $cmd 1807 "					-done 02/23/2013
# * testcaseNode=_null_ will set testcaseNode = ""			-done 02/21/2013
# * generateTAFTestsuite including subTS by testcaseNode = "" 		-done 02/21/2013
# * use Term::ReadKey for the enterY() 					-done 02/21/2013
# * bug:  recursive usage of creating propertyTS by generatePropertyTS  -done 02/16/2013
# * bug: ResultString width is max-so-far during generateTestsuiteAgain -done 02/15/2013
# * ouptputFormat = text|no|html 
# * handle no httpd service scenario (ping localhost)			-done 02/14/2013
# * taf.pl generateTestsuiteAgain (Can't be executed by webUI)		-done 02/14/2013
# * add taf.pl generateTestsuiteAgain to the title			-done 02/14/2013
# * outputPause = 5 							-done 02/14/2013
# * Bug: web_ui_title should from readTSProperty (not readTAFProperty)  -done 02/13/2013 
# * modify taf.cgi 							-done 02/11/2013
# * htmlRefreshRate = 20						-done 02/11/2013
# * add ip as a global variable						-done 02/11/2013
# * modify prHtml2 for http						-done 02/09/2013
# * add prHtml1_strGen_CGI() for http title line			-done 02/08/2013
# * Integration with mongoose web server				-done 02/08/2013
# * backslash \ as a variable (for unix migration) 
# * add genDriver_taf_CGI						-done 02/08/2013
# * add CGI support for the index_http.html
# * c:\_TAF independency (change $_TAF will change different testsuite  -done 01/31/2013
# * add URL to c:\_TAF\taf.bat (taf.txt)                     		-done 01/29/2013
# * add tsProperty.txt for testsuite1 and testsuite2			-done 01/29/2013
# * bug mapTC shadows the listTC/execTC $rst				-done 01/23/2013 
# * bug when there is no tags (_full_ and _smoketest_), _full_ will break the TAF
# * create testbed regression 
# * modify the ps1_args___powershell_args				-done 01/22/2013
# * add the generateChildTestsuites  					-done 01/16/2013  (need further test)
# * Add thProperty.txt for each TS					-not an issue
# * add the c:\_TAF\_tafGlobalVars.txt &readTAFGlobalVars		-done 01/15/2013
# * c:\_TAF\_cmdLogs.txt can grow very big potentially			-done 01/15/2013
# * Issue: testcaseNode default = testcase000N (comflict between taf/ts and generated/ts) -fixed 01/15/2013
# * But one PS TC failed in the test bed  ps1_arg=powershell_args	-doen 01/15/2013
# * cmdLog.txt TimeSpan    $commandLogLifeSpan		= "- 3 days"; 	-done 01/15/2013
# * add command history to c:\_cmdLogs.txt				-done 01/15/2013
# * remove autoTCDesc related lines (remove tcDesc Serial Number) 	-done 01/15/2013
# * tcDelta needs to be copied from Jan_11B version markdaily 		-done 01/15/2013
# * add _tag_ function (index_faild 	mergethProperty();		-done 01/15/2013
# * add refresh from webUI $listTS,$listTSAll				-done 01/14/2013
# * bug: list should not make the moving bar	$scrollAmount_		-done 01/13/2013
# * testsuite log $externalLogName=... see &getTCLogFname__ 		-done 01/13/2013
# * Format the passFailString	add dumyTC				-done 01/13/2013
# * Pass/Fail link failed  getLastPassFail() and genPassFailOther	-done 01/13/2013 
# * Bug Exec_24_7 will run infinite number for propertyOp		-done 01/13/2013 	(propertyExecCtr)
# * duplicated records in webUI (possible reason/solution) testcaseNode (solution: testcaseNode?)
# * fix todo in the code						-done 01/13/2013	(4 todo left to fix)
# * generateRootIndex copy index.htm_ to index.htm doens't work on some system (need exit IE/index.htm or manual copy)
# * there is recursive call on scanTestsuite (call list)
# * add Regexp::Assemble->new; 		 in the build process		-done 01/04/2013
# * add File::Copy::Recursive dependency in the build process		-done 01/04/2013
# * generate the index_http.htm. 					-In progress (12/26/2012 onhold wait for RubyOnRail)
# * Animate Testsuite bulletin. - generateRootIndex ? 			-in Prog (need testing)
# * Extra searial#. was added in the code. thProperty.txt) - as designed-done 01/01/2012
# * Mark automation every day  by            sub getExecDay 		-done 01/04/2013
# * Full width passFailString (index_Full_Length.htm) 	Add intelegent 	-done 01/02/2012
# * Mark with Automation Note/Mouse Over display 			-done 01/01/2013
# * MouseOver * in the Automation history				-done 12/26/2012 
# * generate taf.pl on e: (other than c:)  taf.pl _TAF=tmp\tmp;genDriver-done 12/26/2012
# * generateExcelReport has $rst = `$cmd`. should &func() 		-done 12/26/2012
# * add Mark by "|" in webUI						-done 12/21/2012
# * add stop TS by "." in webUI						-done 12/21/2012
# * multiple command in squence: list;exec;list;exec			-done 12/18/2012 
# * scan TS under c:\_TAF\ doen't work yet. (errous test bed)		-done 12/20/2012
# * fix bug ps1_arg1= bug	In processTCS				-done 12/20/2012 
# * add function: exitTAFGracefully for any TC  .Execution		-done 12/20/2012
# * multiple commands separated by ;	$isBatchProcessing == 1) { $NofExecutionCtr=0; &tcLoop();} -done 12/18/2012
# * add refresh function to c:\_TAF\index.htm				-done 12/14/2012
# * Stop a specific test execution					-done 12/13/2012 
# * Repeat a specific test case	($markTS)				-done 12/13/2012
# * GeneratePowershellShellTS 						-done 06/06/2012
# * create ps1 testsuite createTS and its test cases			-done 06/01/2012
# * integrate gerneatePShellTestsuite 					-done 06/06/2012
# * remove taf recursive by $makeMark=y (perform improvement)		-done 12/05/201/
# * exitGracefully for each test case					-done 12/12/2012 
# * add generateExcelReport Function					-done 12/06/2012
# * add enterY function							-done 12/10/2012
# * remove _cmd_holder and _desc_holder_				-done 12/11/2012
# * convert listHistory to propertyOP=list_history_tcRunReport  	-done 12/11/2012
# * generate daily Excel report						-done 12/11/2012
# * resetTSFile								-done 12/12/2012
# * make Testcase Description link to Daily Report 			-done 12/12/2012
# * run one TC 24_7							-done 05/01/2012
# * win8 installation							-done 12/05/2012
# * use testsuite for tcFilter, tcDefaultFilter 			-done 12/12/2012
# * generateExcelReport handles performance TC (return NN.NN)  		-done 12/12/2012
* # addURLs will add date-time to the log fname 			-done 12/13/2012
###############################################

############# Low Priority Requirement/Bugs #########
#   Need to setup IIS and _TAF as a virtual directory documentation 
# * multiple tppp filters 	(Very difficult/Low priority)
# * Notif for the expected failure
# * bug: when there is no TC in a TS, the TS * is default to move 
# * generateIndex (including generateRootIndex) based on scanTestsuite - works. but index.htm has a lock on it?  (investigation)
# * multi-TS Execution sequentially or concurrently
# * global $index 
# * handle unexpected reboot scenario

############# todo: MarkTC related Actions #########
# * mark by delta time (every day at 0:00?) 
# * mark with comments (mouse over comments)				-done 12/26/2012
# * history mark link to logs/passfail
# * mark non-executed TCs

#################### Completed Requirements/Bug fixes ###########################
# * passFailDisplayWidth is self-adjustable (see todo) 			-done
# * line 1951: **recursive calling** -Done on 09/04/2012		-done
# * 24 exec,  					done			-done
# * Number of TS execution  setGlobal(NofExecution = 5) 		-done
# * start/stop gracefully	taf.pl exitTAF				-done
# * 24 continuously, in stead of one test suite 			-done
# * Stop TAF graceffully from webUI 					-done
# * bug: * history is incorrect 					-done
# * Bug 'mark' is counted as a failure 					-done
# * Cleanup the directory with index.ps1 				-done (.ps1 takes high priority over *.pl)
# * Bug 'L' has characters other than '*' 				-Ignore (invalid bug)
# * Performance improvements						-done (performanceMode)
# * generateTestsuite will add the tcDesc property 			-done 
# * propertyOperation by propertyOp=add=prop1:val1 			-done 
# * propertyOperation by propertyOp=get_prop1:val1			-done 
# * PropertyFilter for TC operation (e.gl tcDesc = ..)			-done
# * Search by TCDesc							-done by tcProperty
# * list should list all TS/TCs						-done -handle by scanTestsuites
# * Refresh or the historical "*"					-done
# * testcase=testcase[1,2,3..] work for list. not work for exec 	-done (it works)
# * Bug: pass/fail html is incorrect					-done
# * modify the getProperties to pass regression				-done
# * add removeDuplicated records to handle webUI dup			-done (wrong fix. reversed)
# * scanTestsuite for generated property files _full_, _smoketest_, _regressiontest_ -done (see taf.bat)
# * scanTestsuite for generated property files _full_,  _tcLogAppend.txt was not copied to the _property_ directory - Done
# * c:\_TAF\index.htm concurrency control 				-done
# * Bug fix for generate index_[pass|fail].htm				-done
###################################################################################
############# done : property operations ###############
# * Add 								-done
# * Delete      add=prop:null						-done 
# * Modify	add=prop:newValue					-done 
# * List|get	propertyOp=list_[history_]propName               	-dene 12/11/2012
############ repalced by [set|get]_tcFilter 
# Know Issue:
# When The TS is under c:\_TAF, generateTestsuite will generate c:\_TAF\_TAF.... no index.pl is copied. 
# The original c:\_TAF\... is treated as the test suites
# Q: does the c:\_TAF\_TAF is necessary created? (It won't hurt for now)
#############################################################

##################### Research Topic1: TAF_Team function   ############################
# * Web Service architecture / CGI / RPC / RubyOnRail
# * Browser independency 
# * local run version and /o IIS , support multiple TC Concurrency Control, 
# * Working with new Concurrency Control scheme, TCExecSummary, tcDelay=10
# * Linux porting (convert \\ to / for unix port)

#################### Research Topics2:TestSuite Machine independency ###################
# *  Move/Merge TAF over machine
# ** Merge test suite from one machine
# ** Merge test suite from multi-machine
# ** Move TS from one dir to different dir and regenerate the index*.*
# 0. Move the TS to c:\_MachineName\....
# 1. generateAyAnvilTestsuite.pl					-done
# 2. Copy c:\_TAF\* to new server
# 3. taf testsuite=...;list
# 4. Need to copy the AUT to new server
# 5. use tsProperty.txt to update 
# 6. TS titleName
# 7. TC directory 
#Note: ts;list will update all index.html

# thProperty.txt recursive format? update thProperty ? 

#c:\_TAF\taf.pl taf.pl testsuite=_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;testcaseNode=testcase;list

#generateChildTestsuite()   has a recursive call 

# $c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;createOrAppendTS=create;generateTAFTestsuite
