##############################################################################################################
#									
# Routine :	alm_copyproject.pl	v1.24			
#   									
# Description :								
#	This perl script copies ALM infrastructure records and their links for a given ALM project.This script clones 
#	a Project and its Phases, Roles, WorkConfigurations, DefaultRequest,and DefaultTask.		
#									
# Syntax :								
#	ratlperl alm_copyproject.pl {-projadmin <projadmin>} {-pw <pw>} {-dbname <db>} {-dbset <dbset>} {-projectid <projectid>}
#       [-clonedprojname [<clonedprojname>]] [-category [<category>]] [-release [<release>]]
#	example: ratlperl alm_copyproject.pl -projadmin ProjectAdmin -pw "" -dbname ALM -dbset CQMS.ALMM3.GALWAY -project ALM00001015
#	-clonedprojname CopyTest -category TestCat -release TestRel	
#									
# Output :								
#	New project is copied from the old project.					
#														
#									
# Licensed Materials - Property of IBM
# Rational ClearQuest
# (C) Copyright IBM Corp. 2008-2009.  All Rights Reserved
# US Government Users Restricted Rights –
# Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp			
#									
##############################################################################################################
#
# Change Log:
#
# Ver       CRs                 Date        Programmer         Comments (fixed, fixed with dependency, added feature)
# 1.24      RATLC01234428	8/1/2008    majidi	       CopyProject should not copy additional Tasks associated with DefaultRequest
#           RATLC01229064       8/1/2008    majidi	       Restructure the copy script to make maintenance easy
# 
# There is change log gap here. Some of the fixes (handful) went directly to the schema record script.
#
# 1.23      RATLC01225506	3/17/2008   majidi	       Set the PriorPhaseLabel to set the PriorPhase (change in m3it4)
# 1.22      offline rfe		3/05/2008   majidi	       Added time stamp to project name with no clonedprojectname
# 1.21      offline defect	3/03/2008   majidi	       Groups field copy support in Role added (post M3 change)
# 1.20 	    offline defect	2/29/2008   majidi	       ApproveActions are now copied from the source role
# 							       instead of, from the rolelabel ( by value changed hook)
# 1.19      offline task	2/24/2008   majidi	       Get replica from session plus various minor changes
# 1.18      offline rfe 	2/19/2008   majidi	       Changed project prefix from Cloned_ to CopyOf_ 
# 1.17      offline rfe 	2/13/2008   majidi	       Set SecurityPolicy for cloned records to
#							       Project->SecurityPolicy except (Role->Everyone)
# 1.16      RATLC01049138 	2/07/2008   majidi	       Project->Name, Category and Release be input parameters 
# 1.15      RATLC00398015	1/30/2008   majidi	       Iterations records are not cloned
#							       Also see RATLC00398015 (dependency)
# 1.14      offline defect	1/31/2008   majidi             Prior phase/iteration does not work
# 1.13      RATLC01049975       1/29/2008   majidi	       Error when Project has CurrentPhaseLabel set
# 1.12	    offline defect	1/28/2008   majidi	       Error when DefaultTask is empty
# 1.11	    RATLC01049252       1/28/2008   majidi	       Clone DefaultRequest and DefaultTask on the project	
# 	    RATLC01049178       1/28/2008   majidi	       Role members are missing (CopyEntity defect)	
# 1.1	    RATLC01220362	1/22/2008   majidi	       WorkConfiguration record does not clone in ALMM3
# 1.0	    RATLC01220362	1/20/2008   majidi	       Added support for ALM schema infrastructure cloning
# 	    	                            Shireen            Created the CopyEntity demo script
#
# Known issues:
# 
# 
##############################################################################################################
#!ratlperl -l -w
use CQPerlExt;
use strict;
use File::Basename;
use Getopt::Long;

