/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

/*
 * Utils.java
 *
 * Created on April 19, 2004, 11:47 AM
 */

package com.sun.enterprise.tools.upgrade.common;

/**
 *
 * @author  prakash
 */
 
import java.io.*;
import java.util.*;
import java.util.logging.*;
import com.sun.enterprise.tools.upgrade.logging.*;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.enterprise.tools.upgrade.cluster.*;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.OutputKeys;

import com.sun.enterprise.tools.upgrade.transform.elements.BaseElement;
import sun.java2d.pipe.AATextRenderer;

public class UpgradeUtils {
    private static UpgradeUtils upgradeUtils;
    private StringManager stringManager = StringManager.getManager(LogService.UPGRADE_LOGGER);
    private static Logger logger=LogService.getLogger(LogService.UPGRADE_LOGGER);
    /** Creates a new instance of Utils */
    private static CommonInfoModel common;
    private UpgradeUtils(CommonInfoModel common) {
        this.common = common;
    }
    public static UpgradeUtils getUpgradeUtils(CommonInfoModel cim){
        //START CR 6348866
        if(upgradeUtils == null) {
            upgradeUtils = new UpgradeUtils(cim);
        } else {
            common = cim;
        }
        //END CR 6348866
        return upgradeUtils;
    }
    public Hashtable enlist70DomainsFromSource(CommonInfoModel cmi){
        String source = cmi.getSourceInstallDir();
        Hashtable domainMapping = null;
        String profile = getProfileInfoFromSourceInput(cmi);	
        if(!checkSourceInputAsDomainRoot(source,cmi)) {
            cmi.getDomainList().clear();
            com.sun.enterprise.tools.upgrade.common.Appserver70DomainNamesResolver as =new Appserver70DomainNamesResolver(source);
            //Admin credential changes. Added for CR 6454007
            domainMapping = as.getDomainNamesPathMapping(cmi);
            //domainMapping = as.getDomainNamesPathMapping();
            //Admin credential changes. - End
            cmi.setInstallConfig70(as.getConfigDir70(source));
            cmi.setDomainMapping(domainMapping);
            Enumeration ee =  domainMapping.keys();
            while (ee.hasMoreElements()) {
                String domain = (String)ee.nextElement();
                cmi.addDomainName(domain);
                cmi.getTargetDomainNameMapping().put(domain,domain);
            }
        } else {     // Input source is domainRoot now
            File sourceDomain = new File(source);
            String [] dirs = sourceDomain.list();
            //sourceInputAsDomainRoot
            /*if(dirs.length == 0) {
                sourceInputAsDomainRoot = false;
                return sourceInputAsDomainRoot;
            }   */
            String domain = "";
            domainMapping = new Hashtable();
            for (int i=0;i<dirs.length;i++) {
                String domainPath=source + File.separator + dirs[i];
                File file = new File(domainPath);
                if(!(dirs[i].endsWith("8x")) && !(file.isFile()) &&
                         isValid70Domain(domainPath)) {
                    domain=dirs[i];
                    domainMapping.put(domain,new DomainInfo(domain,domainPath,profile));
                    cmi.addDomainName(domain);
                    if(new File(cmi.getSourceDomainRoot()).equals(
                                 new File(cmi.getTargetDomainRoot())))
                        cmi.getTargetDomainNameMapping().put(domain,
                                                             domain+"_8x");
                    else
                        cmi.getTargetDomainNameMapping().put(domain,domain);
                }
            }
        }
        System.setProperty("com.sun.aas.configRoot", 
              cmi.getTargetInstallDir() + File.separator + "config");
        return domainMapping;
    }

    public Hashtable enlistDomainsFromDomainsDirectory(CommonInfoModel cmi,
                                                          String domainsDirStr){
        File domainsDir = new File(domainsDirStr);
        String [] dirs = domainsDir.list();
        return enlistDomains(cmi,dirs, domainsDirStr);
    }
    
