# Copyright 2008-2014 Cumulus Systems Incorporated.
# All Rights Reserved.
#
# Version: 1.0

# This file contains the code to collect the Configuration data for a NetApp Storage whose IP Address, User Name and Password is passed as argument to
# this script.
#
# @param : Site Name - NetApp Site Name.
# @param : IP Address - NetApp Storage IP Address
# @param : User Name - User Name to access NetApp Storage.
# @param : Password - Password to access NetApp Storage.
#
# @return : In case of success, returns 0. In case of failure, returns 1.
#
# Sample command: perl netappDataCollector.pl <IP Address> <User Name> <Password>

#!/usr/bin/perl -w

# It is used for strict compilation.
use strict;

# It is used to get the current date and time.
use Time::HiRes qw(gettimeofday);
use POSIX "strftime";

# This is used to create folder recursively.
use File::Path qw(mkpath);

# This is used to get the current working directory.
use Cwd;

# It is used to get base file name from the complete file name.
use File::Basename;

# This variable is used to store the NetApp MDC release version number.
my $version = "1.0";

# This variable is used to store the total number of arguments expected by this script.
my $ARG_COUNT = 3;

# This variable is used to store the complete path of log folder.
my $netappLogFolder = "";

# This variable is used to store the complete path of final NetApp CLI output file.
my $finalCliOutputFile = "";

# This variable is used to store the name of final Zipped Conf file.
my $zipConfFileName = "";

# This variable is used to store the name of final Zipped Probe Custom file.
my $zipProbeCustomFileName = "";

# This variable is used to store the file handle for NetApp CLI output data.
my $CLI_DATA_HANDLE;

# This variable is used to store the file handle of MARS configuration file.
my $CONF_HANDLE;

# This variable is used to store the complete name of log file.
my $logFile = "";

# This variable is used to store the file handle of log file.
my $LOG_HANDLE;

# This variable is used to store the base folder path.
my $baseFolder = "";

# This variable is used to store NetApp Storage User name which is used to connect to the NetApp storage.
my $netappUserName = "";

# This variable is used to store NetApp Storage Password which is used to connect to the NetApp storage.
my $netappPassword = "";

# This variable is used to store NetApp Storage IP Address.
my $netappIpAddress = "";

# This variable is used to store the name of Raw configuration data file.
my $rawConfFile = "";

# This variable is used to store the name of folder where the processed MARS Data will be placed.
my $finalProcessedData = "";

# This variable is used to store MARS Site name.
my $marsSiteName = "";

# Contain Probe Version number.
my $probeVersion = "10";

# This variable is used to store the path which NetApp CLI output file will get created.
my $netappCliOutputPath = "";

# This variable stores the name of the probe custom file.
my $netappCliRawOutputFile = "";

# This variable is used to store the path where final NetApp CLI output file will get created.
my $finalConfFilePath = "";

# This variable is used to store location of NetApp runtime files.
my $netappRunTimeLocation = "";

# This holds the timestamp that will be used in final MARS Conf file and its corresponding List Of file name.
my $timeStamp = "";

# This holds the name of NetApp Storage. This name will be used for creating resource signature for all resources.
my $storageName = "";

# This variable is used to store the name of the file which is used to dump the Probe Custom Data.
my $netappProbeCustomFileName = "netappRawCliOutput.dump";

# This hashmap is used for storing the mapping of "Volume" to its total capacity.
my %volToTotalCap = ();

# This hashmap is used for storing the mapping of "Volume" to its used capacity.
my %volToUsedCap = ();

# This hashmap is used for storing the mapping of "Volume" to its available capacity.
my %volToAvailCap = ();

# This hashmap is used for storing the mapping of "Aggregate" to its Raid Size.
my %aggrToRaidSize = ();

# This array is used to store the name of filers present on the NetApp Storage.
my @filerList = ();

# It is used to store vFiler (key) and number of files associated with it (value).
my %vfilerAndNumberOfFile = ();

# It is used to store Qtree (key) and number of files associated with it (value).
my %qtreeAndNumberOfFile = ();

# It is used to store Qtree (key) and Used Disk Size associated with it (value).
my %qtreeAndUsedDiskSize = ();

# It is used to store Qtree (key) and Average File Size associated with it (value).
my %qtreeAndAverageFileSize = ();

# This HashMap stores Initiator Group as key and and its Initiator as value.
my %initiatorGroupToInitiator = ();

# This array stores all volume list which will be required for snapshot data collection.
my @netappVolList = ();

# This variable is used to store the return status of a function call.
my $status = 0;

# This variable is used to store the name of NetApp Expect script which is used to get the NetApp CLI data.
my $netappExpectScript = "netappGetCliData.sh";

# This variable stores the name of the Conf list of file name.
my $confListOfFileName = "";

# This variable stores the name of the Probe Custom data list of file name.
my $probeCustomListOfFileName = "";

# This variable is used to check whether we are able to find at least one filer on the NetApp Storage.
my $foundFiler = 0;

# This HashMap stores the volume name as key and its associated Qtree (comma separated list) as values. This will be used when a quota is imposed
# on all Qtrees of a Volume then we can use this hashMap "value" in dumping relations of Quota with Qtree.
my %volToQtree = ();

# This array is used to store volumes which are related with the given vFiler.
my @volList = ();

# This hashmap is used for storing the mapping of "Volume" to its Quota Status.
my %volToQuotaStatus = ();

# This folder contains the data for a particular storage,including conf, probecutom zip file and their associated ListOfFile.
my $finalDataZippedFolder = "";

# This file stores the final zipped file name containing the data for a particular storage,including conf, probecutom zip file and their associated ListOfFile.
my $finalZipFileName = "";

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Error codes corresponding to netappGetCliData.sh. Always keep it in sync with error codes in netappGetCliData.sh.
# ----------------------------------------------------------------------------------------------------------------------------------------------------
my $ERROR_SUCCESS               = 0;
my $ERROR_SSH_INVALID_CRED      = 1;
my $ERROR_SSH_CONNECTION_FAILED = 2;
my $ERROR_INVALID_OPTION_FOUND  = 3;

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Main function
# ----------------------------------------------------------------------------------------------------------------------------------------------------

# Initialize the environment.
$status = init();
if (0 != $status)
{
    logMsg("Error: Call to init() failed.");
    goto EXIT;
}

# Prepare the Probe Metadata.
$status = prepareProbeMetadata();
if (0 != $status)
{
    logMsg("Error: Call to prepareProbeMetadata() failed.");
    goto EXIT;
}

print "Begin Data Collection.\n";

# Get "System" configuration data.
$status = processSystemConfData();
if (0 != $status)
{
    logMsg("Error: Call to processSystemConfData() failed.");
    goto EXIT;
}

# Get "Quota" configuration data.
$status = processQuotaConfData();
if (0 != $status)
{
    logMsg("Error: Call to processQuotaConfData() failed.");
}

# Get "User" configuration data.
$status = processUserConfData();
if (0 != $status)
{
    logMsg("Error: Call to processUserConfData() failed.");
}

# Get "Group" configuration data.
$status = processGroupConfData();
if (0 != $status)
{
    logMsg("Error: Call to processGroupConfData() failed.");
}

# Get "Aggregate" configuration data.
$status = processAggregateConfData();
if (0 != $status)
{
    logMsg("Error: Call to processAggregateConfData() failed.");
}

# Get "Volume" configuration data.
$status = processVolumeConfData();
if (0 != $status)
{
    logMsg("Error: Call to processVolumeConfData() failed.");
}

# Get "Snapshot" configuration data.
$status = processSnapshotConfData();
if (0 != $status)
{
    logMsg("Error: Call to processSnapshotConfData() failed.");
}


# Get "Qtree" configuration data.
$status = processQtreeConfData();
if (0 != $status)
{
    logMsg("Error: Call to processQtreeConfData() failed.");
}

# Get "vFiler" configuration data.
$status = processVfilerConfData();
if (0 != $status)
{
    logMsg("Error: Call to processVfilerConfData() failed.");
}

# Get "NfsShare" configuration data.
$status = processNfsConfData();
if (0 != $status)
{
    logMsg("Error: Call to processNfsConfData() failed.");
}

# Get "SnapMirror" configuration data.
$status = processSnapMirrorConfData();
if (0 != $status)
{
    logMsg("Error: Call to processSnapMirrorConfData() failed.");
}

# Get "SnapVault" configuration data.
$status = processSnapVaultConfData();
if (0 != $status)
{
    logMsg("Error: Call to processSnapVaultConfData() failed.");
}

# Get "CifsShare" configuration data.
$status = processCifsShareConfData();
if (0 != $status)
{
    logMsg("Error: Call to processCifsShareConfData() failed.");
}

# Get "Fcp" configuration data.
$status = processFcpConfData();
if (0 != $status)
{
    logMsg("Error: Call to processFcpConfData() failed.");
}

# Get "Iscsi" configuration data.
$status = processIscsiConfData();
if (0 != $status)
{
    logMsg("Error: Call to processIscsiConfData() failed.");
}

# Get "InitiatorGroup" configuration data.
$status = processInitiatorGroupConfData();
if (0 != $status)
{
    logMsg("Error: Call to processInitiatorGroupConfData() failed.");
}

# Get "Lun" configuration data.
$status = processLunConfData();
if (0 != $status)
{
    logMsg("Error: Call to processLunConfData() failed.");
}

# Prepare the Probe Metadata.
$status = prepareProbeCustomMetadata();
if (0 != $status)
{
    logMsg("Error: Call to prepareProbeCustomMetadata() failed.");
}

# Get NetApp Probe Custom data.
$status = getNetAppProbeCustomData();
if (0 != $status)
{
    logMsg("Error: Call to getNetAppProbeCustomData() failed.");
}

print "End Data Collection.\n";

# Zip Final MARS Conf file.
$status = zipMarsFile($zipConfFileName, $confListOfFileName, $finalConfFilePath);
if (0 != $status)
{
    logMsg("Error: Call to zipMarsFile() failed.");
    goto EXIT;
}

# Zip Final MARS Probe Custom file.
$status = zipMarsFile($zipProbeCustomFileName, $probeCustomListOfFileName, $finalCliOutputFile);
if (0 != $status)
{
    logMsg("Error: Call to zipMarsFile() failed.");
    goto EXIT;
}

# Zip Final data folder.
$status = zipFinalDataFolder();
if (0 != $status)
{
    logMsg("Error: Call to zipFinalDataFolder() failed.");
    goto EXIT;
}

EXIT:

# De-init the environment.
deInit();

logMsg("Info: Return status: [$status].");

print "Result:\n";

if (0 == $status)
{
    print "Configuration data collection is completed for <$netappIpAddress>. The final zip data file <$finalZipFileName> is kept at: ";
    print "<$finalProcessedData>\n";
}
else
{
    print "Configuration data collection failed for <$netappIpAddress>. For more details, see logs in: <$netappLogFolder>\n";
}

exit $status;

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Sub-routines
# ----------------------------------------------------------------------------------------------------------------------------------------------------