######################
my $progname = basename $0;
my $entity;
my $VERSION="1.24";
my $CopyToProjectID;
# Define the input parameters
my @options = qw(
    projadmin=s		
    pw=s		
    dbname=s		
    dbset=s		
    projectid=s
    clonedprojname:s
    category:s
    release:s
    secpolicy:s	
    help);

my %options = (
    projadmin => undef,
    pw => undef,
    dbname => undef,
    dbset => undef,
    projectid => undef,
    clonedprojname => undef,
    category => undef,
    release => undef,
    secpolicy => undef,
);

######################
# Get the input parameters
unless (GetOptions(\%options, @options)) {
 	print "Printing Usage to the command line: ";	
      	my $retval = &Usage;
      	exit 0;

}
######################
# Display the help usage
if ($options{help}) {
	print "-projadmin       The login id of the ProjectAdmin.\n";
	print "-pw              The password of the ProjectAdmin.\n";
	print "-dbname          The name of the user database.\n";
	print "-dbset           The name of the database set or connection that contains the database.\n";
	print "-projectid       The ID of the project to be cloned.\n";
	print "-clonedprojname  The name for the cloned project.\n";
	print "-category        The ALMCategory for the cloned project.\n";
	print "-release         The ALMRelease for the cloned project.\n";
	print "-help            This is an optional flag for the help.\n";
	exit 0;
}

######################
# End program if any of the parameters are not defined
  if (!defined $options{projadmin}
     or !defined $options{pw}
     or !defined $options{dbname}
     or !defined $options{dbset}
     or !defined $options{projectid}) 
  { 
     #print"Printing Usage to the command line:";
     my $retval = &Usage();
     exit 1;
  }

######################

my $session = CQSession::Build();
eval{$session->UserLogon($options{projadmin},$options{pw},$options{dbname},$options{dbset});};
die "Error in logon: for $options{projadmin},$options{pw},$options{dbname},$options{dbset} \n$@\n" if ($@);


# Need a Entity Object for project
eval {$entity = $session->GetEntity("ALMProject","$options{projectid}");};
if ($@){

	CQPerlExt::CQSession_Unbuild($session);
	die "Got error from GetEntity $options{projectid} \n$@\n";
}

my $currUser = $session->GetUserLoginName();
almproject_ALM_CopyProject("$options{clonedprojname}\n$options{category}\n$options{release}");
$CopyToProjectID=$session->GetNameValue("CopyToProjectID");
$session->SetNameValue("CopyToProjectID", "");
print("The copy was successful!. The new project ID is: $CopyToProjectID.\n");
CQPerlExt::CQSession_Unbuild($session);
exit 0;
######################
# Subroutine to display the usage
sub Usage {
	 print "\n$progname $VERSION :Utility to copy an ALM project\n
	
         $progname 
	 {-projadmin <projadmin>}
         {-pw <password>}
         {-dbname <database name>}
         {-dbset <database set>}
         {-projectid <projectid>}
	 [-clonedprojname [<clonedprojname>]]
 	 [-category [<category>]]
 	 [-release [<release>]]
	 [-help]
";
return 0;
}