    public Hashtable enlistDomains(CommonInfoModel cmi, 
                                     String [] dirs, String domainRoot) {
        Hashtable domainMapping = new Hashtable();
        boolean domainRootSame =
             new File(cmi.getSourceDomainRoot()).equals(
                 new File(cmi.getTargetDomainRoot()));
        String profile = getProfileInfoFromSourceInput(cmi);	
        for (int i=0;i<dirs.length;i++) {
            if(dirs[i].equals("backup"))
                continue;
            String domainPath=domainRoot + File.separator + dirs[i];
            if(new File(domainPath+"_8x").exists())
                continue;
            File domainFile = new File(domainPath);
            if(domainFile.isFile())
                continue;
            if(domainRootSame) {
                //String latestdomain = findLatestDomainDir(cmi.getSourceDomainRoot(),null);
                String latestdomain = 
                    findLatestDomainDir(cmi.getSourceDomainRoot(),dirs[i]);
                String backupDomainVersion = "";
                String actualDomainVersion = "garbage";
                if(latestdomain != null)  {
                    backupDomainVersion = 
                        (new VersionExtracter(latestdomain,cmi)).getVersion();
                    String[] directories =
                         new File(cmi.getSourceDomainRoot()).list();
                    String domainName = null;
                    for(int j =0;j<directories.length;j++) {
                        if(directories[j].equals("backup") ||
                             new File(cmi.getSourceDomainRoot() +
                                      File.separator +
                                           directories[j]).isFile())
                            continue;
                        else {
                            domainName = directories[j];
                            break;
                        }
                    }
                    //actualDomainVersion = (new VersionExtracter(cmi.getSourceDomainRoot() + File.separator + domainName,cmi)).getVersion();
                    actualDomainVersion =  (new VersionExtracter(cmi.getSourceDomainRoot() +
                                                File.separator +
                                                    dirs[i],cmi)).getVersion();
                }
                //Do only version-version checks since editions will remain same
                /*String actualDomainVersionString = versionString(actualDomainVersion);
                String toCompareVersion = cmi.getTargetVersion();
                String backupDomainVersionString = versionString(backupDomainVersion);		
                boolean actualVersionSame = actualDomainVersionString.equals(toCompareVersion);
                boolean backupVersionSame = actualDomainVersionString.equals(backupDomainVersionString);		
                if(!actualVersionSame && !backupVersionSame) {*/
                if(!actualDomainVersion.equals(cmi.getTargetVersion())
                           && !actualDomainVersion.equals(backupDomainVersion)) {
                    cmi.setIsInPlace(true);
                    String timestamp=""+System.currentTimeMillis();
                    String newDomainName = "";
                    String domainName = dirs[i];
                    if(dirs[i].endsWith("_8x")) {
                        newDomainName = 
                            dirs[i].substring(0,
                                dirs[i].indexOf("_8x"))+"_"+timestamp;
                        domainName = 
                            dirs[i].substring(0,dirs[i].indexOf("_8x"));
                    } else {
                        newDomainName = domainName+"_"+timestamp;
                    }
                    String backup = cmi.getTargetDomainRoot()+
                        File.separator+"backup";
                    File backupFile = new File(backup);
                    if(!(backupFile.isDirectory())) {
                        backupFile.delete();
                        backupFile.mkdir();
                    }
                    File domainDir = new File(domainPath);
                    String sourceDomainPath =
                         backup+File.separator+newDomainName;
                    //This check will take care of all the domain ending with _8x
                    if(new File(domainPath+"_8x").exists()) {
                        new File(domainPath+"_8x").renameTo(
                            new File(sourceDomainPath));
                        //Added for CR 6500226
                        //domainDir.delete();
                        if(!deleteDirectory(domainDir)) {						
                            logger.log(Level.WARNING, 
                                stringManager.getString("DeleteDirectoryFailed",
                                    domainDir.getAbsolutePath()));
                        }
                        //End - added						
                    } else {
                        //Added for CR 6480041				
                        //Copy and delete instead of rename because of Windows issue.						
                        try{
                            copyDirectory(domainDir, new File(sourceDomainPath));
                            //Added for CR 6500226							
                            //domainDir.delete();
                            if(!deleteDirectory(domainDir)) {						
                                logger.log(Level.WARNING, 
                                    stringManager.getString("DeleteDirectoryFailed",
                                        domainDir.getAbsolutePath()));
                            }
                            //End - added						
                        }catch (IOException e) {
	                        logger.log(Level.SEVERE, 
                                    stringManager.getString("CopyDirectoryFailed", 
                                        domainDir.getAbsolutePath(), sourceDomainPath));
                        }
                        //domainDir.renameTo(new File(sourceDomainPath));
                        //End - added
                    }						
                    domainMapping.put(domainName, 
                        new DomainInfo(domainName,sourceDomainPath,profile));
                    cmi.addDomainName(domainName);
                    cmi.getTargetDomainNameMapping().put(domainName,domainName);
                } else {
                    String latestDomain =
                         findLatestDomainDir(cmi.getTargetDomainRoot(),dirs[i]);
                    domainMapping.put(dirs[i], 
                        new DomainInfo(dirs[i],latestDomain,profile));
                    cmi.addDomainName(dirs[i]);
                    cmi.getTargetDomainNameMapping().put(dirs[i],dirs[i]);
                }
            } else {
                domainMapping.put(dirs[i], 
                    new DomainInfo(dirs[i],domainPath,profile));
                cmi.addDomainName(dirs[i]);
                cmi.getTargetDomainNameMapping().put(dirs[i],dirs[i]);
                /*if(new File(cmi.getSourceDomainRoot()).getPath().equals(new File(cmi.getTargetDomainRoot()).getPath()))
                    cmi.getTargetDomainNameMapping().put(dirs[i],dirs[i]+"_8x");
                else
                    cmi.getTargetDomainNameMapping().put(dirs[i],dirs[i]);   */
            }
        }
        return domainMapping;
    }
    public Hashtable enlistDomainsFromUserDefinedDirectories(List srcDomainDirs){
        Hashtable domainMapping = null;
        for(Iterator dIt = srcDomainDirs.iterator(); dIt.hasNext();){
            if(domainMapping == null) domainMapping = new Hashtable();
            String domainDirStr = (String)dIt.next();
            Hashtable dMaps =
                 this.enlistDomainsFromDomainsDirectory(this.common,
                                                           domainDirStr);
            if(dMaps != null){
                for(Enumeration domainsEnum = 
                   dMaps.keys();domainsEnum.hasMoreElements();){
                    String dName = (String)domainsEnum.nextElement();
                    domainMapping.put(dName, dMaps.get(dName));
                }
            }
        }
        return domainMapping;
    }
    public String findLatestDomainDir(String domainRoot,String domainName) {
        File backupDir = new File(domainRoot+File.separator+"backup");
        String lastestDomainPath=null;
        long latestTimestamp = 0;
        if(backupDir.isDirectory()) {
            String [] dirs = backupDir.list();
            for(int i=0;i<dirs.length;i++) {
                String time = dirs[i].substring(dirs[i].lastIndexOf("_")+1);
                if(domainName != null )
                    if(!(dirs[i].startsWith(domainName)))
                        continue;
                long timestamp = Long.parseLong(time);
                if(timestamp > latestTimestamp) {
                    latestTimestamp = timestamp;
                    lastestDomainPath = 
                        domainRoot+File.separator+
                            "backup"+File.separator+dirs[i];
                }
            }
        }
        return  lastestDomainPath;
    }
    
    public boolean checkSourceInputAsDomain(){
        //this supports 8.x domains only
        //TODO 7.x support for single domains
        File domainXML = new File(common.getSourceInstallDir() +
                                     File.separator + 
                                     "config" +
                                     File.separator +
                                     "domain.xml");
        if(domainXML.isFile()) {
            return true;
        }
        return false;
    }
    