# This function is used to initialize the environment to run the Perl script correctly.
#
# @affected global variables :
#   $baseFolder
#   $netappIpAddress
#   $netappUserName
#   $netappPassword
#   $netappCliOutputPath
#   $timeStamp
#   $netappRunTimeLocation
#   $netappLogFolder
#   $finalProcessedData
#   $timeStamp
#   $finalConfFilePath
#   $zipConfFileName
#   $confListOfFileName
#   $zipProbeCustomFileName
#   $probeCustomListOfFileName
#   $finalDataZippedFolder
#
# @return :
#   0 if Success
#   0> if Error
sub init
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # Set MARS base folder.
    $baseFolder = dirname(cwd());

    # Set the variable which is used to store location of NetApp runtime files.
    $netappRunTimeLocation = $baseFolder."/bin";

    # Set NetApp log folder path.
    $netappLogFolder = $baseFolder."/logs";

    # If log folder does not exist then create it.
    if (!(-e $netappLogFolder))
    {
        # Create log folder.
        unless (defined eval {mkpath($netappLogFolder)})
        {
            print("Error: Not able to create folder: [$netappLogFolder].");
            $retVal = 1;

            goto EXIT;
        }
    }

    # If number of command line arguments are not correct then quit.
    if ($ARG_COUNT != ($#ARGV + 1))
    {
        print "Number of arguments to netappDataCollector.pl are incorrect. Run the script as follow:\n";
        print "perl netappDataCollector.pl <Site Name> <Storage IP> <Storage User Name>\n";
        print "For example: perl netappDataCollector.pl HDS 192.168.1.1 mdcuser\n\n";

        logMsg("Error: Number of arguments to netappDataCollector.pl are not correct. Input argument count = [".($#ARGV + 1)."]");
        $retVal = 1;

        goto EXIT;
    }

    # Get NetApp Site name from command line argument.
    $marsSiteName = $ARGV[0];

    # Replace underscore with hyphen in site name, since we are splitting the tokens in the file name on the basis of underscore.
    $marsSiteName =~ s/_/-/g;

    # Get NetApp Storage IP Address from command line argument.
    $netappIpAddress = $ARGV[1];

    # Get NetApp Storage User Name from command line argument.
    $netappUserName = $ARGV[2];

    logMsg("Info: NetApp MDC version: [$version].");
    logMsg("Info: NetApp MDC base location: [$baseFolder].");
    logMsg("Info: Input Site Name = [$marsSiteName]");
    logMsg("Info: Input IP Address = [$netappIpAddress]");
    logMsg("Info: Input User Name = [$netappUserName]");

    # Prompt the user to enter the password.
    print "Password: ";

    # Disable echoing.
    system('/bin/stty', '-echo');

    # Accept the password from the user.
    $netappPassword = <STDIN>;

    # Turn echoing back on.
    system('/bin/stty', 'echo');

    # Remove new line character from password.
    chomp($netappPassword);

    print "\n\n******************************************************************\n";

    # Set the path where NetApp final MARS format data will get dumped.
    $finalProcessedData = $baseFolder."/data/conf/";
    logMsg("Info: Creating NetApp Data folder: [$finalProcessedData].");

    # Create the folder for final conf data.
    unless (defined eval {mkpath($finalProcessedData)})
    {
        logMsg("Error: Not able to create folder: [$finalProcessedData].");
        $retVal = 1;

        goto EXIT;
    }

    $finalDataZippedFolder = $finalProcessedData."MDC_$marsSiteName"."_$netappIpAddress/";
    logMsg("Info: Creating NetApp final Data folder: [$finalDataZippedFolder].");

    # Create the folder for final conf data.
    unless (defined eval {mkpath($finalDataZippedFolder)})
    {
        logMsg("Error: Not able to create folder: [$finalDataZippedFolder].");
        $retVal = 1;

        goto EXIT;
    }

    # Set the path where NetApp CLI output will get dumped. It should be: /home/megha/netapp/data/<NetApp IP>/temp
    $netappCliOutputPath = $baseFolder."/data/$netappIpAddress/temp";
    logMsg("Info: Creating NetApp CLI output folder: [$netappCliOutputPath].");

    # Create the folder for temporary conf data.
    unless (defined eval {mkpath($netappCliOutputPath)})
    {
        logMsg("Error: Not able to create folder: [$netappCliOutputPath].");
        $retVal = 1;

        goto EXIT;
    }

    print "Verifying input arguments.\n";

    # This Function verifies the entered input argument.
    $retVal = testCredentials();
    if (0 != $retVal)
    {
        print "Error: The input arguments to the script are incorrect. Verify the input arguments and run the script again.\n";
        logMsg("Error: Call to testCredentials() failed.");

        goto EXIT;
    }

    # It is used to store the current date and time in "YYYYMMDD_HHMMSS" format.
    $timeStamp = strftime("%Y%m%d_%H%M%S", localtime(time));

    # Set the final Configuration file name.
    my $finalConfFileName = $marsSiteName."_".$netappIpAddress."_snapshot_".$timeStamp."_".$probeVersion.".txt";
    logMsg("Info: NetApp Conf File name: [$finalConfFileName].");

    $zipConfFileName = "Conf".$timeStamp."_".$marsSiteName."_".$netappIpAddress."=_NetApp.zip";
    logMsg("Info: NetApp Conf zip file name: [$zipConfFileName].");

    $confListOfFileName = $finalDataZippedFolder."/ListOfFiles".$timeStamp."_".$marsSiteName."_".$netappIpAddress."=_NetApp_Conf.txt";
    logMsg("Info: NetApp Conf ListOfFile file path: [$confListOfFileName].");

    $zipProbeCustomFileName = "ProbeCustomData".$timeStamp."_".$marsSiteName."_".$netappIpAddress."=_NetApp.zip";
    logMsg("Info: NetApp Probe custom data file name: [$zipProbeCustomFileName].");

    $probeCustomListOfFileName = $finalDataZippedFolder."/ListOfFiles".$timeStamp."_".$marsSiteName."_".$netappIpAddress."=_NetApp_ProbeCustomData.txt";
    logMsg("Info: NetApp Probe custom data ListOfFile file name: [$probeCustomListOfFileName].");

    # Set the final Configuration file path.
    $finalConfFilePath = $netappCliOutputPath."/".$finalConfFileName;
    logMsg("Info: NetApp Conf File path: [$finalConfFilePath].");

    # Get the list of filers present on the NetApp Storage. This list will be used for getting data for resources corresponding to the given vFiler.
    my $retValue = getFilerList(\@filerList);
    if (0 != $retValue)
    {
        logMsg("Error: Call to getFilerList() failed.");
        goto EXIT;
    }

EXIT:

    return $retVal;
}

# This function is used to parse the Raw Configuration data of System Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#   $storageName
#
# @return :
#   0 if Success
#   0> if Failure
sub processSystemConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # It is used to store the "id" configuration data for NetApp "System" resource.
    my $id = "";

    # It is used to store the "model" configuration data for NetApp "System" resource.
    my $model = "";

    # It is used to store the "machineType" configuration data for NetApp "System" resource.
    my $machineType = "";

    # It is used to store the "vendor" configuration data for NetApp "System" resource.
    my $vendor = "NetApp";

    # It is used to store the "serialNumber" configuration data for NetApp "System" resource.
    my $serialNumber = "";

    # It is used to store the "memorySize" configuration data for NetApp "System" resource.
    my $memorySize = "";

    # It is used to store the "numProcessors" configuration data for NetApp "System" resource.
    my $numProcessors = "";

    # It is used to store the "cpuSerialNumber" configuration data for NetApp "System" resource.
    my $cpuSerialNumber = "";

    # It is used to store the "cpuMicroCodeVersion" configuration data for NetApp "System" resource.
    my $cpuMicroCodeVersion = "";

    # It is used to store the "raidArraySupport" configuration data for NetApp "System" resource.
    my $raidArraySupport = "";

    # It is used to store the "snapMirrorAvailable" configuration data for NetApp "System" resource.
    my $snapMirrorAvailable = "false";

    # It is used to collect the Version of NetApp Storage.
    my $version = "";

    # It is used to collect the Mode of NetApp Storage.
    my $mode = "";

    $rawConfFile = $netappCliOutputPath."/netappSystemConf.dump";

    print "    Collecting system resource configuration data...";

    # This variable is used to store the command to get the NetApp raw "System" Resource data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." System $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript System $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get NetApp raw "System" Resource data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem in collecting NetApp raw "System" Resource data then it is an error.
        logMsg("Error: Failed to collect System Conf Data for NetApp Storage.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSystemConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "System" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect System Conf Data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the System data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of System data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)NetApp Release(\s*)(.+)(\s+)(\w)-Mode:(\s*)(.+)(\s*)$/)
        {
            $version = $3;
            $mode = $5."-Mode";
        }
        # In some cases we only get the version and no mode information is there.
        elsif (/^(\s*)NetApp Release(\s+)(.+?):(.*)(\s*)$/)
        {
            $version = $3;

            # If Mode information is not coming then we can assume that it is 7-Mode as C-Mode are the latest addition in NetApp.
            $mode = "7-Mode";
        }
        elsif (/^(\s*)System ID(\s*):(\s*)(.+)(\s*)\((.+)\)(\s*)$/)
        {
            my @serialInfolist = split(/ /, $4);
            $id = $serialInfolist[0];
        }
        elsif (/^(\s*)System Serial Number(\s*):(\s*)(.+)(\s*)\((.+)\)(\s*)$/)
        {
            $serialNumber = $4;

            $storageName = $6;
        }
        elsif (/^(\s*)Model Name(\s*):(\s*)(.+)(\s*)$/)
        {
            $model = $4;

            # Remove trailing spaces.
            $model =~ s/\s+$//;

            $machineType = $model;
        }
        elsif (/^(\s*)Processors(\s*):(\s*)(\d+)(\s*)$/)
        {
            $numProcessors = $4;
        }
        elsif (/^(\s*)Memory Size(\s*):(\s*)(\d+)(\s*)(\w*)(\s*)$/)
        {
            $memorySize = $4;

            if ("GB" eq $6)
            {
                $memorySize = $memorySize * 1024;
            }

            if ("TB" eq $6)
            {
                $memorySize = $memorySize * 1024 * 1024;
            }
        }
        elsif (/^(\s*)Serial Number(\s*):(\s*)(.+)(\s*)$/)
        {
            $cpuSerialNumber = $4;

            # Remove trailing spaces.
            $cpuSerialNumber =~ s/\s+$//;
        }
        elsif (/^(\s*)Microcode Version(\s*):(\s*)(\w+)(\s*)/)
        {
            my $num = $4;

            # Convert the "Microcode Version" from HexaDecimal to Decimal.
            $cpuMicroCodeVersion = sprintf("%d", hex($num));
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);

    # Collect information about SnapMirror.
    $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappSnapMirrorStatusConf.dump";

    # This variable is used to store the command to get NetApp System "SnapMirror Status" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapMirrorStatus $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapMirrorStatus $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get NetApp System "SnapMirror Status" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting NetApp System "SnapMirror Status" data then it is an error.
        logMsg("Error: Failed to collect SnapMirror Status for NetApp Storage.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSnapMirrorStatusConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        # If following condition is true then "SnapMirror" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect SnapMirror status as command not found.");
            last;
        }

        # If following condition is true then it is end of the "SnapMirror" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of SnapMirror data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Snapmirror is(\s*)(\w+).(\s*)$/)
        {
            if ("on" eq $3)
            {
                $snapMirrorAvailable = "true";
            }
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    # Dump the System resource information in the final MARS configuration file.
    print $CONF_HANDLE "R:naSystem#$storageName\n";
    print $CONF_HANDLE "a:name=$storageName\n";
    print $CONF_HANDLE "a:id=$id\n";
    print $CONF_HANDLE "a:model=$model\n";
    print $CONF_HANDLE "a:machineType=$machineType\n";
    print $CONF_HANDLE "a:vendor=$vendor\n";
    print $CONF_HANDLE "a:serialNumber=$serialNumber\n";
    print $CONF_HANDLE "a:memorySize=$memorySize\n";
    print $CONF_HANDLE "a:numProcessors=$numProcessors\n";
    print $CONF_HANDLE "a:cpuSerialNumber=$cpuSerialNumber\n";
    print $CONF_HANDLE "a:cpuMicroCodeVersion=$cpuMicroCodeVersion\n";
    print $CONF_HANDLE "a:snapMirrorAvailable=$snapMirrorAvailable\n";
    print $CONF_HANDLE "a:version=$version\n";
    print $CONF_HANDLE "a:mode=$mode\n";

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of User Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processUserConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappUserConf.dump";

    print "    Collecting user resource configuration data...";

    # This variable is used to store the command to get the NetApp raw "User" Resource data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." User $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript User $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get NetApp raw "User" Resource data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting NetApp raw "User" Resource data then it is an error.
        logMsg("Error: Failed to collect User Conf Data for NetApp Storage.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappUserConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "User" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the functions.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect User conf data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the User data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of User data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Name:(\s+)(.+)(\s*)$/)
        {
            my $name = $3;

            # Remove trailing spaces from the name.
            $name =~ s/\s+$//;

            print $CONF_HANDLE "R:naUser#$storageName^$name\n";
            print $CONF_HANDLE "a:name=$storageName^$name\n";
        }
        elsif (/^(\s*)Rid:(\s*)(\w+)(\s*)$/)
        {
            my $rid = $3;

            # Remove trailing spaces.
            $rid =~ s/\s+$//;

            print $CONF_HANDLE "a:rid=$rid\n";
        }
        elsif (/^(\s*)Groups:(\s*)(.*)(\s*)$/)
        {
            my $groupName = $3;

            # Remove trailing spaces.
            $groupName =~ s/\s+$//;

            print $CONF_HANDLE "a:group=$groupName\n";

            if ("" ne $3)
            {
                print $CONF_HANDLE "r:naGroup#$storageName^$groupName\n";
            }

            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Group Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processGroupConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappGroupConf.dump";

    print "    Collecting group resource configuration data...";

    # This variable is used to store the command to get the NetApp raw "Group" Resource data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." Group $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Group $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get NetApp raw "Group" Resource data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting NetApp "Group" Resource Conf Data then it is an error.
        logMsg("Error: Failed to collect Group Resource Conf Data for NetApp Storage.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netAppGroupConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Group" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect Group resource conf data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Group data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Group data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Name:(\s+)(.+)(\s*)$/)
        {
            my $name = $3;

            # Remove trailing spaces from the name.
            $name =~ s/\s+$//;

            print $CONF_HANDLE "R:naGroup#$storageName^$name\n";
            print $CONF_HANDLE "a:name=$storageName^$name\n";
        }
        elsif (/^(\s*)Rid:(\s*)(.*)(\s*)$/)
        {
            my $rid = $3;

            # Remove trailing spaces from the rid.
            $rid =~ s/\s+$//;

            print $CONF_HANDLE "a:rid=$rid\n";
        }
        elsif (/^(\s*)Roles:(\s*)(.*)(\s*)$/)
        {
            my $roles = $3;

            # Remove trailing spaces from the role.
            $roles =~ s/\s+$//;

            print $CONF_HANDLE "a:roles=$roles\n";
            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Volume Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processVolumeConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    print "    Collecting volume resource configuration data...";

    # If there is no vfiler license present on the machine then process with default vfiler name.
    if (0 == $foundFiler)
    {
        $rawConfFile = $netappCliOutputPath."/netapp_vfiler0_VolumeQuotaStatus.dump";

        # This variable is used to store the command to get the NetApp raw "Volume Quota status" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." QuotaStatusWithoutFiler $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript QuotaStatusWithoutFiler $netappIpAddress $netappUserName <password>> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume Quota status" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume Quota status" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume Quota status data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        getVolumeQuotaStatusInfo($rawConfFile);

        $rawConfFile = $netappCliOutputPath."/netapp_vfiler0_VolumeList.dump";

        # This variable is used to store the command to get the NetApp raw "Volume List" data.
        $cmd = $netappRunTimeLocation."/".$netappExpectScript." VolumeListWithoutFiler $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VolumeListWithoutFiler $netappIpAddress $netappUserName <password>> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume List" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume List" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume List data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = populateVolList($rawConfFile);
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to populateVolList() failed.");
            goto EXIT;
        }

        $retVal = processVolumeDumpFile("vfiler0");
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processVolumeDumpFile() failed.");
        }

        goto EXIT;
    }

    # Loop through each filer name.
    foreach my $vfilerName (@filerList)
    {
        $rawConfFile = $netappCliOutputPath."/netapp_".$vfilerName."_VolumeQuotaStatus.dump";

        # This variable is used to store the command to get the NetApp raw "Volume Quota status" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." QuotaStatus $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript QuotaStatus $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume Quota status" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume Quota status" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume Quota status data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        getVolumeQuotaStatusInfo($rawConfFile);

        $rawConfFile = $netappCliOutputPath."/netapp_".$vfilerName."_VolumeList.dump";

        # This variable is used to store the command to get the NetApp raw "Volume List" data.
        $cmd = $netappRunTimeLocation."/".$netappExpectScript." VolumeList $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VolumeList $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume List" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume List" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume List data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = populateVolList($rawConfFile);
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to populateVolList() failed.");
            goto EXIT;
        }

        $retVal = processVolumeDumpFile($vfilerName);
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processVolumeDumpFile() failed.");
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to put the processed Volume Quota Status data in the final MARS Configuration file.
#
# @param :
#   $_[0] - Raw Conf file name.
#
# @affected global variables :
#   @volList
#   %volToQuotaStatus
#
# @return :
#   Nothing
sub getVolumeQuotaStatusInfo
{
    # Get the raw Quota status file name.
    $rawConfFile = $_[0];

    # This variable stores the volume name.
    my $volName = "";

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "VolumeQuotaStatus.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Volume Quota Status" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Volume Quota status data as command not found.");
            last;
        }

        # If following condition is true then it is end of the "Volume Quota Status" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Quota data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(.+):(\s*)quotas are(\s*)(\w+)(\s*).(\s*)$/)
        {
            my $volName = $2;

            # Remove trailing white-spaces from the volume name.
            $volName =~ s/\s+$//;

            $volToQuotaStatus{$volName} = $5;
        }
        else
        {
            # Current line is of no use so skip it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to Populate Volume list array. The elements of this array will be iterated and then individual volume information will be
# dumped in final MARS Configuration file.
#
# @param :
#   $_[0] - Raw Conf file name.
#
# @affected global variables :
#   @volList
#   @netappVolList
#
# @return :
#   Nothing
sub populateVolList
{
    # Get the raw Quota status file name.
    $rawConfFile = $_[0];

    my $retVal = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    my $volName = "";

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "VolumeList.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Volume List" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Volume List data as command not found.");

            $retVal = 1;
            last;
        }

        # If following condition is true then it is end of the "Volume List" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Volume List data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(.+)(\s+)(\w+)(\s+)(\w+),(\s+)(\w+)(\s+)(.+)(\s*)$/)
        {
            $volName = $2;

            # Remove trailing white-spaces from the volume name.
            $volName =~ s/\s+$//;

            push(@volList, $volName);

            # This list will be used for getting snapshot information.
            push(@netappVolList, $volName);
        }
        elsif (/^(\s*)(.+)(\s+)(\w+)(\s+)(\w+),(\s+)(\w+)(\s*)$/)
        {
            $volName = $2;

            # Remove trailing white-spaces from the volume name.
            $volName =~ s/\s+$//;

            push(@volList, $volName);

            # This list will be used for getting snapshot information.
            push(@netappVolList, $volName);
        }
        else
        {
            # Current line is of no use so skip it.
        }
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to put the processed Volume data in the final MARS Configuration file.
#
# @param :
#   $_[0] - vFiler name.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   0> if Error
sub processVolumeDumpFile
{
    # Get the vFiler name.
    my $vfilerName = $_[0];

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable stores the total capacity corresponding to the given Volume.
    my $totalCapacity = "";

    # This variable stores the used capacity corresponding to the given Volume.
    my $usedCapacity = "";

    # This variable stores the free capacity corresponding to the given Volume.
    my $availCapacity = "";

    # Iterate the array of volumes to get the volume information corresponding to a given vFiler.
    while (my $volName = shift(@volList))
    {
        if (exists $volToTotalCap{$volName})
        {
            $totalCapacity = $volToTotalCap{$volName};
        }

        if (exists $volToUsedCap{$volName})
        {
            $usedCapacity = $volToUsedCap{$volName};
        }

        if (exists $volToAvailCap{$volName})
        {
            $availCapacity = $volToAvailCap{$volName};
        }

        my $isCacheRemoteLocation = 0;

        # It stores the options value corresponding to the given Volume.
        my $volOptions  = "";

        # This variable stores the raid status of the given Volume.
        my $raidStatus = "";

        # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
        my $confDataStart = 0;

        # Construct the complete name of NetApp Volume Options raw output file where Volume related information, will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappVolume_".$volName."_Options.dump";

        # This variable is used to store the command to get the NetApp raw "Volume Options" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." VolumeOptions $netappIpAddress $netappUserName $netappPassword $volName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VolumeOptions $netappIpAddress $netappUserName <password> $volName> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume Options" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume Options" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume Options data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

        # Loop through the content of "netAppVolumeOptions.dump" file.
        while (<CONF_DUMP>)
        {
            # Remove the new line character.
            chomp;

            # If following condition is true then "Volume Options" data will start from the next line.
            if ($_ =~ /^Output start$/)
            {
                $confDataStart = 1;

                # Skip this line as it doesn't contain any useful data.
                next;
            }

            # If the command is not supported then exit from the loop.
            if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
            {
                logMsg("Error: Failed to collect the NetApp raw Volume Options data as command not found.");
                last;
            }

            # If following condition is true then it is end of the "Volume Options" data.
            if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
            {
                # Replace all Commas with semicolons as on the reporting side, we have done the parsing on the basis of semicolon.
                $volOptions =~ s/,/;/g;

                last;
            }

            # If we haven't reached at the beginning of System data then skip the current line.
            if (1 != $confDataStart)
            {
                next;
            }

            if (/^(\s*)(.+)(,|\w+)(\s*)$/)
            {
                $volOptions = $volOptions.$2.$3;
            }
        }

        close (CONF_DUMP);

        $confDataStart = 0;

        # Construct the complete name of NetApp Volume raw output file where Volume related information will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappVolume_".$volName."_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Volume" data.
        $cmd = $netappRunTimeLocation."/".$netappExpectScript." Volume $netappIpAddress $netappUserName $netappPassword $volName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Volume $netappIpAddress $netappUserName <password> $volName> $rawConfFile].");

        # Run the command to get the NetApp raw "Volume" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Volume" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Volume data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

        # Loop through the content of "netAppVolumeConf.dump" file.
        while (<CONF_DUMP>)
        {
            # Remove the new line character.
            chomp;

            # If following condition is true then "Volume" data will start from the next line.
            if ($_ =~ /^Output start$/)
            {
                $confDataStart = 1;

                # Skip this line as it doesn't contain any useful data.
                next;
            }

            # If the command is not supported then exit from the loop.
            if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
            {
                logMsg("Error: Failed to collect the NetApp raw Volume data as command not found.");

                $retVal = 1;
                goto EXIT;
            }

            # If following condition is true then it is end of the "Volume" data.
            if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
            {
                last;
            }

            # If we haven't reached at the beginning of Volume data then skip the current line.
            if (1 != $confDataStart)
            {
                next;
            }

            # We get cacheRemoteLocation value in case of flexcache volume, we get it through the "Source" value.
            if (/^(\s*)Volume(\s+)State(\s+)Status(\s+)Options(\s+)Source(\s*)$/)
            {
                $isCacheRemoteLocation = 1;
            }
            # The Parsing in case of flexcache volume is different,since in this case we get extra information of cacheRemoteLocation.
            elsif ((1 == $isCacheRemoteLocation) && (/^(\s*)(\w+)(\s+)(\w+)(\s+)(\w*),(\s*)(\w*)(\s+)(.+)(\s+)(.+)(\s*)$/))
            {
                $volName = $2;
                $raidStatus = $6;

                print $CONF_HANDLE "R:naVolume#$storageName^$2\n";
                print $CONF_HANDLE "a:name=$storageName^$2\n";
                print $CONF_HANDLE "a:type=$8\n";
                print $CONF_HANDLE "a:raidStatus=$6\n";
                print $CONF_HANDLE "a:capacity=$totalCapacity\n";
                print $CONF_HANDLE "a:usedCapacity=$usedCapacity\n";
                print $CONF_HANDLE "a:freeCapacity=$availCapacity\n";
                print $CONF_HANDLE "a:state=$4\n";
                print $CONF_HANDLE "a:vFiler=$vfilerName\n";
                print $CONF_HANDLE "a:options=$volOptions\n";
                print $CONF_HANDLE "a:cacheRemoteLocation=$12\n";

                if (exists $volToQuotaStatus{$2})
                {
                    print $CONF_HANDLE "a:quotaStatus=$volToQuotaStatus{$2}\n";
                }
            }
            elsif ((0 == $isCacheRemoteLocation) && (/^(\s*)(\w+)(\s+)(\w+)(\s+)(\w*),(\s*)(\w*)(\s+)(.+)(\s*)$/))
            {
                $volName = $2;
                $raidStatus = $6;

                print $CONF_HANDLE "R:naVolume#$storageName^$2\n";
                print $CONF_HANDLE "a:name=$storageName^$2\n";
                print $CONF_HANDLE "a:type=$8\n";
                print $CONF_HANDLE "a:capacity=$totalCapacity\n";
                print $CONF_HANDLE "a:usedCapacity=$usedCapacity\n";
                print $CONF_HANDLE "a:freeCapacity=$availCapacity\n";
                print $CONF_HANDLE "a:state=$4\n";
                print $CONF_HANDLE "a:vFiler=$vfilerName\n";
                print $CONF_HANDLE "a:options=$volOptions\n";
                print $CONF_HANDLE "a:cacheRemoteLocation=\n";

                if (exists $volToQuotaStatus{$2})
                {
                    print $CONF_HANDLE "a:quotaStatus=$volToQuotaStatus{$2}\n";
                }

                # Create the Volume Path variable.
                my $volPath = "/vol/".$2;

                my $sisDataStart = 0;

                my $volSisFile = $netappCliOutputPath."/netappVolume_".$2."_Sis.dump";

                # This variable is used to store the command to get the NetApp raw "Volume Sis" data.
                $cmd = $netappRunTimeLocation."/".$netappExpectScript." VolumeSis $netappIpAddress $netappUserName $netappPassword $volPath> ".$volSisFile;
                logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VolumeSis $netappIpAddress $netappUserName <password> $volPath> $volSisFile].");

                # Run the command to get the NetApp raw "Volume Sis" data.
                $exitCode = executeSystemCmd($cmd);
                if ($ERROR_SUCCESS != $exitCode)
                {
                    # If there is some problem is collecting the NetApp raw "Volume Sis" data then it is an error.
                    logMsg("Error: Failed to collect the NetApp raw Volume Sis data.");

                    $retVal = $exitCode;
                    goto EXIT;
                }

                open(CONF_SIS_DUMP, $volSisFile) or die logMsg("Error: Not able to open the file: [$volSisFile].");

                # Loop through the content of "netAppVolumeSis.dump" file.
                while (<CONF_SIS_DUMP>)
                {
                    # Remove the new line character.
                    chomp;

                    # If following condition is true then "Volume Sis" data will start from the next line.
                    if ($_ =~ /^Output start$/)
                    {
                        $sisDataStart = 1;

                        # Skip this line as it doesn't contain any useful data.
                        next;
                    }

                    # If the command is not supported then exit from the loop.
                    if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
                    {
                        logMsg("Error: Failed to collect the NetApp raw Volume Sis data as command not found.");
                        last;
                    }

                    # If following condition is true then it is end of the "Volume Sis" data.
                    if ((1 == $sisDataStart) && ($_ =~ /^Output end$/))
                    {
                        last;
                    }

                    # If we haven't reached at the beginning of Volume SIS data then skip the current line.
                    if (1 != $sisDataStart)
                    {
                        next;
                    }

                    if (/^(\s*)State:(\s*)(\w*)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisState=$3\n";
                    }
                    elsif (/^(\s*)Status:(\s*)(\w*)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisStatus=$3\n";
                    }
                    elsif (/^(\s*)Type:(\s*)(\w*)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisType=$3\n";
                    }
                    elsif (/^(\s*)Last Operation Begin:(\s*)(.+)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisLastOpBeginTimestamp=$3\n";
                    }
                    elsif (/^(\s*)Last Operation End:(\s*)(.+)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisLastOpEndTimestamp=$3\n";
                    }
                    elsif (/^(\s*)Last Operation Size:(\s*)(\d+)(\s*)(\w*)(\s*)$/)
                    {
                        my $sisLastOpSize = covertCapToBytes($3, $5);
                        print $CONF_HANDLE "a:sisLastOpSize=$sisLastOpSize\n";
                    }
                    elsif (/^(\s*)Schedule:(\s*)(.+)(\s*)$/)
                    {
                        print $CONF_HANDLE "a:sisSchedule=$3\n";
                    }
                }

                close (CONF_SIS_DUMP);
            }
            elsif (/^(\s*)(\w+)=(\w+),(\s+)(\w+)=(.+)(\s*)$/)
            {
                # Skip this line as current line is of no use.
            }
            elsif (/^(\s*)(\w+)=(\w+)(,|(\s))(\s*)$/)
            {
                # Skip this line as current line is of no use.
            }
            elsif (/^(\s*)(.+)(\s+)(\w+)=(\w+),(\s+)(\w+)=(\w+),(\s*)$/)
            {
                my $raidInfo = $2;

                $raidInfo =~ s/\s+$//;
                $raidStatus = "$raidStatus,$raidInfo";
            }
            elsif (/^(\s*)(.+)(\s+)(\w+)=(\w+),(\s*)$/)
            {
                my $raidInfo = $2;

                $raidInfo =~ s/\s+$//;
                $raidStatus = "$raidStatus,$raidInfo";
            }
            elsif (/^(\s*)(.*)Clone, backed by volume '(.+)', snapshot '(.+)'(\s*)(.*)(\s*)$/)
            {
                print $CONF_HANDLE "a:cloneParentVolumeName=$3\n";
                print $CONF_HANDLE "a:cloneParentSnapshotName=$4\n";
            }
            # In case the Aggregate info is "aggregate: <N/A> ", then use volume name in dumping relation to aggregate as it should be a "trad"
            # volume which is tightly couple with aggregate.
            elsif (/^(\s*)Containing aggregate:(\s+)<(.+)>(\s*)$/)
            {
                if (exists $aggrToRaidSize{$volName})
                {
                    print $CONF_HANDLE "a:raidSize=$aggrToRaidSize{$volName}\n";
                }

                print $CONF_HANDLE "a:raidStatus=$raidStatus\n";
                print $CONF_HANDLE "r:naAggregate#$storageName^$volName\n";
                print $CONF_HANDLE "r:naVFiler#$storageName^$vfilerName\n";
            }
            # Get the raid size for volumes from the related aggregate.
            elsif (/^(\s*)Containing aggregate:(\s+)'(\w+)'(\s*)$/)
            {
                if (exists $aggrToRaidSize{$3})
                {
                    print $CONF_HANDLE "a:raidSize=$aggrToRaidSize{$3}\n";
                }

                print $CONF_HANDLE "a:raidStatus=$raidStatus\n";
                print $CONF_HANDLE "r:naAggregate#$storageName^$3\n";
                print $CONF_HANDLE "r:naVFiler#$storageName^$vfilerName\n";
            }
            else
            {
                # Skip this line as current line of no use.
            }
        }

        close (CONF_DUMP);
    }

EXIT:

    %volToQuotaStatus = ();
    @volList = ();

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Aggregate Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processAggregateConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This hashmap is used for storing the mapping of aggregate to its total capacity.
    my %aggrToTotalCap = ();

    # This hashmap is used for storing the mapping of aggregate to its used capacity.
    my %aggrToUsedCap = ();

    # This hashmap is used for storing the mapping of aggregate to its available capacity.
    my %aggrToAvailCap = ();

    # This hashmap is used for storing the mapping of aggregate to its total disk count.
    my %aggrToDiskCount= ();

    # This stores the name of Aggregate Resource.
    my $aggregate = "";

    # This store the total number of disks associated with the Aggregate.
    my $diskCount = 0;

    my $firstIteration = 0;

    print "    Collecting aggregate resource configuration data...";

    # Populate the Volume Capacity map.
    $retVal = populateVolumeCapMap();

    # Construct the complete name of NetApp Aggregate raw output file where Aggregate related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappAggregateCapacity.dump";

    # This variable is used to store the command to get the NetApp raw "Aggregate" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." AggregateCapacity $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript AggregateCapacity $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Aggregate capacity" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Aggregate capacity" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Aggregate capacity data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappAggregateCapacity.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Aggregate Capacity" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Aggregate capacity data as command not found.");
            last;
        }

        # If following condition is true then it is end of the "Aggregate Capacity" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Aggregate Capacity data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Aggregate(\s*)'(.+)'(\s*)$/)
        {
            $aggregate = $3;
        }
        elsif (/^(\s*)Total space(\s+)(\d+)(\w*)(\s+)(\d+)(\w*)(\s+)(\d+)(\w*)(\s*)$/)
        {
            $aggrToTotalCap{$aggregate} = covertCapToBytes($3, $4) + covertCapToBytes($9, $10);
            $aggrToUsedCap{$aggregate} = covertCapToBytes($3, $4);
            $aggrToAvailCap{$aggregate} = covertCapToBytes($9, $10);

            $aggregate = "";
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);

    # Find number of disks associated with each Aggregate.
    $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappAggregateDiskCount.dump";

    # This variable is used to store the command to get the NetApp raw "Aggregate Disk" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." AggregateDiskCount $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript AggregateDiskCount $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Aggregate Disk" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Aggregate Disk" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Aggregate Disk data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Aggregate Disk" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Aggregate Disk data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the "Aggregate Disk" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Aggregate disk data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Aggregate(\s*)(\w+)(\s+)\((.+)\)(\s*)$/)
        {
            if (0 == $firstIteration)
            {
                $aggregate = $3;
                $firstIteration = 1;
            }
            else
            {
                $aggrToDiskCount{$aggregate} = $diskCount;

                $aggregate = $3;
                $diskCount = 0;
            }
        }
        elsif (/^(\s*)(\w+)(\s+)(.+)(\d+)\/(\d+)(\s*)(\d+)\/(\d+)(\s*)$/)
        {
            if (($2 ne "spare") && ($2 ne "partner"))
            {
                $diskCount++;
            }
        }
    }

    # It is used to add the entry of last Aggregate.
    $aggrToDiskCount{$aggregate} = $diskCount;

    close (CONF_DUMP);

    # Iterate through each Aggregate to get its related information.
    while ((my $aggrName, my $diskCount) = each(%aggrToDiskCount))
    {
        # This stores the total capacity of the given aggregate.
        my $totalCap = "";

        # This stores the used capacity of the given aggregate.
        my $usedCapacity = "";

        # This stores the free capacity of the given aggregate.
        my $availCapacity = "";

        if (exists $aggrToTotalCap{$aggrName})
        {
            $totalCap = $aggrToTotalCap{$aggrName};
        }
        if (exists $aggrToUsedCap{$aggrName})
        {
            $usedCapacity = $aggrToUsedCap{$aggrName};
        }
        if (exists $aggrToAvailCap{$aggrName})
        {
            $availCapacity = $aggrToAvailCap{$aggrName};
        }

        # If we have aggregate but we don't get its capacity then it implies that it is a "trad" Volume which is tightly coupled with Aggregate. So
        # we can use Volume Capacity as Aggregate Capacity.
        if (($totalCap eq "" ) && ($usedCapacity eq "" ) && ($availCapacity eq "" ))
        {
            if (exists $volToTotalCap{$aggrName})
            {
                $totalCap = $volToTotalCap{$aggrName};
            }
            if (exists $volToUsedCap{$aggrName})
            {
                $usedCapacity = $volToUsedCap{$aggrName};
            }
            if (exists $volToAvailCap{$aggrName})
            {
                $availCapacity = $volToAvailCap{$aggrName};
            }
        }

        $confDataStart = 0;

        # This stores the total number of Plexes associated with the given Aggregate.
        my $plexCount = 0;

        # This store the total number of Volumes associated with the given Aggregate.
        my $volumeCount = 0;

        # Volume information can be in several consecutive lines. This variable keeps track of it.
        my $nextLineVolCount = 0;

        $rawConfFile = $netappCliOutputPath."/netappAggregate_".$aggrName."_Conf.dump";

        # This variable is used to store the command to get the NetApp raw Aggregate data.
        $cmd = $netappRunTimeLocation."/".$netappExpectScript." Aggregate $netappIpAddress $netappUserName $netappPassword $aggrName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Aggregate $netappIpAddress $netappUserName <password> $aggrName> $rawConfFile].");

        # Run the command to get the NetApp raw data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw Aggregate data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Aggregate data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

        while (<CONF_DUMP>)
        {
            # Remove the new line character.
            chomp;

            # If following condition is true then "Aggregate" data will start from the next line.
            if ($_ =~ /^Output start$/)
            {
                $confDataStart = 1;

                # Skip this line as it doesn't contain any useful data.
                next;
            }

            # If the command is not supported then exit from the function.
            if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
            {
                logMsg("Error: Failed to collect the NetApp raw Aggregate data as command not found.");

                $retVal = 1;
                goto EXIT;
            }

            # If following condition is true then it is end of the "Aggregate" data.
            if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
            {
                last;
            }

            # If we haven't reached at the beginning of Aggregate data then skip the current line.
            if (1 != $confDataStart)
            {
                next;
            }

            if (/^(\s*)(\w+)(\s+)(\w+)(\s+)(\w+),(\s+)(\w+)(\s+)(.+)=(.+)(\s*)$/)
            {
                print $CONF_HANDLE "R:naAggregate#$storageName^$2\n";
                print $CONF_HANDLE "a:name=$storageName^$2\n";
                print $CONF_HANDLE "a:type=$8\n";
                print $CONF_HANDLE "a:sizeTotal=$totalCap\n";
                print $CONF_HANDLE "a:sizeUsed=$usedCapacity\n";
                print $CONF_HANDLE "a:sizeAvailable=$availCapacity\n";
                print $CONF_HANDLE "a:raidStatus=$6\n";
                print $CONF_HANDLE "a:state=$4\n";
            }
            elsif (/^(\s*)(\d+)-(\w*)(\s*)(.+)raidsize=(\d+),(\s*)$/)
            {
                $aggrToRaidSize{$aggrName} = $6;
                print $CONF_HANDLE "a:raidSize=$6\n";
                print $CONF_HANDLE "a:blockType=$2_$3\n";
            }
            elsif (/^(\s*)(.*)raidsize=(\d+)(.*)(\s*)$/)
            {
                $aggrToRaidSize{$aggrName} = $3;
                print $CONF_HANDLE "a:raidSize=$3\n";
            }
            elsif (/^(\s*)Volumes:(\s*)<(.+)>(\s*)$/)
            {
                # Skip this line as no volume information is there. It is the case with trad Aggregate.
            }
            elsif (/^(\s*)Volumes:(\s*)(.+)(,|\w)(\s*)$/)
            {
                my $volList = $3.$4;
                my $lastChar = $4;

                # It counts the number of commas.
                my @matches = $volList =~ /,/g;
                $volumeCount = @matches;

                # If the next line to this line also contains volume information.
                if ($lastChar eq  ",")
                {
                    $nextLineVolCount = 1;
                }
                else
                {
                    # As number of Volumes will be one more than number of commas.
                    $volumeCount++;
                }
            }
            elsif (/^(\s*)Plex(.+):(\s*)(.+)(\s*)$/)
            {
                $plexCount++;
            }
            elsif ((/^(\s*)(.*)(,|\w)(\s*)$/) && (1 == $nextLineVolCount))
            {
                my $volList = $2.$3;
                my $lastChar = $3;

                my @matches = $volList =~ /,/g;

                # @matches gives the count of number of commas in string.
                $volumeCount = $volumeCount + @matches;

                # If the next line to this does not contains volume information.
                if ($lastChar ne  ",")
                {
                    $nextLineVolCount = 0;
                    $volumeCount ++;
                }
            }
        }

        close (CONF_DUMP);

        print $CONF_HANDLE "a:volumeCount=$volumeCount\n";
        print $CONF_HANDLE "a:plexCount=$plexCount\n";
        print $CONF_HANDLE "a:diskCount=$diskCount\n";
        print $CONF_HANDLE "r:naSystem#$storageName\n";
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Quota Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processQuotaConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Quota" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    print "    Collecting quota resource configuration data...";

    # Construct the complete name of NetApp Qtree raw output file where qtree related information will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappQtreeInfo.dump";

    # This variable is used to store the command to get the NetApp raw "Qtree" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." Qtree $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Qtree $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Qtree" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Qtree" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Qtree data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappQtreeInfo.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Qtree" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Qtree data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Qtree data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Qtree data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Volume(\s+)Tree(\s+)Style(\s+)Oplocks(\s+)Status(\s*)$/)
        {
            # skip this line as it is of no use.
        }
        elsif (/^(\s*)(\w+)(\s+)(.+)(\s+)(\w+)(\s+)(\w+)(\s+)(\w+)(\s*)$/)
        {
            my $qtree = $4;
            my $volName = $2;

            # Remove trailing white-spaces from the qtree name.
            $qtree =~ s/\s+$//;

            if ("" ne $qtree)
            {
                my $qtreeName = "naQtree#".$storageName."^".$volName."-".$qtree;
                if (exists $volToQtree{$volName})
                {
                    $volToQtree{$volName} = $volToQtree{$volName}.",".$qtreeName;
                }
                else
                {
                    $volToQtree{$volName} = $qtreeName;
                }
            }
        }
    }

    close (CONF_DUMP);

    if (0 == $foundFiler)
    {
        # Construct the complete name of NetApp Quota raw output file where Quota related information, will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappQuota_vfiler0_Info.dump";

        # This variable is used to store the command to get the NetApp raw "Quota" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." QuotaWithoutFiler $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript QuotaWithoutFiler $netappIpAddress $netappUserName <password>> $rawConfFile].");

        # Run the command to get the NetApp raw "Quota" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Quota" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Quota data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = processQuotaDumpFile($rawConfFile, "vfiler0");
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processQuotaDumpFile(0 failed.");
            goto EXIT;
        }
    }
    else
    {
        # Loop through each filer name.
        foreach my $vfilerName (@filerList)
        {
            # Construct the complete name of NetApp Quota raw output file where Quota related information, will get dumped.
            $rawConfFile = $netappCliOutputPath."/netappQuota_$vfilerName"."_Info.dump";

            # This variable is used to store the command to get the NetApp raw "Quota" data.
            my $cmd = $netappRunTimeLocation."/".$netappExpectScript." Quota $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
            logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Quota $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

            # Run the command to get the NetApp raw "Quota" data.
            $exitCode = executeSystemCmd($cmd);
            if ($ERROR_SUCCESS != $exitCode)
            {
                # If there is some problem is collecting the NetApp raw "Quota" data then it is an error.
                logMsg("Error: Failed to collect the NetApp raw Quota data.");

                $retVal = $exitCode;
                goto EXIT;
            }

            $retVal = processQuotaDumpFile($rawConfFile, $vfilerName);
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to put the processed Quota data in the final MARS Configuration file.
#
# @param :
#   $_[0] - Raw Conf file name.
#   $_[1] - vFiler name.
#
# @affected global variables :
#   None
#
# @return :
#   Nothing
sub processQuotaDumpFile
{
    # Get the raw Quota Data file name.
    $rawConfFile = $_[0];

    my $retVal = 0;

    # Get the vFiler name.
    my $vfilerName = $_[1];

    my $vfilerFileCount = 0;

    # It is used to indicate the beginning of NetApp Quota Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappQuotaInfo.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # This variable holds qtree name associated with the given Quota.
        my $qtree = "";

        # This variable holds all qtree associated with the specified Quota.
        my $qtreeRelation = "";

        # This variable holds qtree name prepended with volume name in order to make it unique.
        my $qtreeName = "";

        # This variable holds Qtree "Files Used" value.
        my $qtreeFileUsed = 0;

        # This variable holds Qtree "Disk Used" value.
        my $qtreeDiskUsed = 0;

        # If following condition is true then "Quota" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Quota data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Quota data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Quota data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        # If the Id is "*" then proceed accordingly.
        if (/^(\s*)(\w+)(\s+)\*(\s+)(\w+)(\s+)(\w*|-)(\s+)(\d*)(\s+)(-|\d*)(\s+)(\d*)(\s+)(-|\d*)(\s*)(.+)(\s*)$/)
        {
            # In case Qtree value is empty then we consider that Quota is imposed on all Qtrees of the related Volume.
            if ($7 eq "-")
            {
                $qtree = "alltree";
                if (exists $volToQtree{$5})
                {
                    $qtreeRelation = $volToQtree{$5};
                }
            }
            else
            {
                $qtree = $7;
                $qtreeRelation = "naQtree#$storageName^$5-$qtree";

                $qtreeName = $5."-".$qtree;
                $qtreeFileUsed = $13;
                $qtreeDiskUsed = $9;

                # Update fileUsed if the given qtree is already present in the map.
                if (exists $qtreeAndNumberOfFile{$qtreeName})
                {
                    $qtreeFileUsed = $qtreeFileUsed + $qtreeAndNumberOfFile{$qtreeName};
                }

                # Update diskUsed if the given qtree is already present in the map.
                if (exists $qtreeAndUsedDiskSize{$qtreeName})
                {
                    $qtreeDiskUsed = $qtreeDiskUsed + $qtreeAndUsedDiskSize{$qtreeName};
                }

                $qtreeAndNumberOfFile{$qtreeName} = $qtreeFileUsed;
                $qtreeAndUsedDiskSize{$qtreeName} = $qtreeDiskUsed;
            }

            # Dump the Quota information in the MARS Conf file.
            if ($2 ne "tree")
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$5-$2-$qtree-all$2\n";
                print $CONF_HANDLE "a:name=$storageName^$5-$2-$qtree-all$2\n";
                print $CONF_HANDLE "a:".$2."Id=all$2\n";
            }
            else
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$5-$2-$qtree\n";
                print $CONF_HANDLE "a:name=$storageName^$5-$2-$qtree\n";
            }

            print $CONF_HANDLE "a:type=$2\n";
            print $CONF_HANDLE "a:fileLimit=$15\n";
            print $CONF_HANDLE "a:fileUsed=$13\n";
            print $CONF_HANDLE "a:diskLimit=$11\n";
            print $CONF_HANDLE "a:diskUsed=$9\n";
            print $CONF_HANDLE "a:qtree=$qtree\n";
            print $CONF_HANDLE "r:naVolume#$storageName^$5\n";
            print $CONF_HANDLE "r:$qtreeRelation\n";

            $vfilerFileCount = $vfilerFileCount + $13;
        }
        # If the Id begins with "\" then proceed accordingly.
        elsif (/^(\s*)(\w+)(\s+)\\(\w*)(\s+)(\w+)(\s+)(-|\w+)(\s+)(\d+)(\s+)(-|\d+)(\s+)(\d+)(\s+)(-|\d+)(\s*)(.+)(\s*)$/)
        {
            # In case Qtree value is empty then we consider that Quota is imposed on all Qtrees of the related Volume.
            if ($8 eq "-")
            {
                $qtree = "alltree";

                if (exists $volToQtree{$6})
                {
                    $qtreeRelation = $volToQtree{$6};
                }
            }
            else
            {
                $qtree = $8;
                $qtreeRelation = "naQtree#$storageName^$6-$qtree";

                $qtreeName = $6."-".$qtree;
                $qtreeFileUsed = $14;
                $qtreeDiskUsed = $10;

                # Update fileUsed if the given qtree is already present in the map.
                if (exists $qtreeAndNumberOfFile{$qtreeName})
                {
                    $qtreeFileUsed = $qtreeFileUsed + $qtreeAndNumberOfFile{$qtreeName};
                }

                # Update diskUsed if the given qtree is already present in the map.
                if (exists $qtreeAndUsedDiskSize{$qtreeName})
                {
                    $qtreeDiskUsed = $qtreeDiskUsed + $qtreeAndUsedDiskSize{$qtreeName};
                }

                $qtreeAndNumberOfFile{$qtreeName} = $qtreeFileUsed;
                $qtreeAndUsedDiskSize{$qtreeName} = $qtreeDiskUsed;
            }

            # Dump the Quota information in the MARS Conf file.
            if ($2 ne "tree")
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$6-$2-$qtree-\\$4\n";
                print $CONF_HANDLE "a:name=$storageName^$6-$2-$qtree-\\$4\n";
                print $CONF_HANDLE "a:".$2."Id=\\$4\n";
            }
            else
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$6-$2-$qtree\n";
                print $CONF_HANDLE "a:name=$storageName^$6-$2-$qtree\n";
            }

            print $CONF_HANDLE "a:type=$2\n";
            print $CONF_HANDLE "a:fileLimit=$16\n";
            print $CONF_HANDLE "a:fileUsed=$14\n";
            print $CONF_HANDLE "a:diskLimit=$12\n";
            print $CONF_HANDLE "a:diskUsed=$10\n";
            print $CONF_HANDLE "a:qtree=$qtree\n";
            print $CONF_HANDLE "r:naVolume#$storageName^$6\n";
            print $CONF_HANDLE "r:$qtreeRelation\n";

            $vfilerFileCount = $vfilerFileCount + $14;
        }
        elsif (/^(\s*)(\w+)(\s+)(\w*)(\s+)(\w+)(\s+)(-|\w+)(\s+)(\d+)(\s+)(-|\d+)(\s+)(\d+)(\s+)(-|\d+)(\s*)(.+)(\s*)$/)
        {
            # In case Qtree value is empty then we consider that Quota is imposed on all Qtrees of the related Volume.
            if ($8 eq "-")
            {
                $qtree = "alltree";
                $qtreeRelation = $volToQtree{$6};
            }
            else
            {
                $qtree = $8;
                $qtreeRelation = "naQtree#$storageName^$6-$qtree";

                $qtreeName = $6."-".$qtree;
                $qtreeFileUsed = $14;
                $qtreeDiskUsed = $10;

                # Update fileUsed if the given qtree is already present in the map.
                if (exists $qtreeAndNumberOfFile{$qtreeName})
                {
                    $qtreeFileUsed = $qtreeFileUsed + $qtreeAndNumberOfFile{$qtreeName};
                }

                # Update diskUsed if the given qtree is already present in the map.
                if (exists $qtreeAndUsedDiskSize{$qtreeName})
                {
                    $qtreeDiskUsed = $qtreeDiskUsed + $qtreeAndUsedDiskSize{$qtreeName};
                }

                $qtreeAndNumberOfFile{$qtreeName} = $qtreeFileUsed;
                $qtreeAndUsedDiskSize{$qtreeName} = $qtreeDiskUsed;
            }

            # Dump the Quota information in the MARS Conf file.
            if ($2 ne "tree")
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$6-$2-$qtree-$4\n";
                print $CONF_HANDLE "a:name=$storageName^$6-$2-$qtree-$4\n";
                print $CONF_HANDLE "a:".$2."Id=$4\n";
            }
            else
            {
                print $CONF_HANDLE "R:naQuota#$storageName^$6-$2-$qtree\n";
                print $CONF_HANDLE "a:name=$storageName^$6-$2-$qtree\n";
            }

            print $CONF_HANDLE "a:type=$2\n";
            print $CONF_HANDLE "a:fileLimit=$16\n";
            print $CONF_HANDLE "a:fileUsed=$14\n";
            print $CONF_HANDLE "a:diskLimit=$12\n";
            print $CONF_HANDLE "a:diskUsed=$10\n";
            print $CONF_HANDLE "a:qtree=$qtree\n";
            print $CONF_HANDLE "r:naVolume#$storageName^$6\n";
            print $CONF_HANDLE "r:$qtreeRelation\n";

            $vfilerFileCount = $vfilerFileCount + $14;
        }
        else
        {
            # Skip this line as it doesn't contain any useful data.
            next;
        }
    }

    # Populate "qtreeAndAverageFileSize" Map.
    while (my ($qtree, $fileUsed)=each %qtreeAndNumberOfFile)
    {
        if (exists $qtreeAndUsedDiskSize{$qtree})
        {
            if (0 < $fileUsed)
            {
                $qtreeAndAverageFileSize{$qtree} = int(($qtreeAndUsedDiskSize{$qtree} / $fileUsed) + 0.5);
            }
        }
    }

    # Update "vfilerAndNumberOfFile" Map.
    $vfilerAndNumberOfFile{$vfilerName} = $vfilerFileCount;