#####################################################################################
# The following will be copied as it is to the record script in the schema. Make sure
# these two subs are identical.
#####################################################################################
sub almproject_ALM_CopyProject {
    my($result);
    my($param) = @_;
    # record type name is ALMProject
	
	# This function implements ClearQuest's CopyEntity API
	# Please note that the aforementioned API is called internally only.
	# It is neither published nor supported, and this implementation should not be imitated.

	### Define variables
	my @params = split(/\n/, $param);

	my $projEntity;
	my @copyArray=();
	my @skipArray=();
	my $idx;
	my $dateStr;
	my $entsCount;
	my $status;
	my $strarray1;
	my $strarray2;
	my $ent;
	my $dspname;
	my $clonedProjName;
	my %AWCHash=();
	my $refh_AWC;
	my $primary;
	my $secondary;
	my $roles;
	my @ptypes=();
	my @stypes=();
	my @AWCroles=();
	my $AWCEntity;
	my $clonedProjID;
	my $currentPhaseLabel;
	my $phaseLabel;
	my $finaldspname;
	my $projName;
	my $localreplica;
	my $adminSess; 
	my $clonedRequestID;
	my $clonedTaskID;
	my $projEntity;
	my $taskOwner;
	my $taskType;
	my $taskEntity;
	my $taskRoles;
	my %ARHash=();
	my $refh_AR;
	my $members;
	my $AREntity;
	my @ARMembers=();
	my $oldmembers=();
	my $origdspName;
	my $cloneddspName;
	my %AIHash=();
	my $refh_AI;
	my $AIEntity;
	my $phase;
	my $iterationLabel;
	my $priorPhaseLabel;
	my %APHash=();
	my $refh_AP;
	my $APEntity;
	my $priorIteration;
	my $projectID;
	my $clonedprojSecPol;
	my %opts=();
	my $failure;
	my $entityobjs;
	my $actions;
	my @ARActions=();
	my @ARGroups=();
	my $groups;
	my ($querydef,$operator,$resultset,$count);
	my $hasParam = 0;

	use subs qw(CQValidateCommit);


	### Initialize some variables
	$projEntity=$entity;
	$session->SetNameValue("CopyToProjectID", "");
	$localreplica= ($session->GetLocalReplica())->GetDisplayName(); 
	$projectID = $projEntity->GetFieldValue("id")->GetValue();
	
	if ($#params > 0) # Get the parameters
	{
		$hasParam = 1;
		$opts{clonedprojname}=$params[0];
		$opts{category}= $params[1];
		$opts{release}= $params[2];

	}
	else			# Get the paramaters from the Project form
	{
		$opts{clonedprojname}=$projEntity->GetFieldValue("CopyToProjectName")->GetValue();
		$opts{category}= $projEntity->GetFieldValue("CopyToCategory")->GetValue();
		$opts{release}= $projEntity->GetFieldValue("CopyToRelease")->GetValue();
	}

	# Check if there already exists an ALMProject with the same Name
	if (! ($opts{clonedprojname} eq "" or $opts{clonedprojname} =~ /^\s+$/))
	{
		$querydef = $session->BuildQuery("ALMProject");	
		$querydef->BuildField("dbid");
		$operator = $querydef->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND);
		$operator->BuildFilter("Name", $CQPerlExt::CQ_COMP_OP_EQ, [$opts{clonedprojname}]);
		$resultset = $session->BuildResultSet($querydef);
		$resultset->EnableRecordCount();
		$resultset->Execute;
		$count = $resultset->GetRecordCount();	
		if ($count > 0) { 
			CQPerlExt::CQSession_Unbuild($session);
			die "*** There already exists an ALMProject record for:\n\t Name: $opts{clonedprojname}\n"; 
		}		
	}

	# Check if there already exists an ALMProject with the same Category + Release combination
		$querydef = $session->BuildQuery("ALMProject");	
		$querydef->BuildField("dbid");
		$operator = $querydef->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND);
		
		if ($opts{category} eq "" or $opts{category} =~ /^\s+$/) { 
			CQPerlExt::CQSession_Unbuild($session);
			die "*** A Category is required in order to create an ALMProject! ***\n"; 
		}
		else {$operator->BuildFilter("Category", $CQPerlExt::CQ_COMP_OP_EQ, [$opts{category}]);}
		

		if ($opts{release} eq "" or $opts{release} =~ /^\s+$/)
		{$operator->BuildFilter("Release", $CQPerlExt::CQ_COMP_OP_IS_NULL, []);}
		else {$operator->BuildFilter("Release", $CQPerlExt::CQ_COMP_OP_EQ, [$opts{release}]);}

		$resultset = $session->BuildResultSet($querydef);
		$resultset->EnableRecordCount();
		$resultset->Execute;
		$count = $resultset->GetRecordCount();	
		if ($count > 0)	{ 
			CQPerlExt::CQSession_Unbuild($session);
			die "*** There already exists an ALMProject record for:\n\t Category: $opts{category}\n\t Release: $opts{release}\n"; 
		}


	######################
	$session->OutputDebugString("Calling CopyEntity $@\n");

	##Copy Array
	##Temporary stopping iteration record cloning

	@copyArray=('ALMProject'
	,'ALMProject.Phases'
	,'ALMProject.Phases.Project'
	,'ALMProject.Roles'
	,'ALMProject.Roles.Project'
	,'ALMProject.WorkConfigurations'
	,'ALMProject.WorkConfigurations.ALMProject'
	,'ALMProject.DefaultRequest'
	,'ALMProject.DefaultRequest.Project'
	,'ALMProject.DefaultTask'
	,'ALMProject.DefaultTask.Project');

	##Skip Array

	@skipArray = ('ALMProject.SubProjects'
	,'ALMProject.SuperProjects'
	,'ALMProject.Release'
	,'ALMProject.CurrentPhaseLabel'
	,'ALMProject.PriorProject'
	,'ALMProject.NextProject'
	,'ALMProject.CurrentPhase'
	,'ALMProject.UCM_Project'
	,'ALMProject.Phases.NextPhase'
	,'ALMProject.Phases.CurrentIteration'
	,'ALMProject.Phases.CurrentIterationLabel'
	,'ALMProject.Phases.StatusLabel'
	,'ALMProject.DefaultRequest.NotifyList'
	,'ALMProject.DefaultRequest.RequestsRelated'
	,'ALMProject.DefaultRequest.RequestsRelatedBack'
	,'ALMProject.DefaultRequest.CategoryPath'
	,'ALMProject.DefaultRequest.Phase'
	,'ALMProject.DefaultRequest.PhaseLabel'
	,'ALMProject.DefaultRequest.IterationLabel'
	,'ALMProject.DefaultRequest.Iteration'
	,'ALMProject.DefaultRequest.Comments'
	,'ALMProject.DefaultRequest.Attachement'
	,'ALMProject.DefaultRequest.BTBuild'
	,'ALMProject.DefaultRequest.CategroyTypeLabel'
	,'ALMProject.DefaultRequest.Tasks'
	,'ALMProject.DefaultTask.PhaseLabel'
	,'ALMProject.DefaultTask.NotifyList'
	,'ALMProject.DefaultTask.TasksRelated'
	,'ALMProject.DefaultTask.TasksRelatedBack'
	,'ALMProject.DefaultTask.Iteration'
	,'ALMProject.DefaultTask.Phase'
	,'ALMProject.DefaultTask.IterationLabel'
	,'ALMProject.DefaultTask.Activities'
	,'ALMProject.DefaultTask.Roles'
	,'ALMProject.DefaultTask.Comments'
	,'ALMProject.DefaultTask.Attachement'
	,'ALMProject.DefaultTask.BTBuild'
	,'ALMProject.DefaultTask.ResolutionCode'
	,'ALMProject.DefaultTask.Request');


	eval {$entityobjs = $session->CopyEntity($projEntity, \@copyArray, \@skipArray);};
	if ($@) {
	 $session->OutputDebugString("Got CopyEntity Error $@\n");
	 CQPerlExt::CQSession_Unbuild($session);
	 die "Got CopyEntity Error $@";
	}

	$entsCount = $entityobjs->Count();
	$session->OutputDebugString("Number of entities created in the CopyEntity Array = $entsCount\n");

	#################################################################################################################
	#When you get an error like this means the unique name is becoming duplicate.....
	#Call CommitEntities
	#Got CommitEntities Error Failed condition: GetState() == AD_VALIDATED
	#Location: ClearQuest Core:adeditaction.cpp:742
	#GetState()=PREPARED at h:/bugbert/nt_i386/pvtinstall/ClearQuest/lib/perl5/site_perl/5.8.6/CQPerlExt.pm line 43.
	##################################################################################################################
	## If you are copying a stateless record make sure the keys are unique and will not cause duplicates.
	for ($idx=0; $idx < $entsCount; $idx++) {

		$ent = $entityobjs->Item ($idx);
		my $entdefname = $ent->GetEntityDefName();
		my $dspName = $ent->GetDisplayName();
		$session->OutputDebugString ("Entity DefName is: $entdefname \n DisplayName is:  $dspName\n");

		if($entdefname eq "ALMProject")
		{	
			$projName=$ent->GetFieldStringValue("Name");
			$clonedProjID=$ent->GetFieldStringValue("id");
			($opts{clonedprojname} ne "") ?  ($clonedProjName=$opts{clonedprojname}) : ($clonedProjName="CopyOf_${projectID}_" . time());
			$failure=$ent->SetFieldValue("Name","$clonedProjName");
			if ($opts{category} ne ""){$failure=$ent->SetFieldValue("Category","$opts{category}");}
			if ($opts{release} ne ""){$failure=$ent->SetFieldValue("Release","$opts{release}");}
			$clonedprojSecPol=$ent->GetFieldStringValue("SecurityPolicy");
			$failure=$ent->SetFieldValue("Obsolete","No");
			$failure=$ent->SetFieldValue("Description","");
			$failure=$ent->SetFieldValue("StartDate","");
			$failure=$ent->SetFieldValue("EndDate","");
			$failure=$ent->SetFieldValue("DefaultRequest","");
			$failure=$ent->SetFieldValue("DefaultTask","");
			$failure=$ent->SetFieldValue("CopyToProjectName","");
			$failure=$ent->SetFieldValue("CopyToCategory","");
			$failure=$ent->SetFieldValue("CopyToRelease","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");
			$failure=$ent->SetFieldValue("OldID","$clonedProjID");
	
		}
		if($entdefname eq "ALMPhase")
		{	
		
			$priorPhaseLabel=$ent->GetFieldStringValue("PriorPhaseLabel");
			if ($priorPhaseLabel) {
			   	$APHash{$dspName}{'PriorPhaseLabel'}=$priorPhaseLabel;
			}
			if ($opts{category} ne ""){
				$failure=$ent->SetFieldValue("SecurityPolicy","$clonedprojSecPol");
			}
			$failure=$ent->SetFieldValue("PriorPhaseLabel","");
			$failure=$ent->SetFieldValue("PriorPhase","");
			$failure=$ent->SetFieldValue("Description","");
			$failure=$ent->SetFieldValue("StartDate","");
			$failure=$ent->SetFieldValue("EndDate","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");

		}
	
		if($entdefname eq "ALMRole")
		{
			$origdspName = $dspName;
			$origdspName =~ s/$clonedProjID/$projectID/;
			$AREntity = $session->GetEntity("ALMRole","$origdspName");
			$ARHash{$dspName}{'Members'} = 	$AREntity->GetFieldStringValue("Members");
			$ARHash{$dspName}{'Groups'} = 	$AREntity->GetFieldStringValue("Groups");
			$ARHash{$dspName}{'ApprovedActions'} = $AREntity->GetFieldStringValue("ApprovedActions");
			if ($opts{category} ne ""){
				$failure=$ent->SetFieldValue("SecurityPolicy","Everyone");
			}
			$failure=$ent->SetFieldValue("Description","");
			$failure=$ent->SetFieldValue("EntityName","");
			$failure=$ent->SetFieldValue("Members","");
			$failure=$ent->SetFieldValue("ApprovedActions","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");
		
		}
		if($entdefname eq "ALMWorkConfiguration")
		{

			$AWCHash{$dspName}{'ChildrenTypes_primary'} = $ent->GetFieldStringValue("ChildrenTypes_primary");
			$AWCHash{$dspName}{'ChildrenTypes_secondary'} = $ent->GetFieldStringValue("ChildrenTypes_secondary");
			$AWCHash{$dspName}{'ALMRoles'} = $ent->GetFieldStringValue("ALMRoles");
			if ($opts{category} ne ""){
				$failure=$ent->SetFieldValue("SecurityPolicy","$clonedprojSecPol");
			}
			$failure=$ent->SetFieldValue("ChildrenTypes_primary","");
			$failure=$ent->SetFieldValue("ChildrenTypes_secondary","");
			$failure=$ent->SetFieldValue("ALMRoles","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");
		
		}
		if($entdefname eq "ALMRequest")
		{
			$clonedRequestID=$ent->GetFieldStringValue("id");
			if ($opts{category} ne ""){
				$failure=$ent->SetFieldValue("Category","$opts{category}");
	 			$failure=$ent->SetFieldValue("Project","$clonedProjID");
			}
			$failure=$ent->SetFieldValue("Description","");
			$failure=$ent->SetFieldValue("CategoryStringPath","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");
			$failure=$ent->SetFieldValue("OldID","$clonedRequestID");
				
		}
		if($entdefname eq "ALMTask")
		{
			$clonedTaskID=$ent->GetFieldStringValue("id");
			$taskType=$ent->GetFieldStringValue("Type");
			if ($opts{category} ne ""){
				$failure=$ent->SetFieldValue("Project","$clonedProjID");
				$failure=$ent->SetFieldValue("SecurityPolicy","$clonedprojSecPol");
			}
			if ($clonedRequestID){
				$failure=$ent->SetFieldValue("Request","$clonedRequestID");
 			}
			else {
				CQPerlExt::CQSession_Unbuild($session);
				die "*** Project $projectID does not have a DefaultRequest.";
			}
			$failure=$ent->SetFieldValue("Description","");
			$failure=$ent->SetFieldValue("ResolutionSummary","");
			$failure=$ent->SetFieldValue("Owner","");
			$failure=$ent->SetFieldValue("Type","");
			$failure=$ent->SetFieldValue("ResolutionCode","");
			$failure=$ent->SetFieldValue("ratl_mastership","$localreplica");
			$failure=$ent->SetFieldValue("OldID","$clonedTaskID");
				
		}
	}

	$session->OutputDebugString("Call ValidateEntities\n");

	#catch exceptions with eval
	############################

	eval{$strarray1 = $session->ValidateEntities($entityobjs);};
	my $size = grep(/\S/, @$strarray1); 
	if  ($@ || $size) {
			$session->RevertEntities($entityobjs);
			$ent=undef;
			$entityobjs=undef;
			CQPerlExt::CQSession_Unbuild($session);
			die "** Error from ValidateEntities: $@ \n Returned status is:@$strarray1\n";		
	}
	else
	{
		$session->OutputDebugString("Call CommitEntities\n");
		eval {	$strarray2  = $session->CommitEntities($entityobjs);};
		my $size = grep(/\S/, @$strarray2);
		if  ($@ || $size)  
		{
			$session->RevertEntities($entityobjs);
			$ent=undef;
			$entityobjs=undef;
			CQPerlExt::CQSession_Unbuild($session);
			die "** Error from CommitEntities: $@ \n Returned status is:@$strarray2\n";
		}
		else{
			$session->OutputDebugString("CopyEntity was successfull.\n");
			$ent=undef;
			$entityobjs=undef;
		}
	}
	######################
	# Restore the values for ALMPhase record on pass2 
	$session->OutputDebugString("Restoring the values for Phase record on the second pass...\n") if (keys %APHash);
	$refh_AP=\%APHash;
	foreach my $AP ( keys %$refh_AP ) {
       
	       $priorPhaseLabel="";
	       $priorPhaseLabel =  $refh_AP->{$AP}->{'PriorPhaseLabel'};
	       $session->OutputDebugString("ALMPhase is: $AP\n");
	       if ($priorPhaseLabel) {
		 $session->OutputDebugString("PriorPhaseLabel is $priorPhaseLabel\n");
		 $APEntity = $session->GetEntity("ALMPhase","$AP");
		 $APEntity->EditEntity("modify");
		 $failure=$APEntity->SetFieldValue("PriorPhaseLabel","$priorPhaseLabel");
	  
	       }
	       CQValidateCommit($APEntity);
 
	}
	######################
	# Restore the values for WorkConfigurations fields on pass2 
	$session->OutputDebugString("Restoring the values for WorkConfigurations fields on the second pass...\n") if (keys %AWCHash);
	$refh_AWC=\%AWCHash;
	foreach my $AWC ( keys %$refh_AWC ) {
     
	       $primary =  $refh_AWC->{ $AWC }->{'ChildrenTypes_primary'};
	       $secondary =  $refh_AWC->{ $AWC }->{'ChildrenTypes_secondary'}; 
	       $roles =  $refh_AWC->{ $AWC }->{'ALMRoles'};
	       $session->OutputDebugString("ALMWC is: $AWC\n");
	       if ($primary || $secondary || $roles) {
		 $session->OutputDebugString("Primary or Secondary or Roles have a value\n");
		 $AWCEntity = $session->GetEntity("ALMWorkConfiguration","$AWC");
		 $AWCEntity->EditEntity("modify");
		 if ($primary) {

	       	 	@ptypes = split(/\n/, $primary);
	                $session->OutputDebugString("Primary is: @ptypes\n");
		 	foreach (@ptypes) {
				$failure=$AWCEntity->AddFieldValue("ChildrenTypes_primary","$_");
	 
	         	}  
		 }
	         if ($secondary) {

	       	   	 @stypes = split(/\n/, $secondary);
			 $session->OutputDebugString("Secondary is: @stypes\n");
			 foreach (@stypes) {
				$failure=$AWCEntity->AddFieldValue("ChildrenTYpes_secondary","$_");
		 	 } 
	         }
		 if ($roles) {

	       	   	 @AWCroles = split(/\n/, $roles);
			 $session->OutputDebugString("Roles are: @AWCroles\n");
			 foreach (@AWCroles) {
				s/$projectID/$clonedProjID/;
						$session->OutputDebugString("Copied Roles are: $_\n");
				$failure=$AWCEntity->AddFieldValue("ALMRoles","$_");
		 	 } 
	         }
		 	 	CQValidateCommit($AWCEntity);
 
	   }

	}

	######################
	# Restore the values for ALMRoles fields on pass2 
	$session->OutputDebugString("Restoring the values for Roles fields on the second pass...\n") if (keys %ARHash);
	$refh_AR=\%ARHash;
	foreach my $AR ( keys %$refh_AR ) {
     
 
	       $members =  $refh_AR->{$AR}->{'Members'};
	       $groups  =  $refh_AR->{$AR}->{'Groups'};	
	       $actions =  $refh_AR->{$AR}->{'ApprovedActions'};
	       $session->OutputDebugString("ALMRole is: $AR\n");
	       if ($members || $actions || $groups) {
		 $session->OutputDebugString("Members has value(s)\n");
		 $AREntity = $session->GetEntity("ALMRole","$AR");
		 $AREntity->EditEntity("modify");
	         if ($members) {
		 	@ARMembers = split(/\n/, $members);
			$session->OutputDebugString("Members are: @ARMembers\n");
		 	foreach (@ARMembers) {
				$session->OutputDebugString("Members are: $_\n");
				$failure=$AREntity->AddFieldValue("Members","$_");
		 	} 
	         }
		if ($groups) {
		 	@ARGroups = split(/\n/, $groups);
			foreach (@ARGroups) {
				$session->OutputDebugString("Groups are: $_\n");
				$failure=$AREntity->AddFieldValue("Groups","$_");
		 	} 
	         }
		 if ($actions) { 
	         	@ARActions = split(/ /, $actions);
		 	foreach (@ARActions) {
				$session->OutputDebugString("Approved Action are:\n$_\n");
				$failure=$AREntity->AddFieldValue("ApprovedActions","$_");
		 	}
	         }
	         die "Got Error from validation or commit.\n" if (CQValidateCommit($AREntity));
	       }
	}

	######################
	# Restore the values Type and Owner for DefaulTask
	if ($taskType) {
	 $session->OutputDebugString("Restoring the values for DefaultTask on the second pass...\n");
	 $taskEntity = $session->GetEntity("ALMTask","$clonedTaskID");
	 $session->OutputDebugString("ALMTask type is $taskType\n");
	 $taskEntity->EditEntity("modify");
	 $failure=$taskEntity->SetFieldValue("Type","$taskType");
	 CQValidateCommit($taskEntity);
	}

	######################
	#Restore the values for DefaultRequest and/or DefaultTask and SercurityPolicy fields on the project
	if ($clonedRequestID || $clonedTaskID) {
	 $session->OutputDebugString("Restoring the values DefaultRequest and DefaultTask for project on the second pass...\n");
	 $projEntity = $session->GetEntity("ALMProject","$clonedProjID");
	 $projEntity->EditEntity("modify");
	 if ($clonedRequestID){
	   $session->OutputDebugString("Setting default request on the cloned project to $clonedRequestID\n");
	   $failure=$projEntity->SetFieldValue("DefaultRequest","$clonedRequestID");
	 }
	 if ($clonedTaskID){
	   $session->OutputDebugString("Setting default task on the cloned project to $clonedTaskID\n");
	   $failure=$projEntity->SetFieldValue("DefaultTask","$clonedTaskID");
	 }
	 CQValidateCommit($projEntity);
	}
	$session->OutputDebugString("\nProject $projectID is successfully copied to $clonedProjName .\n");
	$session->SetNameValue("CopyToProjectID", "$clonedProjID");
	$failure = $entity->SetFieldValue("CopyToProjectName","");
	$failure = $entity->SetFieldValue("CopyToCategory","");
	$failure = $entity->SetFieldValue("CopyToRelease","");

	sub CQValidateCommit {
	
		my $Entity=shift(@_);
		my $status;
		$session->OutputDebugString("Call Validate Entity\n");
		$status="";
		my $currEntityName = $Entity->GetDisplayName();
		my $currEntityType = $Entity->GetEntityDefName();
		eval {$status = $Entity->Validate()};

		if  ($@ || ($status ne "")) 
		{
			my $msg = "\nValidation failed \n $@ .\nReturned status is:$status. \n$currEntityType: $currEntityName\n is Reverted.\n";
			$session->OutputDebugString("$msg");
		    	$Entity->Revert();
			CQPerlExt::CQSession_Unbuild($session);
			die "$msg";
		}
		else
		{
			$session->OutputDebugString("Call Commit Entity\n");
			eval {$status = $Entity->Commit()};
			if ($@ || ($status ne ""))
			{

				my $msg = "\nCommit failed \n $@ .\n Returned status is:$status. \n $currEntityType: $currEntityName\n is Reverted.\n";
				$session->OutputDebugString("$msg");
		    		$Entity->Revert();
				CQPerlExt::CQSession_Unbuild($session);
				die "$msg";
		
			}
			else {
				my $msg = "$currEntityType $currEntityName committed.";
				$session->OutputDebugString("$msg");
			}
	
		}
		return $status;

	}

	$session->SetNameValue("CopyToProjectID", "$clonedProjID");

	if (! $hasParam) # If called using the Project form's button
	{
		$failure = $entity->SetFieldValue("CopyToProjectName","");
		$failure = $entity->SetFieldValue("CopyToCategory","");
		$failure = $entity->SetFieldValue("CopyToRelease","");
		return "Finished creating ALMProject $clonedProjID by copying the current project";
	}
    return $result;
}

        