    public boolean checkSourceInputAsDomainRoot(String source, 
                                                 CommonInfoModel cmi) {
        if (source == null) {
            return false;
        }
        File sourceDomain = new File(source);
        File biDir = new File(source+File.separator+"bin");
        //String osName = cmi.getOSName();
        //if(!biDir.isDirectory() && sourceDomain.isDirectory() && osName.startsWith("SunOS")) {
        if(!biDir.isDirectory() && sourceDomain.isDirectory()) {
            // Now check wheather it is a domainRoot
            //by checking the existence of domain/server1/config/server.xml file
            String [] dirs = sourceDomain.list();
            //sourceInputAsDomainRoot
            if(dirs.length == 0) {
                cmi.setSourceDomainRootFlag(false);
                return false;
            }
            
            if(new File(source + File.separator +"backup").exists()) {
                cmi.setSourceDomainRootFlag(true);
                return true;
            }
            // Checking If it contains 8.0 domain
            for (int i=0;i<dirs.length;i++) {
                File domainXML = new File(source+
                                      File.separator+dirs[i]+
                                      File.separator+"config"+
                                      File.separator+"domain.xml");
                if(domainXML.isFile()) {
                    cmi.setSourceDomainRootFlag(true);
                    return true;
                }
            }
            
            // Checking If it contains 7.0 domain
            //if(cmi.getSourceVersion().equals(UpgradeConstants.VERSION_7X)){
            // Get any 7.0 domain
            String domain = "";
            boolean domain70=false;
            for (int i=0;i<dirs.length;i++) {
                if(!(dirs[i].endsWith("8x")) && 
                    (new File(source +File.separator+ dirs[i]).isDirectory())&&                         this.isValid70Domain(source +File.separator+ dirs[i])) {
                    domain = dirs[i];
                    domain70 =true;
                    break;
                }
            }
            if(!domain70)
                return false;
            File domainDir = new File(source+File.separator+domain);
            String [] serverDirs = domainDir.list();
            String serverInstanceName ="";
            if(serverDirs[0].equals("admin-server"))
                serverInstanceName = serverDirs[1];
            else
                serverInstanceName = serverDirs[0];
            File serverXML = new File(source+File.separator+domain+
                                      File.separator+serverInstanceName+
                                      File.separator+"config"+
                                      File.separator+"server.xml");
            if(serverXML.isFile())
                cmi.setSourceDomainRootFlag(true);
            else
                cmi.setSourceDomainRootFlag(false);
            /*}else {
                File domainXML = new File(source+File.separator+dirs[0]+File.separator+"config"+File.separator+"domain.xml");
                if(domainXML.isFile())
                    cmi.setSourceDomainRootFlag(true);
                else
                    cmi.setSourceDomainRootFlag(false);
            }  */
            
        }else {
            cmi.setSourceDomainRootFlag(false);
        }
        return cmi.getSourceDomainRootFlag();
    }
    public boolean isValid70Domain(String domainPath) {
        File domainDir = new File(domainPath);
        boolean domain70 = false;
        String [] serverDirs = domainDir.list();
        String serverInstanceName ="";
        if(serverDirs[0].equals("admin-server"))
            serverInstanceName = serverDirs[1];
        else
            serverInstanceName = serverDirs[0];
        File serverXML = new File(domainPath+File.separator+
                             serverInstanceName+File.separator+
                             "config"+File.separator+"server.xml");
        if(serverXML.isFile())
            domain70 = true;
        else
            domain70 = false;
        return domain70;
    }
    public String versionString(String versionEditionString){
        if(UpgradeConstants.VERSION_AS7X_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS7X_SE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS7X_EE.equals(versionEditionString)){
            return UpgradeConstants.VERSION_7X;
        }
        if(UpgradeConstants.VERSION_AS80_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS80_SE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS81_EE.equals(versionEditionString)){
            return UpgradeConstants.VERSION_80;
        }
        if(UpgradeConstants.VERSION_AS81_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS81_EE.equals(versionEditionString)){
            return UpgradeConstants.VERSION_81;
        }
        if(UpgradeConstants.VERSION_AS90_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS90_SE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS90_EE.equals(versionEditionString)){
            return UpgradeConstants.VERSION_90;
        }
        //Added for CR 6468082		
        if(UpgradeConstants.VERSION_91.equals(versionEditionString)) {
            return UpgradeConstants.VERSION_91;
        }
        if(UpgradeConstants.VERSION_AS82_PE.equals(versionEditionString)||
                UpgradeConstants.VERSION_AS82_SE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS82_EE.equals(versionEditionString)){
            return UpgradeConstants.VERSION_82;
        }			
        //End - CR 6468082		
        return "";
    }
    public String editionString(String versionEditionString){
        if(UpgradeConstants.VERSION_AS7X_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS80_PE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS81_PE.equals(versionEditionString) ||
                //Added for CR 6468082
                UpgradeConstants.VERSION_AS82_PE.equals(versionEditionString) ||
                //End - CR 6468082		
                UpgradeConstants.VERSION_AS90_PE.equals(versionEditionString)) {
            return UpgradeConstants.EDITION_PE;
        }
        if(UpgradeConstants.VERSION_AS7X_SE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS80_SE.equals(versionEditionString)||
                //Added for CR 6468082
                UpgradeConstants.VERSION_AS81_SE.equals(versionEditionString)||
                UpgradeConstants.VERSION_AS82_SE.equals(versionEditionString)||
                //End - CR 6468082		
                UpgradeConstants.VERSION_AS90_SE.equals(versionEditionString)){
            return UpgradeConstants.EDITION_SE;
        }
        if(UpgradeConstants.VERSION_AS7X_EE.equals(versionEditionString) ||
                UpgradeConstants.VERSION_AS81_EE.equals(versionEditionString)||
                UpgradeConstants.VERSION_AS81_EE.equals(versionEditionString)||
                UpgradeConstants.VERSION_AS90_EE.equals(versionEditionString)||
                //Added for CR 6468082
                UpgradeConstants.VERSION_AS82_EE.equals(versionEditionString)){
                //End - CR 6468082		
            return UpgradeConstants.EDITION_EE;
        }
        return "";
    }
    public boolean isValidSourcePath(String sourcePath){
        //Added for CR 6468082
        // If the directory does not exist throw an error instantly
        if(!(new File(sourcePath)).exists()) return false;
        File domainXML=null;
		//End - CR 6468082
        // First check if it is regular 7.x install directory.
        String as7xInstallFileName = "admingui.ear"; //only exists in 7.x installations
        File runtime70Jar = new File(sourcePath+
                                   File.separator+
                                   "lib"+
                                   File.separator+
                                   as7xInstallFileName);
        if((runtime70Jar != null) && runtime70Jar.exists()) {
            // Its a valid 7.x directory.
            return true;
        }
        
        // Check if the source path is a domainRoot 
        domainXML = new File(sourcePath + File.separator + "config" +
                               File.separator + "domain.xml");
        if(domainXML.exists() &&
             domainXML.isFile() ){
            return true;
        }
        
        // Check if this a domainsDir
        File domainsDir = new File(sourcePath);
        String[] domainsDirContents = domainsDir.list();
        for(int i=0 ; i<domainsDirContents.length; i++) {
            if(new File(sourcePath, domainsDirContents[i]).isDirectory()) {
                domainXML = new File(sourcePath + File.separator + 
                              domainsDirContents[i] +
                                 File.separator + "config" +
                                   File.separator +"domain.xml");
                if(domainXML.exists() && domainXML.isFile() ){
                    return true;
                }
            }
        }   
        // if none of the above match then its an invalid directory
        return false;
    }
        
    
    /** public boolean isValidSourcePath(String sourcePath){
        File biDir = new File(sourcePath+File.separator+"bin");
        if(sourcePath.equals("") || !biDir.isDirectory()) {
            if(!checkSourceInputAsDomainRoot(sourcePath, common)) {
                //check for 8.x domain dir as input
                if(new File(sourcePath + File.separator + "config").isDirectory()){
                    return true;
                }
                return false;
            }
            common.setSourceDomainRoot(sourcePath);
        }
		
        // Now check if it is AS8.x or solaris 10 installation or in-place upgrade.
        String[] domainConfigDirs = new VersionExtracter(sourcePath,common).getDomainAndConfigDirs();
        if(domainConfigDirs == null || domainConfigDirs.length == 0){
            // if sourcePath is not valid, then getDomainAndConfigDirs returns null;
            return false;
        }
        String domainsDir = domainConfigDirs[0];
        
        // If the domainsDir is <sourcePath>/domains then sourcePath is AS8.0.
        // If the domainsDir is <sourcePath>_bak then sourcePath is AS8.0 in-place upgrade. (in-place upgrade only supported from 8.0PE onwards
        // if the domainsDir is <sourcePath>  then sourcePath is a domains directory given for solaris 10 integration.
        if(domainsDir == null)
            return false;
        return true;
    }
     */
    