EXIT:

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Qtree Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processQtreeConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Qtree" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # It is used to store the total file count corresponding to the given Qtree.
    my $fileCount = 0;

    # It is used to store the total disk count corresponding to the given Qtree.
    my $diskUsed = 0;

    # It is used to store the average file size corresponding to the given Qtree.
    my $avgFileSize = 0;

    print "    Collecting Qtree resource configuration data...";

    # Construct the complete name of NetApp Qtree raw output file where qtree related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappQtreeInfo.dump";

    # This variable is used to store the command to get the NetApp raw "Qtree" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." Qtree $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Qtree $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Qtree" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Qtree" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Qtree data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappQtreeInfo.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Qtree" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Qtree data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Qtree data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Qtree data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Volume(\s+)Tree(\s+)Style(\s+)Oplocks(\s+)Status(\s*)$/)
        {
            # skip this line as it is of no use.
        }
        elsif (/^(\s*)(\w+)(\s+)(.+)(\s+)(\w+)(\s+)(\w+)(\s+)(\w+)(\s*)$/)
        {
            my $volume = $2;
            my $qtreeName = $4;
            my $status = $10;
            my $security = $6;
            my $opLocks = $8;

            # Remove trailing spaces from the $qtree variable.
            $qtreeName =~ s/\s+$//;

            if ("" ne $qtreeName)
            {
                my $qtree = $volume."-".$qtreeName;

                if (exists $qtreeAndNumberOfFile{$qtree})
                {
                    $fileCount = $qtreeAndNumberOfFile{$qtree};
                }

                if (exists $qtreeAndUsedDiskSize{$qtree})
                {
                    $diskUsed = $qtreeAndUsedDiskSize{$qtree};
                }

                if (exists $qtreeAndAverageFileSize{$qtree})
                {
                    $avgFileSize = $qtreeAndAverageFileSize{$qtree};
                }

                print $CONF_HANDLE "R:naQtree#$storageName^$qtree\n";
                print $CONF_HANDLE "a:name=$storageName^$qtree\n";
                print $CONF_HANDLE "a:status=$status\n";
                print $CONF_HANDLE "a:securityStyle=$security\n";
                print $CONF_HANDLE "a:opLocks=$opLocks\n";
                print $CONF_HANDLE "a:fileCount=$fileCount\n";
                print $CONF_HANDLE "a:diskUsed=$diskUsed\n";
                print $CONF_HANDLE "a:avgFileSize=$avgFileSize\n";
                print $CONF_HANDLE "r:naVolume#$storageName^$volume\n";
            }
        }
        else
        {
           # skip this line as it is of no use.
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Vfiler Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processVfilerConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Vfiler" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This stores the IP Address of the given vfiler.
    my $ipAddress = "";

    # This variable keeps track if there are more than two IP Address associated with the given vfiler.
    my $parseIpAddress = 0;

    # This variable keeps track of total number of files corresponding to the given vfiler.
    my $fileCount = 0;

    # This variable stores comma separated vstore path.
    my $vStorePath = "";

    # This variable stores comma separated value either "TRUE" or "FALSE" depending on whether the given path is etc path or not.
    my $vStoreIsEtc = "";

    print "    Collecting vFiler resource configuration data...";

    # Construct the complete name of NetApp vfiler raw output file where vfiler related information will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappVfilerConf.dump";

    # This variable is used to store the command to get the NetApp raw "vfiler" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." VFiler $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VFiler $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "vfiler" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "vfiler" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw vfiler data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "NetAppVfilerConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "vfiler" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw vfiler data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the vfiler data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of vFiler data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (($parseIpAddress == 0) && (/^(\s*)IP address:(\s+)(\d+).(\d+).(\d+).(\d+)(\s+)(.+)(\s*)$/))
        {
            $ipAddress = "$3.$4.$5.$6";
            $parseIpAddress = 1;
        }
        elsif (/^(\s*)IP address:(\s+)(\d+).(\d+).(\d+).(\d+)(\s+)(.+)(\s*)$/)
        {
            $ipAddress = $ipAddress.",$3.$4.$5.$6";
        }
        elsif (/^(\s*)(.+)(\s+)(\w+)(\s*)$/)
        {
            my $vfilerName = $2;
            $vfilerName =~ s/\s+$//;

            print $CONF_HANDLE "R:naVFiler#$storageName^$vfilerName\n";
            print $CONF_HANDLE "a:name=$storageName^$vfilerName\n";

            if ($4 eq "running")
            {
                print $CONF_HANDLE "a:vStoreStatus=online\n";
            }
            elsif ($4 eq "stopped")
            {
                print $CONF_HANDLE "a:vStoreStatus=offline\n";
            }

            $parseIpAddress = 0;
            $ipAddress = "";

            if (exists $vfilerAndNumberOfFile{$vfilerName})
            {
                $fileCount = $vfilerAndNumberOfFile{$vfilerName};
            }

            # Collect NetBios information.
            my $dataStart = 0;

            # Construct the complete name of NetApp NetBios Information raw output file where NetBios related information, will get dumped.
            $rawConfFile = $netappCliOutputPath."/netappNetBios_$vfilerName.dump";

            # This variable is used to store the command to get the NetApp raw "NetBios" data.
            my $cmd = $netappRunTimeLocation."/".$netappExpectScript." NetBios $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
            logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript NetBios $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

            # Run the command to get the NetApp raw "NetBios" data.
            $exitCode = executeSystemCmd($cmd);
            if ($ERROR_SUCCESS != $exitCode)
            {
                # If there is some problem is collecting the NetApp raw "NetBios" data then it is an error.
                logMsg("Error: Failed to collect the NetApp raw NetBios data.");

                $retVal = $exitCode;
                goto EXIT;
            }

            open(CONF_NETBIOS_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

            # Loop through the content of "netappNetBiosConf.dump" file.
            while (<CONF_NETBIOS_DUMP>)
            {
                # Remove the new line character.
                chomp;

                # If following condition is true then "NetBios" data will start from the next line.
                if ($_ =~ /^Output start$/)
                {
                    $dataStart = 1;

                    # Skip this line as it doesn't contain any useful data.
                    next;
                }

                # If the command is not supported then exit from the loop.
                if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
                {
                    logMsg("Error: Failed to collect the NetApp raw NetBios data as command not found.");
                    last;
                }

                # If following condition is true then it is end of the NetBios data.
                if ((1 == $dataStart) && ($_ =~ /^Output end$/))
                {
                    last;
                }

                # If we haven't reached at the beginning of NetBios data then skip the current line.
                if (1 != $dataStart)
                {
                    next;
                }

                if (/^(\s*)(.+)'(.+)'(\s*)(.+)'(.+)'(\s*)$/)
                {
                   print $CONF_HANDLE "a:netbiosServerName=$3\n";
                   print $CONF_HANDLE "a:netbiosDomainName=$6\n";
                }
                else
                {
                    # Current line is of no use so ignore it.
                }
            }

            close (CONF_NETBIOS_DUMP);

            # Collect AdminHost information.
            $dataStart = 0;

            # Construct the complete name of NetApp Admin Host Information raw output file where NetApp Admin Host related information, will get dumped.
            $rawConfFile = $netappCliOutputPath."/NetAppAdminHostConf.dump";

            # This variable is used to store the command to get the NetApp raw "Admin Host" data.
            $cmd = $netappRunTimeLocation."/".$netappExpectScript." AdminHost $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
            logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript AdminHost $netappIpAddress $netappUserName <password>> $rawConfFile].");

            # Run the command to get the NetApp raw "Admin Host" data.
            $exitCode = executeSystemCmd($cmd);
            if ($ERROR_SUCCESS != $exitCode)
            {
                # If there is some problem is collecting the NetApp raw "Admin Host" data then it is an error.
                logMsg("Error: Failed to collect the NetApp raw Admin Host data.");

                $retVal = $exitCode;
                goto EXIT;
            }

            open(CONF_ADMINHOST_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

            # Loop through the content of "NetAppAdminHostConf.dump" file.
            while (<CONF_ADMINHOST_DUMP>)
            {
                # Remove the new line character.
                chomp;

                # If following condition is true then "Admin Host" data will start from the next line.
                if ($_ =~ /^Output start$/)
                {
                    $dataStart = 1;

                    # Skip this line as it doesn't contain any useful data.
                    next;
                }

                # If the command is not supported then exit from the loop.
                if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
                {
                    logMsg("Error: Failed to collect the NetApp raw Admin Host data as command not found.");
                    last;
                }

                # If following condition is true then it is end of the Admin Host data.
                if ((1 == $dataStart) && ($_ =~ /^Output end$/))
                {
                    last;
                }

                # If we haven't reached at the beginning of Admin Host data then skip the current line.
                if (1 != $dataStart)
                {
                    next;
                }

                if (/^(\s*)admin.hosts(\s*)(.+)(\s*)$/)
                {
                   print $CONF_HANDLE "a:adminHost=$3\n";
                }
                else
                {
                    # Current line is of no use so ignore it.
                }
            }

            close (CONF_ADMINHOST_DUMP);

            $vStorePath = "";
            $vStoreIsEtc = "";
        }
        elsif (/^(\s*)ipspace:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:ipSpace=$3\n";
        }
        elsif (($vStorePath eq "") && (/^(\s*)Path:(\s+)(.+)(\s+)\[\/etc\](\s*)$/))
        {
            $vStorePath = $3;
            $vStorePath =~ s/[\n\r]//g;

            $vStoreIsEtc = "TRUE";
        }
        elsif (/^(\s*)Path:(\s+)(.+)(\s+)\[\/etc\](\s*)$/)
        {
            $vStorePath = $vStorePath.",".$3;
            $vStorePath =~ s/[\n\r]//g;

            $vStoreIsEtc = $vStoreIsEtc.",TRUE";
        }
        elsif (($vStorePath eq "") && (/^(\s*)Path:(\s+)(.+)(\s*)$/))
        {
            $vStorePath = $3;
            $vStorePath =~ s/[\n\r]//g;

            $vStoreIsEtc = "FALSE";
        }
        elsif (/^(\s*)Path:(\s+)(.+)(\s*)$/)
        {
            $vStorePath = $vStorePath.",".$3;
            $vStorePath =~ s/[\n\r]//g;

            $vStoreIsEtc = $vStoreIsEtc.",FALSE";
        }
        elsif (/^(\s*)UUID:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:ipAddress=$ipAddress\n";
            print $CONF_HANDLE "a:vStorePath=$vStorePath\n";
            print $CONF_HANDLE "a:vStoreIsEtc=$vStoreIsEtc\n";
            print $CONF_HANDLE "a:fileCount=$fileCount\n";
            print $CONF_HANDLE "r:naSystem#$storageName\n"
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of LUN Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processLunConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Lun Mapping" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This hashmap stores "lun path" as key and its corresponding "protocol type" as value.
    my %lunToProtocolType = ();

    # This hashmap stores "lun path" as key and its corresponding "Initiator Groups" as value.
    my %lunToInitiatorGroup = ();

    # This variable stores the path of Lun.
    my $lunPath = "";

    # It stores the size of lun in bytes.
    my $size = 0;

    # This variable stores the path of lun.
    my $path = "";

    # It stores the online status of Lun.
    my $onlineStatus = "true";

    print "    Collecting LUN resource configuration data...";

    # Construct the complete name of NetApp "Lun Mapping" raw output file where Lun Mapping related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappLunMappingConf.dump";

    # This variable is used to store the command to get the NetApp raw "Lun Mapping" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." LunMapping $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript LunMapping $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Lun Mapping" data.
    $exitCode = executeSystemCmd("$cmd");
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Lun Mapping" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Lun Mapping data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappLunMappingConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        my $group = "";

        # If following condition is true then "Lun Mapping" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Lun Mapping data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Qtree data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of LUN data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)\/vol\/(.+)\/(\w+)(\s+)(.+)(\s+)(\d+)(\s+)(\w+)(\s*)$/)
        {
            $path = "/vol/".$2."/".$3;
            $lunToProtocolType{$path} = $9;

            $group = $5;

            # Remove trailing spaces from the $group variable.
            $group =~ s/\s+$//;

            $lunToInitiatorGroup{$path} = $group;
        }
        # Sometimes a single lun associated information can be spread across multiple lines so handling that case.
        elsif (/^(\s*)(.+)(\s+)(\d+)(\s+)(\w+)(\s*)$/)
        {
            $group = $2;

            # Remove trailing spaces from the $group variable.
            $group =~ s/\s+$//;

            $lunToInitiatorGroup{$path} = $lunToInitiatorGroup{$path}.",".$group;
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);

    $confDataStart = 0;

    # In some cases, we are not able to find "Occupied size" information in the LUN output. So we don't have a specific way to know when the data for
    # a LUN ends. So we are also using "Multiprotocol Type" information as end marker if it is not followed by "Occupied size".
    my $foundAlternateEndMarker = 0;

    $rawConfFile = $netappCliOutputPath."/netappLunConf.dump";

    # This variable is used to store the command to get the NetApp raw "Lun" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." Lun $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Lun $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Lun" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Lun" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Lun data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappLunConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Lun" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Lun data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Qtree data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of LUN data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)\/vol\/(.+)\/(\w+)(\s+)(.+)(\s+)\((.+)\)(\s+)\((.+)\)(\s*)$/)
        {
            # If we didn't find "Occupied size" information for the previous LUN resource, add remaining information about that resource now.
            if (1 == $foundAlternateEndMarker)
            {
                print $CONF_HANDLE "a:usedSize=\n";

                # Add references to all initiator groups which are associated with current LUN.
                my $initiatorGroupList = $lunToInitiatorGroup{$lunPath};

                my @arrayInitiatorGroup = split(/,/, $initiatorGroupList);
                foreach (@arrayInitiatorGroup)
                {
                    print $CONF_HANDLE "r:naInitiatorGroup#$storageName^$_\n";
                }

                my @volName = $lunPath =~ /\/(\w*)/g;
                print $CONF_HANDLE "r:naVolume#$storageName^$volName[1]\n";

                # If LUN is not associated with any initiator group then only add this relation.
                if (0 == @arrayInitiatorGroup)
                {
                    print $CONF_HANDLE "r:naSystem#$storageName\n";
                }

                $foundAlternateEndMarker = 0;
            }

            $lunPath = "/vol/".$2."/".$3;
            $size = $7;

            if (index($9, "online") == -1)
            {
                $onlineStatus = "false";
            }
        }
        elsif (/^(\s*)Serial#:(\s+)(.+)(\s*)$/)
        {
            my $name = $3;

            # Remove trailing spaces from name.
            $name =~ s/\s+$//;

            print $CONF_HANDLE "R:naLun#$name\n";
            print $CONF_HANDLE "O:naLun#$storageName^$lunPath-$name\n";
            print $CONF_HANDLE "a:name=$storageName^$lunPath\n";
            print $CONF_HANDLE "a:path=$lunPath\n";
            print $CONF_HANDLE "a:size=$size\n";
            print $CONF_HANDLE "a:serialNumber=$name\n";
            print $CONF_HANDLE "a:onlineStatus=$onlineStatus\n";

            if (exists $lunToProtocolType{$lunPath})
            {
                print $CONF_HANDLE "a:type=$lunToProtocolType{$lunPath}\n";
            }
        }
        elsif (/^(\s*)Multiprotocol Type:(\s+)(.+)$/)
        {
            my $protocolType = $3;

            # Remove trailing spaces from protocol type.
            $protocolType =~ s/\s+$//;

            print $CONF_HANDLE "a:protocolType=$protocolType\n";
            $foundAlternateEndMarker = 1;
        }
        elsif (/^(\s*)Occupied Size:(\s+)(.+)(\s+)\((\d+)\)(\s*)$/)
        {
            print $CONF_HANDLE "a:usedSize=$5\n";

            # Add references to all initiator groups which are associated with current LUN.
            my $initiatorGroupList = $lunToInitiatorGroup{$lunPath};

            my @arrayInitiatorGroup = split(/,/, $initiatorGroupList);
            foreach (@arrayInitiatorGroup)
            {
                print $CONF_HANDLE "r:naInitiatorGroup#$storageName^$_\n";
            }

            my @volName = $lunPath =~ /\/(\w*)/g;
            print $CONF_HANDLE "r:naVolume#$storageName^$volName[1]\n";

            # If LUN is not associated with any initiator group then only add this relation.
            if (0 == @arrayInitiatorGroup)
            {
                print $CONF_HANDLE "r:naSystem#$storageName\n";
            }

            $foundAlternateEndMarker = 0;
        }
    }

    # If we didn't find "Occupied size" information for the previous LUN resource, add remaining information about that resource now.
    if (1 == $foundAlternateEndMarker)
    {
        print $CONF_HANDLE "a:usedSize=\n";

        # Add references to all initiator groups which are associated with current LUN.
        my $initiatorGroupList = $lunToInitiatorGroup{$lunPath};

        my @arrayInitiatorGroup = split(/,/, $initiatorGroupList);
        foreach (@arrayInitiatorGroup)
        {
            print $CONF_HANDLE "r:naInitiatorGroup#$storageName^$_\n";
        }

        my @volName = $lunPath =~ /\/(\w*)/g;
        print $CONF_HANDLE "r:naVolume#$storageName^$volName[1]\n";

        # If LUN is not associated with any initiator group then only add this relation.
        if (0 == @arrayInitiatorGroup)
        {
            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }

        $foundAlternateEndMarker = 0;
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Nfs Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processNfsConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Nfs" command.
    my $exitCode = 0;

    print "    Collecting NFS share resource configuration data...";

    # If there is no vfiler license present on the Storage then process with default vfiler name.
    if (0 == $foundFiler)
    {
        # Construct the complete name of NetApp "Nfs" raw output file where Nfs related information will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappNfsShare_vfiler0_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Nfs" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." NfsShareWithoutFiler $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript NfsShareWithoutFiler $netappIpAddress $netappUserName <password>> $rawConfFile].");

        # Run the command to get the NetApp raw "Nfs" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Nfs" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Nfs data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = processNfsRawDumpFile($rawConfFile, "vfiler0");
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processNfsRawDumpFile() failed.");
        }

        goto EXIT;
    }

    # Loop through each filer name.
    foreach my $vfilerName (@filerList)
    {
        # Construct the complete name of NetApp "Nfs" raw output file where Nfs related information will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappNfsShare_".$vfilerName."_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Nfs" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." NfsShare $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript NfsShare $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

        # Run the command to get the NetApp raw "Nfs" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Nfs" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Nfs data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = processNfsRawDumpFile($rawConfFile, $vfilerName);
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processNfsRawDumpFile() failed.");
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to put the processed raw Nfs Share data in the final MARS Configuration file.
#
# @param :
#   $_[0] - Raw Conf file name.
#   $_[1] - vFiler name.
#
# @affected global variables :
#   None
#
# @return :
#   Nothing
sub processNfsRawDumpFile
{
    # Get the raw Nfs Data file name.
    $rawConfFile = $_[0];

    # Get the vFiler name.
    my $vfilerName = $_[1];

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    my $retVal = 0;

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappNfsShareConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Nfs" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Nfs data as command not found.");

            $retVal = 1;
            last;
        }

        # If following condition is true then it is end of the Nfs data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of NFS data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }
        if (/^(\s*)(.*)\/(.+)(\s+)-(.+)(\s*)$/)
        {
            # This variable keeps track whether any IP address is associated with the permission or it is applicable to all.
            my $permTracker = "";

            # This variable stores comma separated list of attributes related to NfsShare.
            my $nfsInfo = $5;

            # This variable stores the pathname corresponding to the given NfsShare.
            my $actualPathName = "";

            # This variable stores the "Read Write Access" Permission.
            my $readWriteAccess = "";

            # This variable stores the "Root Access" Permission.
            my $rootAccess = "";

            # This array stores the list of attributes related to NfsShare.
            my @attrlist = ();

            # This variable stores the "Read Only Access" Permission.
            my $readOnlyAccess = "";

            print $CONF_HANDLE "R:naNfsShare#$storageName^$2/$3\n";
            print $CONF_HANDLE "a:name=$storageName^$2/$3\n";

            if ($nfsInfo =~ /^(\s*)(.*)rw(,|=|\s+)(.*)(\s*)$/)
            {
                my $readWritePerm = $3.$4;
                $permTracker = $3;

                $readWritePerm =~ s/\s+$//;
                $permTracker =~ s/\s+$//;

                if (("" eq $permTracker) || ("," eq $permTracker))
                {
                    $readWriteAccess = "all";
                }
                elsif ($readWritePerm =~ /^(\s*)=(.+)(\s*)$/)
                {
                    @attrlist = split(/,/, $2);
                    $readWriteAccess = $attrlist[0];
                }
            }

            if ($nfsInfo =~ /^(\s*)(.*)ro(,|=|\s+)(.*)(\s*)$/)
            {
                my $readPerm = $3.$4;
                $permTracker = $3;

                $readPerm =~ s/\s+$//;
                $permTracker =~ s/\s+$//;

                if (("" eq $permTracker) || ("," eq $permTracker))
                {
                    $readOnlyAccess = "all";
                }
                elsif ($readPerm =~ /^(\s*)=(.+)(\s*)$/)
                {
                    @attrlist = split(/,/, $2);
                    $readOnlyAccess = $attrlist[0];
                }
            }

            if ($nfsInfo =~ /^(\s*)(.*)root=(.+)(\s*)$/)
            {
                @attrlist = split(/,/, $3);
                $rootAccess = $attrlist[0];
            }

            if ($nfsInfo =~ /^(\s*)(.*)actual=(.+)(\s*)$/)
            {
                @attrlist = split(/,/, $3);
                $actualPathName = $attrlist[0];
            }

            print $CONF_HANDLE "a:root=$rootAccess\n";
            print $CONF_HANDLE "a:readOnlyAccess=$readOnlyAccess\n";
            print $CONF_HANDLE "a:readWriteAccess=$readWriteAccess\n";
            print $CONF_HANDLE "a:actualPathName=$actualPathName\n";
            print $CONF_HANDLE "r:naVFiler#$storageName^$vfilerName\n";
        }
        else
        {
            # Current line is of no use so skip it.
        }
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of SnapMirror Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processSnapMirrorConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "SnapMirror" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This hashmap stores the SnapMirror Source as key and its corresponding schedule as value.
    my %snapSourceToSchedule = ();

    print "    Collecting SnapMirror resource configuration data...";

    # Construct the complete name of NetApp "SnapMirror Schedule" raw output file where SnapMirror related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappSnapMirrorSchedule.dump";

    # This variable is used to store the command to get the NetApp raw "SnapMirror Schedule" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapMirrorSchedule $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapMirrorSchedule $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "SnapMirror Schedule" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "SnapMirror Schedule" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw SnapMirror Schedule data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    # Collect the information about SnapMirror schedule.
    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSnapMirrorSchedule.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "SnapMirror Schedule" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw SnapMirror Schedule data as command not found.");
            last;
        }

        # If following condition is true then it is end of the SnapMirror Schedule data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of SnapMirror Schedule data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(.+):(.+)(\s+)(.+):(.+)(\s+)-(\s+)(.+)(\s*)$/)
        {
            my $snapMirrorSource = "$2:$3";
            my $schedule = $9;

            # Remove trailing whitespaces from the schedule.
            $schedule =~ s/\s+$//;

            $snapSourceToSchedule{$snapMirrorSource} = $schedule;
        }
    }

    close (CONF_DUMP);

    $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappSnapMirrorConf.dump";

    # This variable is used to store the command to get the NetApp raw "SnapMirror" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapMirror $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapMirror $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "SnapMirror" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "SnapMirror" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw SnapMirror data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSnapMirrorConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "SnapMirror" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw SnapMirror data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the SnapMirror data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of SnapMirror data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Source:(\s+)(.+)(\s*)$/)
        {
            my $snapMirrorSource = $3;

            # Remove white-space characters.
            $snapMirrorSource =~ s/\s+$//;

            print $CONF_HANDLE "R:naSnapMirror#$storageName^$snapMirrorSource\n";
            print $CONF_HANDLE "a:name=$storageName^$snapMirrorSource\n";
            print $CONF_HANDLE "a:sourceLocation=$snapMirrorSource\n";

            if (exists $snapSourceToSchedule{$snapMirrorSource})
            {
                print $CONF_HANDLE "a:schedule=$snapSourceToSchedule{$snapMirrorSource}\n";
            }
        }
        elsif (/^(\s*)Destination:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:destinationLocation=$3\n";
        }
        elsif (/^(\s*)Status:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:status=$3\n";
        }
        elsif (/^(\s*)State:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:state=$3\n";
        }
        elsif (/^(\s*)Lag:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:lagTime=$3\n";
        }
        elsif (/^(\s*)Mirror Timestamp:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:mirrorTimeStamp=$3\n";
        }
        elsif (/^(\s*)Base Snapshot:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:baseSnapshot=$3\n";
        }
        elsif (/^(\s*)Contents:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:contents=$3\n";
        }
        elsif (/^(\s*)Last Transfer Size:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:lastTransferSize=$3\n";
        }
        elsif (/^(\s*)Last Transfer Duration:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:lastTransferDuration=$3\n";
            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of SnapVault Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processSnapVaultConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "SnapVault" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This hashmap stores the SnapVault Source as key and its corresponding schedule as value.
    my %snapVaultToSchedule = ();

    # This hashmap stores the SnapVault Source as key and its corresponding retention as value.
    my %snapVaultToRetention = ();

    print "    Collecting SnapVault resource configuration data...";

    # Construct the complete name of NetApp "SnapVault Schedule" raw output file where SnapVault related information will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappSnapVaultSchedule.dump";

    # This variable is used to store the command to get the NetApp raw "SnapVault Schedule" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapVaultSchedule $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapVaultSchedule $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "SnapVault Schedule" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "SnapVault Schedule" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw SnapVault Schedule data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    # Collect SnapVault schedule information.
    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSnapVaultSchedule.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "SnapVault Schedule" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
           logMsg("Error: Failed to collect the NetApp raw SnapVault Schedule data as command not found.");
           last;
        }

        # If following condition is true then it is end of the SnapVault Schedule data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of SnapVault Schedule data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(\w+)(\s+)(\w+)(\s+)(\w+)(\s+)(.+)(\s*)$/)
        {
            my $snapVaultSource = $4;
            my $tempSchedule = $8;
            my $schedule = "";
            my $retention = "";

            # Remove trailing whitespaces from the $tempSchedule.
            $tempSchedule =~ s/\s+$//;

            # In some case we get extra information separated by space along with schedule, so extracting only schedule part out of it.
            my @schedulelist = split(/ /, $tempSchedule);
            $tempSchedule = $schedulelist[0];

            my @attrList = split('@', $tempSchedule);
            my $tempRetention = $attrList[0];
            my $stringToRemove = "$tempRetention\@";

            # Remove retention part from schedule.
            $tempSchedule =~ s/$stringToRemove//;

            if (exists $snapVaultToSchedule{$snapVaultSource})
            {
               $schedule = $snapVaultToSchedule{$snapVaultSource}.";".$tempSchedule;
               $retention = $snapVaultToRetention{$snapVaultSource}.";".$tempRetention;
            }
            else
            {
               $schedule = $tempSchedule;
               $retention = $tempRetention;
            }

            $snapVaultToSchedule{$snapVaultSource} = $schedule;
            $snapVaultToRetention{$snapVaultSource} = $retention;
        }
    }

    close (CONF_DUMP);

    $confDataStart = 0;

    # Collect SnapVault attributes other than schedule.
    $rawConfFile = $netappCliOutputPath."/netappSnapVaultConf.dump";

    # This variable is used to store the command to get the NetApp raw "SnapVault" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapVault $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapVault $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "SnapVault" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "SnapVault" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw SnapVault data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappSnapVaultConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "SnapVault" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw SnapVault data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the SnapVault data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of SnapVault data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Source:(\s+)(.+)(\s*)$/)
        {
            my $source = $3;

            # Remove trailing whitespaces from the source.
            $source =~ s/\s+$//;

            # Find the volume name.
            my @attrList = split('\/', $source);
            my $volName = $attrList[2];

            print $CONF_HANDLE "R:naSnapVault#$storageName^$source\n";
            print $CONF_HANDLE "a:name=$storageName^$source\n";
            print $CONF_HANDLE "a:sourceLocation=$source\n";

            if (exists $snapVaultToSchedule{$volName})
            {
                print $CONF_HANDLE "a:schedule=$snapVaultToSchedule{$volName}\n";
            }

            if (exists $snapVaultToRetention{$volName})
            {
                print $CONF_HANDLE "a:retention=$snapVaultToRetention{$volName}\n";
            }
        }
        elsif (/^(\s*)Destination:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:destinationLocation=$3\n";
        }
        elsif (/^(\s*)Status:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:status=$3\n";
        }
        elsif (/^(\s*)State:(\s+)(.+)(\s*)/)
        {
            print $CONF_HANDLE "a:state=$3\n";
        }
        elsif (/^(\s*)Lag:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:lagTime=$3\n";
        }
        elsif (/^(\s*)Base Snapshot:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:snapshotName=$3\n";
        }
        elsif (/^(\s*)Contents:(\s+)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "a:contents=$3\n";
            print $CONF_HANDLE "r:naSystem#$storageName\n"
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of CifsShare Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processCifsShareConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Cifs Share" command.
    my $exitCode = 0;

    print "    Collecting CIFS share resource configuration data...";

    # If there is no vfiler license present on the Storage and process with default vfiler name.
    if (0 == $foundFiler)
    {
        # Construct the complete name of NetApp "Cifs Share" raw output file where cifs related information, will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappCifsShare_vfiler0_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Cifs Share" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." CifsShareWithoutFiler $netappIpAddress $netappUserName $netappPassword> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript CifsShare $netappIpAddress $netappUserName <password>> $rawConfFile].");

        # Run the command to get the NetApp raw "Cifs Share" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Cifs Share" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Cifs Share data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = processCifsShareDumpFile($rawConfFile, "vfiler0");
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processCifsShareDumpFile() failed.");
        }

        goto EXIT;
    }

    # Loop through each filer name.
    foreach my $vfilerName (@filerList)
    {
        # Construct the complete name of NetApp "Cifs Share" raw output file where Nfs related information, will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappCifsShare_".$vfilerName."_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Cifs Share" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." CifsShare $netappIpAddress $netappUserName $netappPassword $vfilerName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript CifsShare $netappIpAddress $netappUserName <password> $vfilerName> $rawConfFile].");

        # Run the command to get the NetApp raw "Cifs Share" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Cifs Share" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Cifs Share data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        $retVal = processCifsShareDumpFile($rawConfFile, $vfilerName);
        if ($ERROR_SUCCESS != $retVal)
        {
            logMsg("Error: Call to processCifsShareDumpFile() failed.");
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to put the processed Cifs Share data in the final MARS Configuration file.
#
# @param :
#   $_[0] - Raw Conf file name.
#   $_[1] - vFiler name.
#
# @affected global variables :
#   None
#
# @return :
#   Nothing
sub processCifsShareDumpFile
{
    # Get the raw Cifs Data file name.
    $rawConfFile = $_[0];

    # Get the vFiler name.
    my $vfilerName = $_[1];

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # For every CIFS Share information, the information is spread across 2 lines. First line contains Share name and other information
    # while second line contains Permission information. This variable is used to check which line we are parsing currently.
    my $isCifsNameLine = 0;

    # This variable stores the name of Cifs Share.
    my $cifsName = "";

    # This hashmap stores Cifs Share Name as key and its mount point as value.
    my %cifsToMountPoint = ();

    # This hashmap stores Cifs Share Name as key and its Share Permission as value.
    my %cifsToSharePermission = ();

    my $retVal = 0;

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappCifsShareConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Cifs Share" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Cifs Share data as command not found.");

            $retVal = 1;
            last;
        }

        # If following condition is true then it is end of the Cifs Share data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Cifs Share data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s+)(.+)(\s*)$/)
        {
            my $sharePermission = $_;

            # Remove spaces from the beginning of the $sharePermission variable.
            $sharePermission =~ s/^\s+//;

            # Remove trailing spaces from the $sharePermission variable.
            $sharePermission =~ s/\s+$//;

            if (exists $cifsToSharePermission{$cifsName})
            {
                $sharePermission = "$sharePermission,$cifsToSharePermission{$cifsName}";
            }

            $cifsToSharePermission{$cifsName} = $sharePermission;
        }
        elsif (/^(\s*)(.+?)(\s+)\/(.+)$/)
        {
            $cifsName = $2;

            my @attrList =  split(/ /, "/$4");
            my $mountPoint = $attrList[0];

            # Remove trailing spaces from the $sharePermission variable.
            $cifsName =~ s/\s+$//;

            # Remove trailing spaces from the $mountPoint variable.
            $mountPoint =~ s/\s+$//;

            $cifsToMountPoint{$cifsName} = $mountPoint;
        }
    }

    close (CONF_DUMP);

    # Dump Cifs Share Data in the final MARS Configuration file.
    while (my ($cifsName,$mountPoint)=each %cifsToMountPoint)
    {
        print $CONF_HANDLE "R:naCifsShare#$storageName^$vfilerName-$cifsName\n";
        print $CONF_HANDLE "a:name=$storageName^$cifsName\n";
        print $CONF_HANDLE "a:mountPoint=$mountPoint\n";

        if (exists $cifsToSharePermission{$cifsName})
        {
            print $CONF_HANDLE "a:sharePermission=$cifsToSharePermission{$cifsName}\n";
        }
        print $CONF_HANDLE "r:naVFiler#$storageName^$vfilerName\n";
    }

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Snapshot Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processSnapshotConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Snapshot" command.
    my $exitCode = 0;

    print "    Collecting Snapshot resource configuration data...";

    foreach my $volName (@netappVolList)
    {
        # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
        my $confDataStart = 0;

        # Construct the complete name of NetApp "Snapshot" raw output file where Snapshot related information will get dumped.
        $rawConfFile = $netappCliOutputPath."/netappSnapshot_$volName"."_Conf.dump";

        # This variable is used to store the command to get the NetApp raw "Snapshot" data.
        my $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapShot $netappIpAddress $netappUserName $netappPassword $volName> ".$rawConfFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapShot $netappIpAddress $netappUserName <password> $volName> $rawConfFile].");

        # Run the command to get the NetApp raw "Snapshot" data.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting the NetApp raw "Snapshot" data then it is an error.
            logMsg("Error: Failed to collect the NetApp raw Snapshot data.");

            $retVal = $exitCode;
            goto EXIT;
        }

        open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

        # Loop through the content of "netappSnapshotConf.dump" file.
        while (<CONF_DUMP>)
        {
            # Remove the new line character.
            chomp;

            # If following condition is true then "Snapshot" data will start from the next line.
            if ($_ =~ /^Output start$/)
            {
                $confDataStart = 1;

                # Skip this line as it doesn't contain any useful data.
                next;
            }

            # If the command is not supported then exit from the loop.
            if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
            {
                logMsg("Error: Failed to collect the NetApp raw Snapshot data as command not found.");

                $retVal = 1;
                goto EXIT;
            }

            # If following condition is true then it is end of the SnapShot data.
            if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
            {
                last;
            }

            # If we haven't reached at the beginning of Snapshot data then skip the current line.
            if (1 != $confDataStart)
            {
                next;
            }

            if (/^(\s*)(\d+)%(\s*)\((\s*)(\d+)%\)(\s+)(\d+)%(\s*)\((\s*)(\d+)%\)(\s+)(\w*)(\s*)(\d+)(\s+)(\d+):(\d+)(\s+)(.+)(\s*)$/)
            {
                my $snapshotName = $19;
                my $blockCount = "";
                my $usedBlockPct = $5;
                my $totalBlockPct = $10;
                my $accessTime = "$12 $14 $16:$17";

                # Remove trailing spaces from the $snapshotName variable.
                $snapshotName=~ s/\s+$//;

                # In some cases, we are getting some extra information in $snapshotName. So only extracting snapshot name from the entire variable.
                if ($snapshotName =~ /\s/)
                {
                    my @snapshotArray = split(/ /, $snapshotName);
                    $snapshotName = $snapshotArray[0];
                }

                print $CONF_HANDLE "R:naSnapshot#$storageName^$volName-$snapshotName\n";
                print $CONF_HANDLE "a:name=$storageName^$volName-$snapshotName\n";
                print $CONF_HANDLE "a:usedBlockPct=$usedBlockPct\n";
                print $CONF_HANDLE "a:totalBlockPct=$totalBlockPct\n";
                print $CONF_HANDLE "a:accessTime=$accessTime\n";

                # Keep the snapshot name in double quotes so that it can be passed to shell script even if it contains special characters.
                my $snapshot = "\"$snapshotName\"";

                my $dataStart = 0;

                my $fileVariable = $snapshotName;

                # Remove all special characters in $fileVariable.
                $fileVariable =~ s/[#\-%&\$*+()]//g;

                # Construct the complete name of NetApp "SnapShot Block Count" raw output file where "Snapshot Block Count" related information, will get dumped.
                $rawConfFile = $netappCliOutputPath."/netappSnapShotblockCount_$volName"."_$fileVariable.dump";

                # This variable is used to store the command to get the NetApp raw "SnapShot Block Count" data.
                my $cmd = $netappRunTimeLocation."/".$netappExpectScript." SnapShotBlockCount $netappIpAddress $netappUserName $netappPassword $volName ".$snapshot."  > ".$rawConfFile;
                logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript SnapShotBlockCount $netappIpAddress $netappUserName <password> $volName $snapshot> $rawConfFile].");

                # Run the command to get the NetApp raw "Snapshot Block Count" data.
                $exitCode = executeSystemCmd($cmd);
                if ($ERROR_SUCCESS != $exitCode)
                {
                    # If there is some problem is collecting the NetApp raw "Snapshot Block Count" data then it is an error.
                    logMsg("Error: Failed to collect the NetApp raw Snapshot Block Count data.");

                    $retVal = $exitCode;
                    goto EXIT;
                }

                open(CONF_SNAP_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

                # Loop through the content of "netappSnapshotBlockCountConf.dump" file.
                while (<CONF_SNAP_DUMP>)
                {
                    # Remove the new line character.
                    chomp;

                    # If following condition is true then "Snapshot Block Count" data will start from the next line.
                    if ($_ =~ /^Output start$/)
                    {
                        $dataStart = 1;

                        # Skip this line as it doesn't contain any useful data.
                        next;
                    }

                    # If the command is not supported then exit from the loop.
                    if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
                    {
                        logMsg("Error: Failed to collect the NetApp raw Snapshot Block Count data as command not found.");
                        last;
                    }

                    # If following condition is true then it is end of the Snapshot Block Count data.
                    if ((1 == $dataStart) && ($_ =~ /^Output end$/))
                    {
                        last;
                    }
                    # If we haven't reached at the beginning of "Snapshot Block Count" data then skip the current line.
                    if (1 != $dataStart)
                    {
                        next;
                    }

                    if (/^(\s*)(.+)(\s+)(.+)(\s+)(\d+)(\s+)(.+)(\s+)(.+)(\s*)$/)
                    {
                        if (index($2, $snapshotName) != -1)
                        {
                            $blockCount = $6;

                            # This is done beacuse we can have double entries of block count for a particular snapshot.We only require the first entry.
                            last;
                        }
                    }
                    else
                    {
                        # Current line is of no use so ignore it.
                    }
                }
                close (CONF_SNAP_DUMP);

                print $CONF_HANDLE "a:blockCount=$blockCount\n";
                print $CONF_HANDLE "r:naVolume#$storageName^$volName\n";
            }
            else
            {
                # Current line is of no use so ignore it.
            }
        }

        close (CONF_DUMP);
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    return $retVal;
}