    public boolean isValidTargetPath(String targetPath) {
        // START CR 6461833 
        // check if this path exists
        File targetPathDir = new File(targetPath);
        if( !targetPathDir.exists() ) {
            return false;
        }  
        // END CR 6461833
        // check if this is an existing domain
        File domainXML = new File(targetPath + File.separator + 
                                    "config" + File.separator +"domain.xml");
        if( domainXML.isFile() && domainXML.exists()) {
            return false;
        }
        // else its valid
        return true;
    }
    
    /*public boolean isValidTargetPath(String targetPath) {
        // Now check if it is AS8.x or solaris 10 installation or in-place upgrade.
        //String[] domainConfigDirs = new VersionExtracter(targetPath,common).getDomainAndConfigDirs();
        //if(domainConfigDirs == null || domainConfigDirs.length == 0){
            // if targetPath is not valid, then getDomainAndConfigDirs returns null;
          //  return false;
        //}
        //String domainsDir = domainConfigDirs[0];
         
        // If the domainsDir is <targetPath>/domains then targetPath is AS8.0.
        // If the domainsDir is <targetPath>_bak then targetPath is AS8.0 in-place upgrade. (in-place upgrade only supported from 8.0PE onwards
        // if the domainsDir is <targetPath>  then targetPath is a domains directory given for solaris 10 integration.
        //if(domainsDir == null)
        //    return false;
        //return true;
        
        String osName = System.getProperty("os.name");
        String asenv = null;
        String asadmin = null;
        if(osName.indexOf("Windows") != -1)
            asadmin = targetPath + File.separator + "bin" + File.separator + "asupgrade.bat";
        else
            asadmin = targetPath + File.separator + "bin" + File.separator + "asupgrade";
        try {
            if(! new File(asadmin).exists()) return false;
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(asadmin)));
            String readString =reader.readLine();
            while(readString != null) {
                if(readString.indexOf("targetVersion") != -1) {
                    return true;
                }
                readString =reader.readLine();
            }
        }catch (Exception e) {
            logger.log(Level.WARNING,this.stringManager.getString("enterprise.tools.upgrade.unknownError"),e);
        }
        
        if(!new File(targetPath).isDirectory())
            return false;

        // check if this is an existing domain
        File domainXML = new File(targetPath + File.separator +
                                  "config" + File.separator +"domain.xml");
        if( domainXML.isFile() && domainXML.exists()) {
            return false;
	    }
        // else its valid
		
        return true;
    }
        return false;
    } 
     **/
   
    //Added for CR 6480041
    /**
      * This method is invoked only in EE -> EE upgrade scenarios.
      * The method parses the domain.xml for the server elements 
      * Returns the list of stand alone instances.
      */	  
    public List getStandAloneInstancesFromDomainXml(Hashtable domainsMapping) {
        List stdAloneList = new ArrayList();
        for(Iterator domIt = domainsMapping.values().iterator(); domIt.hasNext();) {
            DomainInfo dInfo = (DomainInfo) domIt.next();
            String domainName = dInfo.getDomainName();
            String sourceDomainPath = 
                    ((DomainInfo) common.getDomainMapping().get(domainName)).getDomainPath();
            String domainXmlFile = sourceDomainPath + File.separator +
                "config" + File.separator + "domain.xml";
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            try {
                DocumentBuilder builder = factory.newDocumentBuilder();
                builder.setEntityResolver((org.xml.sax.helpers.DefaultHandler)Class.forName
                    ("com.sun.enterprise.config.serverbeans.ServerValidationHandler").newInstance());
                Document adminServerDoc = builder.parse( new File(domainXmlFile));
                NodeList servers = adminServerDoc.getDocumentElement().getElementsByTagName("servers");
                NodeList serverList =
	                ((Element)servers.item(0)).getElementsByTagName("server");
                for(int lh =0; lh < serverList.getLength(); lh++){
                    Element server = (Element)serverList.item(lh);
                    String instanceName = server.getAttribute("name");
                    String configRef = server.getAttribute("config-ref");
                    if(!"server".equals(instanceName)) {					
                        if((instanceName + "-config").equals(configRef)) {
                            Vector instDInfo = new Vector();
                            instDInfo.add(instanceName);
                            instDInfo.add(dInfo);
                            stdAloneList.add(instDInfo);
                        }                    						
                    }
                }					
            }catch (Exception ex){
                logger.log(Level.WARNING, stringManager.getString("domainProcessor.serverInstancesFromXML"),ex);
            }
        }			
        return stdAloneList;
    }
    //end - added
	
    public List getStandAloneInstances(Hashtable domainsMapping){
        // This method is called while upgradeing 7.x EE upgrading. This comapres with servers listed in clusters with domains mapping.
        List stdAloneList = new ArrayList();
        for(Iterator domIt=domainsMapping.values().iterator(); domIt.hasNext();){
            DomainInfo dInfo = (DomainInfo)domIt.next();
            for(Iterator instIt = 
                  dInfo.getInstanceNames().iterator(); instIt.hasNext();){
                String instName = (String)instIt.next();
                if(this.isInstanceInCluster(instName)){
                    continue;
                }
                if( !instName.equals("admin-server") ) {
                    Vector instDInfo = new Vector();
                    instDInfo.add(instName);
                    instDInfo.add(dInfo);
                    stdAloneList.add(instDInfo);
                }
            }
        }
        return stdAloneList;
    }
	
    public boolean isInstanceInCluster(String instName){
        // This method is a utility method to check for the instnce clustered or not.
        List clList = ClustersInfoManager.getClusterInfoManager().getClusterInfoList();
        if(clList == null) return false;
        for(Iterator clIt = clList.iterator(); clIt.hasNext(); ){
            ClusterInfo clInfo = (ClusterInfo)clIt.next();
            for(Iterator instIt = clInfo.getClusteredInstanceList().iterator(); instIt.hasNext();){
                if(((ClusteredInstance)instIt.next()).getInstanceName().equals(instName)){
                    return true;
                }
            }
        }
        return false;
    }
	
    private Element getConfigElementFromDocumentElement(Element documentElement, String lookUpConfigName){
        NodeList configEles = documentElement.getElementsByTagName("config");
        Element configEle = null;
        for(int lh =0; lh < configEles.getLength(); lh++){
            String configName = ((Element)configEles.item(lh)).getAttribute("name");
            if(configName.equals(lookUpConfigName)){
                configEle = (Element)configEles.item(lh);
                break;
            }
        }
        return configEle;
    }

    public boolean switchedIIOPPorts(String serverID, 
                        String portValue, Element documentElement){
        Element configEle =
            this.getConfigElementFromDocumentElement(documentElement,
                                                      "server-config");
        NodeList iiopService = configEle.getElementsByTagName("iiop-service");
        NodeList iiopListeners =
             ((Element)iiopService.item(0)).getElementsByTagName("iiop-listener");
        Element iiopListener = null;
        for(int ii =0; ii < iiopListeners.getLength(); ii++){
            if(((Element)iiopListeners.item(ii)).
                     getAttribute("id").equals("orb-listener-1")){
                iiopListener = (Element)iiopListeners.item(ii);
                break;
            }
        }
        if(iiopListener != null){
            String serverIIOPPort =
                  this.getIIOPListenerPortForServer(
                     iiopListener.getAttribute("port"),
                         "server", documentElement);
            if(serverIIOPPort.equals("3700")){
                String portValueFromServer =
                    this.getIIOPListenerPortForServer(portValue,serverID,
                                                       documentElement);
                if(portValueFromServer != null)
                    iiopListener.setAttribute("port", portValueFromServer);
                return true;
            }else{
                return false;
            }
        }
        return false;
    }
    private String getIIOPListenerPortForServer(String portValue,
                            String serverName, Element documentElement){
        try{
            if(portValue != null){
                int portIntValue = Integer.parseInt(portValue);
                return String.valueOf(portIntValue);
            }
        }catch(java.lang.NumberFormatException ne){
            // This shows the the portValue is not a string but ${IIOP_LISTENER_PORT}
        }
        NodeList servers = documentElement.getElementsByTagName("servers");
        NodeList serverList = 
               ((Element)servers.item(0)).getElementsByTagName("server");
        String portValueFromServer = null;
        for(int lh =0; lh < serverList.getLength(); lh++){
            if(serverName.equals(((Element)serverList.item(lh)).getAttribute("name"))){
                Element serverElement = (Element)serverList.item(lh);
                Element sysProp = 
                    getSystemPropertyElement("IIOP_LISTENER_PORT",serverElement);
                if(sysProp != null){
                    return sysProp.getAttribute("value");
                }else{
                    Element configElement =
                      this.getConfigElementFromDocumentElement(documentElement,
                                      serverElement.getAttribute("config-ref"));
                    if(configElement != null){
                        sysProp = getSystemPropertyElement("IIOP_LISTENER_PORT",configElement);
                        if(sysProp != null)
                            return sysProp.getAttribute("value");
                    }
                }
            }
        }
        return null;
    }

    private Element getSystemPropertyElement(String propertyName,
                                              Element parentForSysProp){
        NodeList sysProps =
              parentForSysProp.getElementsByTagName("system-property");
        for(int sh =0; sh < sysProps.getLength(); sh++){
            if(propertyName.equals(((Element)sysProps.item(sh)).getAttribute("name"))){
                return ((Element)sysProps.item(sh));
            }
        }
        return null;
    }

    public void updateDomainXMLWithIIOPCluster(CommonInfoModel cmnInfo,
                            String domainXMLFile, IIOPCluster iiopCluster){
        String clusterName = iiopCluster.getClusterName();
        List servInstances = iiopCluster.getIIOPServerInstanceList();
        boolean domainFileChanged = false;
        Document domainDoc = this.getDomainDocumentElement(domainXMLFile);
        for(int servIt = 0; servIt < servInstances.size(); servIt++){
            List endPoints =
             ((IIOPServerInstance)servInstances.get(servIt)).getIIOPEndPoints();
            String serverName = 
              ((IIOPServerInstance)servInstances.get(servIt)).getName();
            for(int endPt = 0; endPt < endPoints.size(); endPt++){
                IIOPEndPoint iiopEndPoint = (IIOPEndPoint)endPoints.get(endPt);
                // just use only one endpoint and transfer the port no.
                if(domainDoc != null){
                    String propertyName = "IIOP_LISTENER_PORT";
                    String propValue = iiopEndPoint.getPort();
                    NodeList servers =
                         domainDoc.getDocumentElement().
                             getElementsByTagName("servers");
                    NodeList serverList =
                             ((Element)servers.item(0)).
                             getElementsByTagName("server");
                    if(propValue.equals("3700")){
                        this.switchedIIOPPorts(serverName, 
                           null, domainDoc.getDocumentElement());
                        //logger.log(Level.WARNING,this.stringManager.getString("enterprise.tools.upgrade.iiop_port_defined"));
                    }
                    // Passing baseElement as null.  "IIOP_LISTENER_PORT" should definitely exist.  Ssome times the create-instance does not add it.
                    // This base element is only a structural reference to invoke appendChild method.
                    BaseElement baseElement = null;
                    try{
                        baseElement =
                           com.sun.enterprise.tools.upgrade.transform.ElementToObjectMapper.getMapper().getElementObject(domainDoc.getDocumentElement().getTagName());
                    }catch(Exception ef){
                    }
                    this.addOrUpdateSystemPropertyToServer(serverName, 
                            serverList, propertyName, propValue, baseElement);
                    domainFileChanged = true;
                }
                break;
            }
        }
        if(domainFileChanged && (domainDoc != null)){
            this.saveDocumentToDomainFile(domainXMLFile, domainDoc);
        }
    }
    
    //Added for CR 6480041
    /**
      * This method builds the ClusteredInstance object for the particular cluster.
      * The source domain.xml is parsed for the cluster and its associated instances.
      * The values are loaded in the ClusteredInstance object.
      */	  
    public void updateClusteredInstanceList(String domainXMLFile, 
            String domainName, String clusterName, java.util.List clusteredInstanceList) {
        Document domainDoc = this.getDomainDocumentElement(domainXMLFile);
        if(domainDoc != null){
            NodeList servers = domainDoc.getDocumentElement().getElementsByTagName("servers");
            if(servers != null){
                NodeList serverList = ((Element)servers.item(0)).getElementsByTagName("server");
                if((serverList != null) && (serverList.getLength() >0)){
                    for(int lh =0; lh < serverList.getLength(); lh++){
                        Element server = (Element) serverList.item(lh);
                        String configRefName = server.getAttribute("config-ref");
                        if((clusterName+"-config").equals(configRefName)) {
                            //Server instance of this particular cluster.
                            String instanceName = server.getAttribute("name");
                            String nodeAgentName = server.getAttribute("node-agent-ref");
                            String userName = common.getAdminUserName();
                            String domainPath = ((DomainInfo)common.getDomainMapping().get(domainName)).getDomainPath();
                            DomainsProcessor dProcessor = new DomainsProcessor(common);
                            String adminPort = dProcessor.getSourceAdminPort(domainPath);
                            ClusteredInstance clInstance = new ClusteredInstance(instanceName);
                            clInstance.setHost(nodeAgentName);
                            clInstance.setDomain(domainName);			
                            clInstance.setUser(userName);							
                            clInstance.setPort(adminPort);
                            clusteredInstanceList.add(clInstance);							
                        }
                    }
                }
            }
        }
    }		

    /**
      * This method builds the ClusterInfo object and loads the clusters in a list.
      * The domain.xml is parsed for all clusters.
      * The values are loaded in ClusterInfo object and the list clusterInfoList is updated.
      */	  
    public void updateClusterList(String domainXMLFile, String domainName, java.util.List clusterInfoList) {
        Document domainDoc = this.getDomainDocumentElement(domainXMLFile);
        if(domainDoc != null){
            NodeList clusters = domainDoc.getDocumentElement().getElementsByTagName("clusters");
            if(clusters != null){
                NodeList clusterList = ((Element)clusters.item(0)).getElementsByTagName("cluster");
                if((clusterList != null) && (clusterList.getLength() >0)){
                    for(int lh =0; lh < clusterList.getLength(); lh++){
                        String clName = ((Element)clusterList.item(lh)).getAttribute("name");
                        ClusterInfo clInfo = new ClusterInfo();
                        clInfo.setClusterName(clName);
                        clInfo.setDomainName(domainName);
                        clInfo.updateClusteredInstanceList(domainXMLFile, domainName, clName, this);
                        clusterInfoList.add(clInfo);
                    }
                }
            }
        }
    }		
    