# This function is used to parse the Raw Configuration data of FCP (Fibre Channel) Resource. After processing, it put the processed data in the final
# MARS Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processFcpConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Fcp" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This variable stores the portId.
    my $portId = "";

    # This variable stores port name.
    my $portName = "";

    # This stores the name of Adapter.
    my $adapter = "";

    # This hashmap stores portname as key and portId as value.
    my %portNameToId = ();

    # This stores portName as key and nodeName as value.
    my %portNameToNodeName = ();

    print "    Collecting FCP resource configuration data...";

    # Construct the complete name of NetApp "Fcp Name Server" raw output file where SnapShot related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappFcpNameServer.dump";

    # This variable is used to store the command to get the NetApp raw "Fcp Name Server" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." FcpNameServer $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript FcpNameServer $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Fcp Name Server" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Fcp Name Server" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Fcp Name Server data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappFcpNameServer.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Fcp Name Server" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Fcp Name Server data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Fcp Name Server data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }
        # If we haven't reached at the beginning of System data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Port ID:(\s+)(\w+)(\s*)$/)
        {
            $portId = sprintf("%d", hex($3));
        }
        elsif (/^(\s*)Port Name:(\s+)(.+)(\s*)$/)
        {
            $portName = $3;

            # Remove trailing whitespaces from the $portName.
            $portName =~ s/\s+$//;

            $portNameToId{$portName} = $portId;
        }
        elsif (/^(\s*)Node Name:(\s+)(.+)(\s*)$/)
        {
            my $nodeName = $3;

            # Remove trailing whitespaces from the $nodeName.
            $nodeName =~ s/\s+$//;

            $portNameToNodeName{$portName} = $nodeName;
        }
    }

    close (CONF_DUMP);

    $confDataStart = 0;

    # Construct the complete name of NetApp "Fcp Initiator" raw output file where Fcp related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappFcpInitiatorConf.dump";

    # This variable is used to store the command to get the NetApp raw "Fcp Initiator" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." FcpInitiator $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript FcpInitiator $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Fcp Initiator" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Fcp Initiator" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Fcp Initiator data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappFcpInitiatorConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Fcp Initiator" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Fcp Initiator data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Fcp Initiator data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of FCP initiator data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Initiators connected on adapter(\s+)(.+):(\s*)$/)
        {
            $adapter = $3;
        }
        elsif (/^(\s*)Portname(\s+)Group(\s*)$/)
        {
            # Skip this line as it is of no use.
        }
        elsif (/^(\s*)(.+)(\s+)(\w+)(\s*)$/)
        {
            my $name = "$2";

            # Remove trailing whitespaces from the $name.
            $name =~ s/\s+$//;

            print $CONF_HANDLE "R:naFcpInitiator#$storageName^$name\n";
            print $CONF_HANDLE "a:name=$storageName^$name\n";
            print $CONF_HANDLE "a:adaptor=$adapter\n";

            if (exists $portNameToId{$name})
            {
                print $CONF_HANDLE "a:portAddress=$portNameToId{$name}\n";
            }

            if (exists $portNameToNodeName{$name})
            {
                print $CONF_HANDLE "a:nodeName=$portNameToNodeName{$name}\n";
            }

            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Iscsi Resource. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processIscsiConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Iscsi Portal" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This hashmap stores tpGroup as key and corresponding "ip" as value.
    my %tpGroupToIp = ();

    # This hashmap stores tpGroup as key and corresponding "port" as value.
    my %tpGroupToPort = ();

    # This hashmap stores tpGroup as key and corresponding "interface" as value.
    my %tpGroupToInterface = ();

    # This hashmap stores TSIH as key and Initiator Ip as value.
    my %tsihToInitiatorIp = ();

    # This hashmap stores TSIH as key and Initiator Port as value.
    my %tsihToInitiatorPort = ();

    # This variable stores maximum number if iscsi connections.
    my $maxConnection = "";

    # This variable store the authentication information for iscsi initiator.
    my $authentication = "";

    # This variable stores the TSIH number.
    my $tsih = "";

    print "    Collecting iSCSI resource configuration data...";

    # Construct the complete name of NetApp "Iscsi Portal" raw output file where Iscsi Portal related information will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappIscsiPortal.dump";

    # This variable is used to store the command to get the NetApp raw "Iscsi Portal" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." IscsiPortal $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript IscsiPortal $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Iscsi Portal" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Iscsi Portal" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Iscsi Portal data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappIscsiPortal.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Iscsi Portal" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Iscsi Portal data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Iscsi Portal data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Iscsi Portal data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(\d+).(\d+).(\d+).(\d+)(\s+)(\w+)(\s+)(\w+)(\s+)(\w*)(\s*)$/)
        {
            $tpGroupToIp{$9} = "$2.$3.$4.$5";
            $tpGroupToPort{$9} = $7;
            $tpGroupToInterface{$9} = $11;
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);

    # Find information about TSIH.
    $confDataStart = 0;

    # Construct the complete name of NetApp "Iscsi connection" raw output file where Iscsi connection related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappIscsiCon.dump";

    # This variable is used to store the command to get the NetApp raw "Iscsi connection" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." IscsiCon $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript IscsiCon $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Iscsi connection" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Iscsi connection" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Iscsi connection data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappIscsiCon.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Iscsi connection" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Iscsi connection data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Iscsi connection data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }
        # If we haven't reached at the beginning of Iscsi connection data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Connection(\s+)(\w+)\/(\w+):(\s*)$/)
        {
            $tsih = $3;
        }
        elsif (/^(\s*)Remote Endpoint:(\s+)(.+):(\w+)(\s*)$/)
        {
            $tsihToInitiatorIp{$tsih} = $3;
            $tsihToInitiatorPort{$tsih} = $4;
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);

    # Find information about iSCSI security.
    $confDataStart = 0;

    # Construct the complete name of NetApp "Iscsi Security" raw output file where Iscsi Security related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappIscsiSecurity.dump";

    # This variable is used to store the command to get the NetApp raw "Iscsi Security" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." IscsiSecurity $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript IscsiSecurity $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Iscsi Security" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Iscsi Security" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Iscsi Security data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappIscsiSecurity.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Iscsi security" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Iscsi Security data as command not found.");
            last;
        }

        # If following condition is true then it is end of the Iscsi security data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Iscsi security data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)Default sec is(\s*)(\w*)(\s*)$/)
        {
            $authentication = $3;
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);

    # Collect information about iSCSI initiator remaining information.
    $confDataStart = 0;

    # Construct the complete name of NetApp "Iscsi Initiator" raw output file where Fcp related information, will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappIscsiInitiator.dump";

    # This variable is used to store the command to get the NetApp raw "Iscsi Initiator" data.
    $cmd = $netappRunTimeLocation."/".$netappExpectScript." IscsiInitiator $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript IscsiInitiator $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Iscsi Initiator" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Iscsi Initiator" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Iscsi Initiator data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappIscsiInitiator.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Iscsi Initiator" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Iscsi Initiator data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Iscsi Initiator data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }
        # If we haven't reached at the beginning of Iscsi Initiator data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        # Here the Output formatt is : "14    1000   iqn.1991-05.com.microsoft:priyanka-pc.corp.cumulus / 40:00:01:37:00:01 / windowsTested; windows2007"
        if (/^(\s*)(\d+)(\s+)(\d+)(\s+)(.+)(\s*)\/(\s*)(.+)(\s*)\/(\s*)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "R:naIscsiInitiator#$storageName^$6\n";
            print $CONF_HANDLE "a:name=$storageName^$6\n";
            print $CONF_HANDLE "a:sessionId=$9\n";
            print $CONF_HANDLE "a:maxConnection=\n";
            print $CONF_HANDLE "a:authentication=$authentication\n";

            if (exists $tsihToInitiatorIp{$2})
            {
                print $CONF_HANDLE "a:initiatorIp=$tsihToInitiatorIp{$2}\n";
            }

            if (exists $tsihToInitiatorPort{$2})
            {
                print $CONF_HANDLE "a:initiatorPort=$tsihToInitiatorPort{$2}\n";
            }

            if (exists $tpGroupToIp{$4})
            {
                print $CONF_HANDLE "a:filerIp=$tpGroupToIp{$4}\n";
            }

            if (exists $tpGroupToPort{$4})
            {
                print $CONF_HANDLE "a:filerPort=$tpGroupToPort{$4}\n";
            }

            if (exists $tpGroupToInterface{$4})
            {
                print $CONF_HANDLE "a:interfaceName=$tpGroupToInterface{$4}\n";
            }

            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
        # Here the Output formatt is : "5    1000   iqn.1991-05.com.microsoft:priyanka-pc.corp.cumulus / 40:00:01:37:00:01"
        elsif (/^(\s*)(\d+)(\s+)(\d+)(\s+)(.+)(\s*)\/(\s*)(.+)(\s*)$/)
        {
            print $CONF_HANDLE "R:naIscsiInitiator#$storageName^$6\n";
            print $CONF_HANDLE "a:name=$storageName^$6\n";
            print $CONF_HANDLE "a:sessionId=$9\n";
            print $CONF_HANDLE "a:maxConnection=\n";
            print $CONF_HANDLE "a:authentication=$authentication\n";

            if (exists $tsihToInitiatorIp{$2})
            {
                print $CONF_HANDLE "a:initiatorIp=$tsihToInitiatorIp{$2}\n";
            }

            if (exists $tsihToInitiatorPort{$2})
            {
                print $CONF_HANDLE "a:initiatorPort=$tsihToInitiatorPort{$2}\n";
            }

            if (exists $tpGroupToIp{$4})
            {
                print $CONF_HANDLE "a:filerIp=$tpGroupToIp{$4}\n";
            }

            if (exists $tpGroupToPort{$4})
            {
                print $CONF_HANDLE "a:filerPort=$tpGroupToPort{$4}\n";
            }

            if (exists $tpGroupToInterface{$4})
            {
                print $CONF_HANDLE "a:interfaceName=$tpGroupToInterface{$4}\n";
            }

            print $CONF_HANDLE "r:naSystem#$storageName\n";
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to parse the Raw Configuration data of Initiator Group. After processing, it put the processed data in the final MARS
# Configuration file.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub processInitiatorGroupConfData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "Initiator Group" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    # This variable stores Initiator Group name.
    my $initiatorGroup = "";

    # This variable stores Initiator name.
    my $initiator = "";

    # This HashMap stores Initiator Group as key and and its OS as value.
    my %initiatorGroupToOs = ();

    # This HashMap stores Initiator Group as key and and its type as value.
    my %initiatorGroupToType = ();

    print "    Collecting initiator group resource configuration data...";

    # Construct the complete name of NetApp "Initiator Group" raw output file where Initiator Group related information will get dumped.
    $rawConfFile = $netappCliOutputPath."/netappInitiatorGroup.dump";

    # This variable is used to store the command to get the NetApp raw "Initiator Group" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." InitiatorGroup $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript InitiatorGroup $netappIpAddress $netappUserName <password> > $rawConfFile].");

    # Run the command to get the NetApp raw "Initiator Group" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Initiator Group" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Initiator Group data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netappInitiatorGroup.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        # If following condition is true then "Initiator Group" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the loop.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Initiator Group data as command not found.");

            $retVal = 1;
            last;
        }

        # If following condition is true then it is end of the Initiator Group data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Initiator Group data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(.+)(\s+)\((\w*)\)(\s+)\(ostype:(\s+)(\w*)\):(\s*)$/)
        {
            $initiatorGroup = $2;

            $initiatorGroupToOs{$initiatorGroup} = $7;
            $initiatorGroupToType{$initiatorGroup} = $4;
        }
        elsif (/^(\s*)(.+)(\s+)\((.+)\)(\s*)$/)
        {
            $initiator = $2;
            if (exists $initiatorGroupToInitiator{$initiatorGroup})
            {
                $initiator = $initiator.",".$initiatorGroupToInitiator{$initiatorGroup};
            }

            $initiatorGroupToInitiator{$initiatorGroup} = $initiator;
        }
    }

    while (my ($initiatorGroupName,$osType)=each %initiatorGroupToOs)
    {
        print $CONF_HANDLE "R:naInitiatorGroup#$storageName^$initiatorGroupName\n";
        print $CONF_HANDLE "a:name=$storageName^$initiatorGroupName\n";
        print $CONF_HANDLE "a:osType=$osType\n";

        if (exists $initiatorGroupToInitiator{$initiatorGroupName})
        {
            print $CONF_HANDLE "a:initiator=$initiatorGroupToInitiator{$initiatorGroupName}\n";
        }
        else
        {
            print $CONF_HANDLE "a:initiator=\n";
        }

        if (exists $initiatorGroupToType{$initiatorGroupName})
        {
            print $CONF_HANDLE "a:type=$initiatorGroupToType{$initiatorGroupName}\n";
        }
        else
        {
            print $CONF_HANDLE "a:type=\n";
        }

        print $CONF_HANDLE "r:naSystem#$storageName\n";
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }
    else
    {
        print " Data collection failed.\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to find the list of filers present on the NetApp Storage.
#
# @param :
#   $_[0] - Array of filer name.
#
# @return :
#   0 if Success.
#   0> if Error.
sub getFilerList
{
    # This variable is used to store the return value of function call.
    my $retVal = 0;

    # This variable is used to store the exit status of "FilerList" command.
    my $exitCode = 0;

    my @inputFilerList = $_[0];

    # Construct the complete name of NetApp CLI raw output file where name of NetApp vfiler name will get dumped.
    my $netappTempCliOutputFile = $netappCliOutputPath."/vfilerListOutput.dump";

    # This variable is used to store the command to get the NetApp raw CLI data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." FilerList $netappIpAddress $netappUserName $netappPassword > ".$netappTempCliOutputFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript FilerList $netappIpAddress $netappUserName <password> > $netappTempCliOutputFile].");

    # Run the command to get NetApp vFiler list.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting NetApp CLI data then it is an error.
        logMsg("Error: Failed to collect CLI output for FilerList.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $netappTempCliOutputFile) or die logMsg("Error: Not able to open the file: [$netappTempCliOutputFile].");

    # This variable is used to indicate that we have reached at the output line from where vFiler information start.
    my $dataStart = 0;

    # Loop through the content of "vfilerListOutput.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        chomp;

        logMsg("Info: Filer line: [$_].");

        # If following condition is true then filer data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $dataStart = 1;
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect CLI output for FilerList as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the filer data.
        if ((1 == $dataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of filer data then skip the current line.
        if (1 != $dataStart)
        {
            next;
        }

        # Look for string which contain filer name on NetApp storage.
        if ($_ =~ /^(\s*)(\S+)(\s+)(\S+)(\s*)$/)
        {
            logMsg("Info: Found Filer: [$2].");
            push(@{$_[0]}, $2);

            $foundFiler = 1;
        }
    }

EXIT:

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to log a message in the log file. It logs the message in the following format:
# [YYYY-MM-DD HH:MM:ss,SSS] [NetApp-<IP Address>] <Log message>
#
# @param :
#   $_[0] - Log message.
#
# @affected global variables :
#   None
#
# @return :
#   Nothing
sub logMsg
{
    # Get the current date and time.
    my ($seconds, $microseconds) = gettimeofday;
    my $currentTime = strftime("%Y-%m-%d %H:%M:%S", localtime($seconds));

    # Get the date from the given date and time .
    my($date, $time) = split(' ', $currentTime, 2);

    # Set the name of log file.
    $logFile = $netappLogFolder."/mdcNetApp.".$date.".log";

    # Open the log file.
    open($LOG_HANDLE, ">>", $logFile) or die "Not able to open the file: [$logFile].";

    # Read input parameters.
    my $logMsg = $_[0];

    # For getting time in a given format.
    $currentTime = "[".$currentTime.",".$microseconds."]";

    # Construct the final log message.
    my $finalMsg = $currentTime." [NetApp-".$netappIpAddress."] ".$logMsg."\n";

    # Dump the final log message in log file.
    print $LOG_HANDLE $finalMsg;
}

# This function is used to update the NetApp Configuration output file with the Metadata information about the Probe.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   1 if Error
sub prepareProbeMetadata
{
    # It is used to store the current date and time (GMT) in "YYYYMMDD_HHMMSS" format.
    (my $second, my $minute, my $hour, my $dayOfMonth, my $month, my $yearOffset, my $dayOfWeek, my $dayOfYear, my $daylightSavings) = gmtime();
    my $year = 1900 + $yearOffset;
    my $currentTime = sprintf("%04d%02d%02d_%02d%02d%02d", $year, $month + 1, $dayOfMonth, $hour, $minute, $second);

    # Open the final MARS configuration file.
    open($CONF_HANDLE, ">", $finalConfFilePath) or die logMsg("Error: Not able to open the file: [$finalConfFilePath].");

    print $CONF_HANDLE "%meta\n";
    print $CONF_HANDLE "probe_id:$marsSiteName"."_"."$netappIpAddress\n";
    print $CONF_HANDLE "probe_type:NetApp\n";
    print $CONF_HANDLE "probe_site:$marsSiteName\n";
    print $CONF_HANDLE "probe_server:$netappIpAddress\n";
    print $CONF_HANDLE "probe_version:$probeVersion\n";
    print $CONF_HANDLE "%meta\n";
    print $CONF_HANDLE "t:$currentTime\n";

    return 0;
}

# This function is used for zipping final Mars file into format that can be processed by MARS server.
#
# @param :
#   $_[0] - Final conf zip file name.
#   $_[1] - Conf ListOfFiles... name.
#   $_[2] - File which needs to be zipped.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   0> if Error
sub zipMarsFile
{
    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the final Conf Zip File Name which will be processed by server.
    my $zipFileName = $_[0];

    # Create List of File corresponding to the Zipped MARS File.
    my $listOfFileName = $_[1];

    # Get the name of file that needs to be zipped.
    my $fileToBeZipped = $_[2];

    # This variable is used to store the final Conf Zip File Name location.
    my $zipFileLocation = $finalDataZippedFolder."/".$zipFileName;

    # This variable is used to store the command to Zip the final Mars Conf file.
    my $cmd = "zip -q -j '$zipFileLocation' '$fileToBeZipped'" ;
    logMsg("Info: Running command: zip -q -j '$zipFileLocation' '$fileToBeZipped' ");

    # Run the command to Zip the final Mars Conf file.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is creating zip file then it is an error.
        logMsg("Error: Failed to Zip the final Mars Conf file.");
    }

    $retVal = $exitCode;

    # Delete the unzipped file.
    logMsg("Info: Deleting file: [$fileToBeZipped].");

    if (1 != unlink($fileToBeZipped))
    {
        logMsg("Error: File delete failed. File: [$fileToBeZipped].");
        $retVal = 1;
    }

    # Open the List Of file corresponding to the Zipped MARS configuration file.
    open(my $FILE_HANDLE, ">", $listOfFileName) or die logMsg("Error: Not able to open the file: [$listOfFileName].");

    # Write Zipped file name in the List Of File.
    print $FILE_HANDLE "$zipFileName\n";

    # Close the file handle.
    close $FILE_HANDLE;

    return $retVal;
}

# This function is used to de-initialize the environment.
#
# @affected global variables :
#   $CONF_HANDLE
#
# @return :
#   None
sub deInit
{
    if (0 != $CONF_HANDLE)
    {
        close($CONF_HANDLE);
    }

    if (0 != $LOG_HANDLE)
    {
        close($LOG_HANDLE);
    }

    # De-initialize memory allocated to all global hashmap.
    %vfilerAndNumberOfFile = ();
    %qtreeAndNumberOfFile = ();
    %qtreeAndUsedDiskSize = ();
    %qtreeAndAverageFileSize = ();
    %initiatorGroupToInitiator = ();
    %volToTotalCap = ();
    %volToUsedCap = ();
    %volToAvailCap = ();
    %aggrToRaidSize = ();
    %volToQtree = ();

    # De-initialize memory allocated to all global array.
    @netappVolList = ();
    @filerList = ();
}

# This function is used to convert given size capacity in bytes.
#
# @affected global variables :
#   None
#
# @param :
#   $_[0] - [In] Capacity which need to be converted to Bytes.
#   $_[1] - [In] Unit of the capacity which need to be converted to Bytes.
#
# @return :
#   $capInBytes - Capacity in Bytes.
sub covertCapToBytes
{
    # Get the input parameters.
    (my $cap, my $unit) = @_;

    # Capacity in Bytes.
    my $capInBytes = "";

    if ($unit eq "KB")
    {
        $capInBytes = $cap * 1024;
    }
    elsif ($unit eq "MB")
    {
        $capInBytes = $cap * 1024 * 1024;
    }
    elsif ($unit eq "GB")
    {
        $capInBytes = $cap * 1024 * 1024 * 1024 ;
    }
    elsif ($unit eq "TB")
    {
        $capInBytes = $cap * 1024 * 1024 * 1024 * 1024;
    }

    return $capInBytes;
}

# This function is used to populate volume capacities map.
#
# @affected global variables :
#   %volToTotalCap
#   %volToUsedCap
#   %volToAvailCap
#
# @return :
#   0 if Success
#   0> if Error
sub populateVolumeCapMap
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappVolumeCapacityConf.dump";

    # This variable is used to store the command to get the NetApp raw "Volume Capacity" data.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." VolumeCapacity $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript VolumeCapacity $netappIpAddress $netappUserName <password>> $rawConfFile].");

    # Run the command to get the NetApp raw "Volume Capacity" data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting the NetApp raw "Volume Capacity" data then it is an error.
        logMsg("Error: Failed to collect the NetApp raw Volume Capacity data.");

        $retVal = $exitCode;
        goto EXIT;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of "netAppVolumeCapacityConf.dump" file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        # If following condition is true then "Volume Capacity" data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to collect the NetApp raw Volume Capacity data as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the "Volume Capacity" data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Volume capacity data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)\/(\w+)\/(.+)\/(\s+)(\d+)(\w*)(\s+)(\d+)(\w*)(\s+)(\d+)(\w*)(\s+)(\d+)%(.+)(\s*)$/)
        {
            $volToTotalCap{$3} = covertCapToBytes($5, $6);
            $volToUsedCap{$3} = covertCapToBytes($8, $9);
            $volToAvailCap{$3} = covertCapToBytes($11, $12);
        }
        else
        {
            # Current line is of no use. So skip it.
        }
    }

EXIT:

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to update the Probe Custom output file with the Metadata information about the Probe.
#
# @affected global variables :
#   None.
#
# @return :
#   0 if Success
#   1 if Error
sub prepareProbeCustomMetadata
{
    # It is used to store the current date and time (GMT) in "YYYYMMDD_HHMMSS" format.
    (my $second, my $minute, my $hour, my $dayOfMonth, my $month, my $yearOffset, my $dayOfWeek, my $dayOfYear, my $daylightSavings) = gmtime();
    my $year = 1900 + $yearOffset;
    my $currentTime = sprintf("%04d%02d%02d_%02d%02d%02d", $year, $month + 1, $dayOfMonth, $hour, $minute, $second);

    # Set the final NetApp CLI output file name.
    $finalCliOutputFile = $netappCliOutputPath."/".$marsSiteName."_".$netappIpAddress."_customdata_".$currentTime."_".$probeVersion.".txt";
    logMsg("Info: NetApp CLI output file name: [$finalCliOutputFile].");

    # Open the final NetApp CLI output file.
    open($CLI_DATA_HANDLE, ">", $finalCliOutputFile) or die logMsg("Error: Not able to open the file: [$finalCliOutputFile].");

    print $CLI_DATA_HANDLE "#%meta\n";
    print $CLI_DATA_HANDLE "#probe_id:$marsSiteName"."_"."$netappIpAddress\n";
    print $CLI_DATA_HANDLE "#probe_type:NetApp\n";
    print $CLI_DATA_HANDLE "#probe_site:$marsSiteName\n";
    print $CLI_DATA_HANDLE "#probe_server:$netappIpAddress\n";
    print $CLI_DATA_HANDLE "#probe_version:$probeVersion\n";
    print $CLI_DATA_HANDLE "#%meta\n";
    print $CLI_DATA_HANDLE "#t:$currentTime\n";

    return 0;
}

# This function is used to collect NetApp CLI output data and dump it in a file.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   0> if Error
sub getNetAppProbeCustomData
{
    # This variable is used to store the return code for this function.
    my $retVal = 0;

    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # This variable is used to indicate whether we have found NetApp CLI name in the raw CLI output file.
    my $commandFound = 0;

    # This variable is used to indicate the end of NetApp CLI output in the raw CLI output file.
    my $cliOutputStart = 0;

    # This variable is used to store the content of line which got passed in the previous iteration. We are storing it as we don't want to append
    # "\n \" in the last line of CLI output.
    my $previousLine = "";

    # This array is used to store the name of filers present on the NetApp Storage.
    my @filerList = ();

    print "    Collecting raw configuration data...";

    # Construct the complete name of NetApp CLI raw output file.
    $netappCliRawOutputFile = $netappCliOutputPath."/".$netappProbeCustomFileName;

    # This variable is used to store the command to get the NetApp CLI data specific to NetApp Storage.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." NetApp $netappIpAddress $netappUserName $netappPassword > ".$netappCliRawOutputFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript NetApp $netappIpAddress $netappUserName <password> > $netappCliRawOutputFile].");

    # Run the command to get the NetApp CLI data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is collecting NetApp CLI data then it is an error.
        logMsg("Error: Failed to collect CLI output for NetApp Storage.");

        $retVal = $exitCode;
        goto EXIT;
    }

    # Get the list of filers present on the NetApp Storage.
    my $retValue = getFilerList(\@filerList);
    if (0 != $retValue)
    {
        logMsg("Error: Call to getFilerList() failed.");
        goto EXIT;
    }

    # Loop through each filer name.
    foreach my $vfilerName (@filerList)
    {
        logMsg("Info: vFiler name: [$vfilerName].");

        # Prepare the command to get the CLI output specific to a Filer.
        $cmd = $netappRunTimeLocation."/".$netappExpectScript." Filer $netappIpAddress $netappUserName $netappPassword $vfilerName >> ".$netappCliRawOutputFile;
        logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Filer $netappIpAddress $netappUserName <password> $vfilerName >> $netappCliRawOutputFile].");

        # Run the command to get the Filer information.
        $exitCode = executeSystemCmd($cmd);
        if ($ERROR_SUCCESS != $exitCode)
        {
            # If there is some problem is collecting NetApp CLI data then it is an error.
            logMsg("Error: Failed to collect CLI output for NetApp Storage.");

            $retVal = $exitCode;
            goto EXIT;
        }
    }

    logMsg("Info: Reading NetApp raw CLI data.");

    open(CONF_DUMP, $netappCliRawOutputFile) or die logMsg("Error: Not able to open the file: [$netappCliRawOutputFile].");

    # Loop through the content of NetApp raw CLI output file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        # Look for "NetApp CLI" string in the file. This string is the start indicator of NetApp CLI execution.
        if ($_ =~ /^NetApp CLI: (.+)$/)
        {
            # Replace " " (space) in the command name with "_" as Java property file doesn't except spaces in the name part of name-value pair.
            my $command = $1;
            $command =~ s/ /_/g;

            # We need to append "\n \" so that Java code can get the value part of name-value pair which is spread over multiple lines.
            print $CLI_DATA_HANDLE "$command=\\n \\\n";

            $commandFound = 1;

            next;
        }

        # If we found "Output start" then it means that we will find the CLI output from the next line.
        if ((1 == $commandFound) && ($_ =~ /^Output start$/))
        {
            $cliOutputStart = 1;

            next;
        }

        # If we found "Output end" then it means that we reached at the end of CLI output.
        if ((1 == $cliOutputStart) && ($_ =~ /^Output end$/))
        {
            # Dump the last line of the CLI output without appending "\n \" at the end.
            print $CLI_DATA_HANDLE ":$previousLine\n";

            # Reset different variables.
            $cliOutputStart = 0;
            $commandFound = 0;
            $previousLine = "";

            next;
        }

        # We will come here when we have found NetApp CLI data in the file.
        if (1 == $cliOutputStart)
        {
            # If previous line is not empty then dump it along with appending "\n \" at the end.
            if ("" ne $previousLine)
            {
                if ($previousLine =~ /^=====(\s+)(\w+)(\s*)$/)
                {
                    my $stringToReplace = "=====";
                    my $stringToReplaceWith = "*****";
                    $previousLine =~ s/$stringToReplace/$stringToReplaceWith/;
                }

                print $CLI_DATA_HANDLE ":$previousLine\\n \\\n";
            }

            # Save the current line.
            $previousLine = $_;

            next;
        }
    }