    //Rewritten method as above.	
    /*public java.util.List updateClusterList(String domainXMLFile, String domainName, java.util.List clList){
        Document domainDoc = this.getDomainDocumentElement(domainXMLFile);
        if(domainDoc != null){
            NodeList clusters = domainDoc.getDocumentElement().getElementsByTagName("clusters");
            if(clusters != null){
                NodeList clusterList = ((Element)clusters.item(0)).getElementsByTagName("cluster");
                if((clusterList != null) && (clusterList.getLength() >0)){
                    for(int lh =0; lh < clusterList.getLength(); lh++){
                        String clName = ((Element)clusterList.item(lh)).getAttribute("name");
                        ClusterInfo clInfo = new ClusterInfo();
                        clInfo.setClusterName(clName);
                        clInfo.setDomainName(domainName);
                        clList.add(clInfo);
                    }
                }
            }
        }
        return clList;
    }*/
    //End - added
	
    private Document getDomainDocumentElement(String domainFileName){
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //factory.setValidating(true);
        factory.setNamespaceAware(true);
        Document resultDoc = null;
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            builder.setEntityResolver(
                   (org.xml.sax.helpers.DefaultHandler)Class.forName
                    ("com.sun.enterprise.config.serverbeans.ServerValidationHandler").newInstance());
            resultDoc = builder.parse( new File(domainFileName));
        }catch (Exception ex){
            logger.log(Level.WARNING,
                stringManager.getString(
                   "enterprise.tools.upgrade.iiop_port_domain_doc"),ex);
        }
        return resultDoc;
    }

    private void saveDocumentToDomainFile(String domainFileName,
                                             Document resultDoc){
        // Use a Transformer for output
        try{
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            if (resultDoc.getDoctype() != null){
                String systemValue = resultDoc.getDoctype().getSystemId();
                transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
                                                systemValue);
                String pubValue = resultDoc.getDoctype().getPublicId();
                transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, 
                                                 pubValue);
            }
            DOMSource source = new DOMSource(resultDoc);
            StreamResult result =
                new StreamResult(new FileOutputStream(domainFileName));
            transformer.transform(source, result);
            result.getOutputStream().close();
        }catch (Exception ex){
            logger.log(Level.WARNING,
                 stringManager.getString(
                     "enterprise.tools.upgrade.iiop_port_domain_save_fail"),ex);
            //throw new HarnessException(stringManager.getString("upgrade.transform.startFailureMessage"));
        }
    }
    
    public void recover() {
        List domainList = common.getDomainList();
        String sourceDir = common.getSourceDomainRoot();
        String targetDir = common.getTargetDomainRoot();
        if(domainList != null && sourceDir != null && targetDir != null) {
            Iterator itr = domainList.iterator();
            while(itr.hasNext()) {
                String dname = (String)itr.next();               
                boolean domainRootSame =
                     new File(sourceDir).equals(new File(targetDir));               
                if(domainRootSame) {
                    if(new File(sourceDir +
                          File.separator + "backup").isDirectory()) {                       
                        common.setCurrentDomain(dname);
                        String latestDomainPath=
                            common.findLatestDomainDir(sourceDir);                        
                        if(latestDomainPath != null) {
                            //Copy and Delete instead of rename because of the Windows issue.
                            try{
                                 copyDirectory(new File(latestDomainPath),
                                     new File(sourceDir + File.separator + dname));
                                 File backupdir = new File(sourceDir + File.separator + "backup");
                                 if(!deleteDirectory(backupdir)) {
                                     logger.log(Level.WARNING,
                                         stringManager.getString("DeleteDirectoryFailed", 
                                             backupdir.getAbsolutePath()));					 
                                 }
                            }catch (IOException e) {				 
                                logger.log(Level.SEVERE,
                                    stringManager.getString("CopyDirectoryFailed",
                                        latestDomainPath, sourceDir)); 
                            } 				    
			    /*	new File(latestDomainPath).renameTo(
                                new File(sourceDir + File.separator + dname));
                            File backupdir =
                                new File(sourceDir + File.separator + "backup");
                            String[] dirs = backupdir.list();
                            if(dirs.length == 0) {
                                //Added for CR 6500226			
                                //backupdir.delete();
                                if(!deleteDirectory(backupdir)) {
                                    logger.log(Level.WARNING, 
                                        stringManager.getString("DeleteDirectoryFailed",
                                            backupdir.getAbsolutePath()));
                                }
                                //End - added						
                            }*/
                        }
                    }
                }
                
            }//while loop
        }//not null check of domainList
    }
    
    public boolean validateUserDetails(String adminUserName, String adminPassword, String masterPassword){
        try{
            com.sun.enterprise.admin.servermgmt.RepositoryManager rManager =
                 new com.sun.enterprise.admin.servermgmt.RepositoryManager();
            String domainPath = this.common.getTargetDomainRoot();
            //Added for CR 6486068
            //The current domain is got from the domainList.			
            String domainName = "domain1";			
            List domainList = common.getDomainList();
            Iterator itr =  domainList.iterator();
            while(itr.hasNext()) {
                domainName = (String)itr.next();
            }				
            //if(!new File(domainPath+File.separator+"domain1").exists() ||
            if(!new File(domainPath+File.separator+domainName).exists() ||
            //End - added						
                    ((common.getSourceInstallDir() != null &&
                      common.getTargetInstallDir() != null) &&
                       (common.getSourceInstallDir().
                           equalsIgnoreCase(common.getTargetInstallDir() +
                                             File.separator + "domains") ||
                        (common.getSourceInstallDir().
                            equalsIgnoreCase(common.getTargetInstallDir()))))){
                // domain1 should exist in target directory in order to validate user name and password.
                // If this does not exist, then cannot validate user name and password.  Just return true.
                // In case of in-place upgrade domain1 is created by upgrade process.  The time this method is called for user details validation
                // the domain1 wouldnt have been created.  Also, in case if in-place upgrade upgrade is invoked soon after installation.
                // The upgrade tool uses com.sun.enterprise.admin.servermgmt.RepositoryConfig to validate passwords before the upgrade starts.
                // The RepositoryConfig.validateAdminUserAndPassword() method doesn't work if an 8.x domain hasn't been created.
                // In the in-place upgrade scenario the installer doesn't create one and this method gets called before the upgrade tool
                // creates one. When the upgrade tool does create a domain, it uses the passwords passed in by the installers to create the
                // new domains, so we don't have to worry about checking for incorrect passwords in this case.
                return true;
            }
            com.sun.enterprise.admin.servermgmt.RepositoryConfig repConf =
                 new com.sun.enterprise.admin.servermgmt.RepositoryConfig(
                     //Edited for CR 6486068
                     //validate against the current domain rather than domain1.
                     domainName,domainPath);
                     //"domain1",domainPath);
                     //End- edit			
            rManager.validateAdminUserAndPassword(repConf,
                                                  adminUserName,adminPassword);
            if((masterPassword != null) &&
                (!UpgradeConstants.EDITION_PE.equals(common.getSourceEdition())))
                //(!this.common.getTargetVersionAndEdition().equals(UpgradeConstants.VERSION_AS82_PE)))
                rManager.validateMasterPassword(repConf,masterPassword);
        }catch(com.sun.enterprise.admin.servermgmt.RepositoryException re){
            logger.log(Level.SEVERE,
                         stringManager.getString("enterprise.tools.upgrade.generalException",
                          re.getMessage()), re);
            return false;
        }
        return true;
    }
    public void updateDomainXMLWithPersistenceStoreProps(java.util.Properties props){
        // TODO
        // Read each property and add it to appropriate place in domain.xml
        // Yet to hear back from Larry white.
    }
    public void updateListenerPortsForClusteredInstances(Element docElement, String propertyName, String portValue, BaseElement bElement){
        NodeList servers = docElement.getElementsByTagName("servers");
        NodeList serverList = 
            ((Element)servers.item(0)).getElementsByTagName("server");
        String clusterName = this.common.getCurrentCluster();
        for(java.util.Iterator dItr =
             ClustersInfoManager.getClusterInfoManager().getClusterInfoList().iterator(); dItr.hasNext();){
            ClusterInfo cInfo = (ClusterInfo)dItr.next();
            if(cInfo.getClusterName().equals(clusterName)){
                for(java.util.Iterator clItr =
                       cInfo.getClusteredInstanceList().iterator();
                           clItr.hasNext();){
                    ClusteredInstance clInstance = (ClusteredInstance)clItr.next();
                    if(portValue == null){
                        this.addOrUpdateSystemPropertyToServer(
                            clInstance.getInstanceName(),
                                 serverList, propertyName, 
                                     clInstance.getInstancePort(),bElement);
                    }else{
                        this.addOrUpdateSystemPropertyToServer(
                            clInstance.getInstanceName(),
                                 serverList, propertyName, portValue,bElement);
                    }
                }
            }
        }
    }
    public void addOrUpdateSystemPropertyToServer(String serverName,
                    NodeList serverList, String propertyName, 
                        String propertyValue, BaseElement bElement){
        for(int lh =0; lh < serverList.getLength(); lh++){
            if(serverName.equals(((Element)serverList.item(lh)).
                                                     getAttribute("name"))){
                Element serverElement = (Element)serverList.item(lh);
                Element sysProp = 
                    this.getSystemPropertyElement(propertyName,serverElement);
                if(sysProp != null){
                    sysProp.setAttribute("value", propertyValue);
                    return;
                }
                if(sysProp == null){
                    // bElement could be passed as null in case if this property need not be added.
                    if(bElement != null){
                        sysProp =
                             serverElement.getOwnerDocument().
                                              createElement("system-property");
                        sysProp.setAttribute("name", propertyName);
                        sysProp.setAttribute("value", propertyValue);
                        bElement.appendElementToParent(serverElement,sysProp);
                    }
                }
                return;
            }
        }
    }
    
    public void copyFile(String source, String target) throws IOException {
        copyFile(source, target, false);
    }
    
    public void copyFile(String source, String target, boolean append) 
                 throws IOException{
        //copy the file
        FileReader in = new FileReader(new File(source));
        FileWriter out = new FileWriter(new File(target), append);
        int c;
        while ((c = in.read()) != -1) {
            out.write(c);
        }
        in.close();
        out.close();
    }
    
    //returns the value of the jvm-option or null if not found
    public String getJvmOptionValueFromSourceConfig(String optionName) {
        String sourceConfig = common.getSourceConfigXMLFile();
        Document sourceDoc = 
            this.getDomainDocumentElement(common.getSourceConfigXMLFile());
        NodeList serverList = sourceDoc.getElementsByTagName("server");
        String serverName = common.getCurrentSourceInstance();
        if (serverName == null || serverName == "") {
            serverName = "server";
        }
        String configName = null;
        String password = null;
        for(int i=0;i<serverList.getLength();i++){
            Node serverNode = (Node)serverList.item(i);
            NamedNodeMap attributes = serverNode.getAttributes();
            String name = (attributes.getNamedItem("name")).getNodeValue();
            if(serverName.equals(name)){
                configName = 
                    (attributes.getNamedItem("config-ref")).getNodeValue();
            }
        }
        if (configName != null) {
            NodeList jvmOptionList =
                 sourceDoc.getElementsByTagName("jvm-options");
            for(int j=0;j<jvmOptionList.getLength();j++) {
                Node jvmNode = jvmOptionList.item(j);
                String jvmOptions = getTextNodeData((Element)jvmNode);
                if (jvmOptions.indexOf(optionName) != -1) {
                    password = jvmOptions.substring(jvmOptions.indexOf("=")+1, jvmOptions.length());
                }
            }
        } else {
            logger.warning(stringManager.
                getString("enterprise.tools.upgrade.configNotFound", 
                    configName));
        }
        return password;
        
    }
    
    public String getTextNodeData(Element element){
        NodeList children = element.getChildNodes();
        for(int index=0; index < children.getLength(); index++){
            if(children.item(index).getNodeType() == Node.TEXT_NODE){
                return children.item(index).getNodeValue();
            }
        }
        return "";
    }

  /**
     * Copies the entire tree to a new location.
     *
     * @param   sourceTree  File pointing at root of tree to copy
     * @param   destTree    File pointing at root of new tree
     *
     * If target directory does not exist, it will be created.
     *
     * @exception  IOException  if an error while copying the content
     */
    public static void copyDirectory(File sourceDir , File targetDir)
                    throws IOException {

        if (sourceDir.isDirectory()) {
            if (!targetDir.exists()) {
                targetDir.mkdir();
            }

            String[] children = sourceDir.list();
            for (int i=0; i<children.length; i++) {
                copyDirectory(new File(sourceDir, children[i]),
                    new File(targetDir, children[i]));
            }
        } else {

            InputStream in = new FileInputStream(sourceDir);
            OutputStream out = new FileOutputStream(targetDir);

            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }
    }

     // start - added for 6396486
     /* Builds the application deployment parameters.
     * Builds an arraylist with the parameters enabled and virtual-servers
     * taken from the source domain.xml file.
     *
     */
    public ArrayList buildAppDeploymentParameters(String moduleName) {
        ArrayList appDeploymentParameters = null;
        String appEnabledStatus = null;
        String appVirtualServers = null;
        String sourceConfig = common.getSourceConfigXMLFile();
        Document sourceDoc = 
             this.getDomainDocumentElement(common.getSourceConfigXMLFile());
        NodeList appRefList = 
             sourceDoc.getDocumentElement().getElementsByTagName("application-ref");
        for(int i=0; i<appRefList.getLength(); i++) {
            Element element = ((Element)appRefList.item(i));
            if(null == element) {
            } else {
                if(element.getAttribute("ref").equals(moduleName)) {
                    appEnabledStatus = element.getAttribute("enabled");
                    appVirtualServers = element.getAttribute("virtual-servers");
                }
            }
        }
        if(appEnabledStatus != null || appVirtualServers != null) {
            appDeploymentParameters = new ArrayList();
        }
        if(appEnabledStatus != null) {
            appDeploymentParameters.add("--enabled=" + appEnabledStatus);
        }
        if(appVirtualServers != null && !(appVirtualServers.equals(""))) {
            appDeploymentParameters.add("--virtualservers");
            appDeploymentParameters.add(appVirtualServers);
        }
        return appDeploymentParameters;
    }

    //end - Added for 6396486

    //start - Added for 6392209
     /* Builds the web module deployment parameter context-root.
     * Returns a string with the parameters context-root value
     * taken from the source domain.xml file.
     *
     */
    public String buildWebModuleContextRoot(String moduleName) {
        String webModuleContextRoot = null;
        String actualModName = moduleName;
        if(common.getSourceVersion().equals(UpgradeConstants.VERSION_7X)) {
            //Fix for CR 6461423
            if(moduleName.lastIndexOf("_1") != -1) {
                actualModName = moduleName.substring(0,moduleName.lastIndexOf("_1"));
            } else {
                actualModName = moduleName;
            }
            //Fix for CR 6461423
        }

        String sourceConfig = common.getSourceConfigXMLFile();
        Document sourceDoc =
             this.getDomainDocumentElement(common.getSourceConfigXMLFile());
        NodeList webModuleList =
             sourceDoc.getDocumentElement().getElementsByTagName("web-module");
        for(int i=0; i<webModuleList.getLength(); i++) {
            Element element = ((Element)webModuleList.item(i));
            if(null == element) {
            } else {
                if(element.getAttribute("name").equals(actualModName)) {
                    webModuleContextRoot = element.getAttribute("context-root");
                }
            }
        }
        return webModuleContextRoot;
    }
    //end - Added for 6392209

    //start CR 6426419
    public String getSourceApplicationRoot(CommonInfoModel common) {
        String applicationRootDir = "applications";
        String applicationRoot = common.getSourceApplicationRoot();
        if(applicationRoot != null) {
            //Fix for CR 6444368
            applicationRoot =
                 applicationRoot.replaceAll("/", "\\" + File.separator);
            String[] aryApplRoot = applicationRoot.split("\\" + File.separator);
            //String[] aryApplRoot = applicationRoot.split(File.separator);
            //End - fix 6444368
            int indexApplRoot = (aryApplRoot.length) - 1;
            applicationRootDir = aryApplRoot[indexApplRoot];
        }
        
        return applicationRootDir;
    }
    //end CR 6426419
    
    //start - Added for CR 6480041
     /** 
       * Builds the web module target.
       * Returns a string that is the target server for this web module.
       * It is taken from the source domain.xml file.
       * Used only for > 8.1/8.2EE domain.xmls
       */
    public String buildAppDeploymentTarget(String moduleName) {
        String appTarget = null;
        String actualModName = moduleName;

        String sourceConfig = common.getSourceConfigXMLFile();
        Document sourceDoc =
             this.getDomainDocumentElement(common.getSourceConfigXMLFile());
        Element sourceDocumentElement = sourceDoc.getDocumentElement();	
        
        //Check for the occurence of the instance name in the clusters		
        NodeList clusters = sourceDocumentElement.getElementsByTagName("clusters");
        if(clusters != null) {
            Element clustersEle = (Element)clusters.item(0);
            if(clustersEle != null) {			
                NodeList clusterList = clustersEle.getElementsByTagName("cluster");
                if(clusterList != null) {		
                    for(int k=0; k<clusterList.getLength(); k++) {
                        Element cluster = (Element)clusterList.item(k);			
                        String clusterName = cluster.getAttribute("name");             
                        NodeList clusterAppRefs = cluster.getElementsByTagName("application-ref");
                        for(int j = 0; j<clusterAppRefs.getLength(); j++) {
                            Element clusterAppRef = (Element) clusterAppRefs.item(j);
                            String appRef = clusterAppRef.getAttribute("ref");
                            if(actualModName.equals(appRef)) {
                                //The target is a cluster name
                                appTarget = clusterName;
                                break;					
                            }								
                        }					
                    }            						
                }
            }
        }			
        if(appTarget != null) {
            return appTarget;
        }			
        NodeList servers = sourceDocumentElement.getElementsByTagName("servers");		
        if(servers != null) {		
            Element serversEle = (Element) servers.item(0);
            if(serversEle != null) {			
                NodeList serverList = serversEle.getElementsByTagName("server");
                if(serverList != null) {			
                    for(int lh =0; lh < serverList.getLength(); lh++){
		                Element server = (Element)serverList.item(lh);
			            String instanceName = server.getAttribute("name");
                        String configRef = server.getAttribute("config-ref");
                        //Get application refs for only stand alone servers
                        if((instanceName + "-config").equals(configRef)) {	
                            NodeList applicationRefList = server.getElementsByTagName("application-ref");
                            for(int i = 0; i<applicationRefList.getLength(); i++) {
                                Element applicationRef = (Element) applicationRefList.item(i);
                                String ref = applicationRef.getAttribute("ref");
                                if(actualModName.equals(ref)) {
                                    //The target can be a stand alone instance name or the DAS itself.
                                    if(!("server".equals(instanceName))) {
                                        appTarget = instanceName;
                                        break;						
                                    }
                                }									
                            }
                        }							
                    }							
                }            						
            }
        }			
        return appTarget;
    }
    //end - added

    //Added for CR 6500226
    public static boolean deleteDirectory(File dir) {
        if(dir.isDirectory()) {
            String[] subDirs = dir.list();
            for(int i=0; i<subDirs.length; i++) {
                boolean success = deleteDirectory(new File(dir, subDirs[i]));
                if(!success) {
                    return false;
                }
            }	
        }
        //Delete the empty directory
        return dir.delete();
    }
    //End - added	

    public static String getProfileInfoFromSourceInput(CommonInfoModel commonInfo) {
        String sourceEdition = commonInfo.getSourceEdition();
        if(UpgradeConstants.EDITION_PE.equals(sourceEdition)) {
            return UpgradeConstants.DEVELOPER_PROFILE;
        } else if(UpgradeConstants.EDITION_EE.equals(sourceEdition)) {
            return UpgradeConstants.ENTERPRISE_PROFILE;
        } else {
            //Source is SE
            return UpgradeConstants.DEVELOPER_PROFILE;
        }	    
    }	    
}