EXIT:

    if ($ERROR_SUCCESS == $retVal)
    {
        print " Done\n";
    }

    close (CONF_DUMP);

    return $retVal;
}

# This function is used to run a command through system() call. system() call somehow returns error code differently by shifting the exit code to 8
# bits left side. So this function also shifted back the exit code to 8 bits right side and return it.
#
# @affected global variables :
#   None
#
# @return :
#   Exit code shifted to 8 bits right.
sub executeSystemCmd
{
    my $tempExitCode = system($_[0]);

    my $exitCode = $tempExitCode >> 8;

    return $exitCode;
}

# This function is used for zipping final NetApp Storage specific Data into a single file.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   0> if Error
sub zipFinalDataFolder
{
    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # Get the current date and time.
    my ($seconds, $microseconds) = gettimeofday;
    my $currentTime = strftime("%Y%m%d_%H%M%S", localtime($seconds));

    $finalZipFileName = $marsSiteName."_".$netappIpAddress."_".$currentTime.".zip";
    logMsg("Info: Final zip file name: [$finalZipFileName].");

    # This variable stores the current directory.
    my $cwd = cwd();

    print "Compressing NetApp configuration data.\n";

    # Change the directory to the folder where the final data is place so that only the contents of this directory get zipped in the final zip file.
    chdir($finalDataZippedFolder);

    # This variable is used to store the final Data Zip File Name location.
    my $zipFileLocation = $finalProcessedData."/".$finalZipFileName;

    # This variable is used to store the command to Zip the final data.
    my $cmd = "zip -q $zipFileLocation *" ;
    logMsg("Info: Running command: zip -q $zipFileLocation * ");

    # Run the command to Zip the final data.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is creating zip file then it is an error.
        logMsg("Error: Failed to Zip the final data folder. Zip file: [$zipFileLocation]");
    }

    $retVal = $exitCode;

    chdir($cwd);

    # Delete the $finalDataZippedFolder.
    $cmd = "rm -rf $finalDataZippedFolder" ;
    logMsg("Info: Deleting folder: [$finalDataZippedFolder].");

    # Run the command to delete the $finalDataZippedFolder
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is creating zip file then it is an error.
        logMsg("Error: Failed to delete the final data folder. Folder: [$finalDataZippedFolder].");
    }

    $retVal = $exitCode;

    print "******************************************************************\n\n";

    return $retVal;
}

# This function is used for verifying the credentials entered by the user.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   0> if Error
sub testCredentials
{
    # This variable is used to store the exit status of "system" command.
    my $exitCode = 0;

    # This variable is used to store the return value of function calls.
    my $retVal = 1;

    # It is used to indicate the beginning of NetApp Configuration data in the raw configuration data file.
    my $confDataStart = 0;

    $rawConfFile = $netappCliOutputPath."/netappAuthentication.dump";

    # Prepare the command to test the credentials entered by the user.
    my $cmd = $netappRunTimeLocation."/".$netappExpectScript." Authentication $netappIpAddress $netappUserName $netappPassword > ".$rawConfFile;
    logMsg("Info: Running command: [$netappRunTimeLocation/$netappExpectScript Authentication $netappIpAddress $netappUserName <password>.");

    # Run the command to test the credentials.
    $exitCode = executeSystemCmd($cmd);
    if ($ERROR_SUCCESS != $exitCode)
    {
        # If there is some problem is in verifying the user credentials, then it is an error.
        logMsg("Error: Failed to verify the credentials entered by the user.");

        $retVal = $exitCode;
    }

    open(CONF_DUMP, $rawConfFile) or die logMsg("Error: Not able to open the file: [$rawConfFile].");

    # Loop through the content of NetApp raw CLI output file.
    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        # If following condition is true then Authentication data will start from the next line.
        if ($_ =~ /^Output start$/)
        {
            $confDataStart = 1;

            # Skip this line as it doesn't contain any useful data.
            next;
        }

        # If the command is not supported then exit from the function.
        if ($_ =~ /^(\s*)no such command(.*)(\s*)$/)
        {
            logMsg("Error: Failed to verify the credentials entered by the user as command not found.");

            $retVal = 1;
            goto EXIT;
        }

        # If following condition is true then it is end of the Authentication data.
        if ((1 == $confDataStart) && ($_ =~ /^Output end$/))
        {
            last;
        }

        # If we haven't reached at the beginning of Authentication data then skip the current line.
        if (1 != $confDataStart)
        {
            next;
        }

        if (/^(\s*)(.*)NetApp Release(.*)(\s*)$/)
        {
            $retVal = 0;
            goto EXIT;
        }
        else
        {
            # Current line is of no use so ignore it.
        }

    }

EXIT:

    return $retVal;
}
# ----------------------------------------------------------------------------------------------------------------------------------------------------