com.pari.pcb.zip.ZIPProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.pari.pcb.zip.ZIPProcessor.java

Source

/**
 * Copyright (c) 2005 - 2007 Pari Networks, Inc.  All Rights Reserved.
 *
 * This software is the proprietary information of Pari Networks, Inc.
 *
 */

package com.pari.pcb.zip;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import com.ibm.icu.text.CharsetDetector;
import com.pari.api.utils.CompressionUtils;
import com.pari.api.utils.DevicePropertyProviderIf;
import com.pari.nm.modules.dsp.DSPHandler;
import com.pari.nm.modules.dsp.ZipImportDSPHandler;
import com.pari.nm.modules.dsp.management.DeviceScriptInfo.PackageType;
import com.pari.nm.modules.dsp.management.DeviceScriptManagerImpl;
import com.pari.nm.modules.dsp.pojo.DSPZipImportData;
import com.pari.nm.modules.dsp.pojo.DevProperties;
import com.pari.nm.utils.performance.NCCMObserver;
import com.pari.pcb.PCBFile;
import com.pari.swim.ScriptInfo;

public class ZIPProcessor extends Thread implements DevicePropertyProviderIf {
    public static final Logger logger = Logger.getLogger(ZIPProcessor.class);

    // Pattern for checking the Valid version number

    private static Pattern validVersionPattern = Pattern.compile("[\\s]*([-:_0-9a-zA-Z\\.\\[\\]()]+).*$");
    // ----------------------------------------------------------- Generic Hostname & Version Patterns
    // ----------------------------------------------/

    private static Pattern generic_configVersionPattern1 = Pattern.compile("^[ \t]*version [ \t]*(.*)");
    private static Pattern generic_VersionPattern2 = Pattern.compile("^.*Version(.*)");
    private static Pattern generic_configVersionPattern3 = Pattern.compile("^vesrsion (.*)");
    private static Pattern generic_configVersionPattern4 = Pattern.compile("^#[ \t]*version [ \t]*(.*)");
    private static Pattern generic_configHostNamePattern1 = Pattern.compile("^[ \t]*host-name[ \t](.*)?;$");
    private static Pattern generic_configHostNamePattern2 = Pattern.compile("^switchname[ \t](.*)$");
    private static Pattern generic_configHostNamePattern3 = Pattern.compile("^hostname[ \t](.*)$");
    private static Pattern generic_configHostNamePattern4 = Pattern.compile("^host-name\\s+(.*)$");
    private static Pattern generic_configHostNamePattern5 = Pattern.compile("^switchname (.*)");

    private static Pattern generic_versionHostNamePattern1 = Pattern.compile("^Hostname:\\s+(.*)");
    private static Pattern generic_versionHostNamePattern2 = Pattern
            .compile("^[ \t]*([^ \t]+)[ \t]+uptime[ \t]+is[ \t]+.*$");
    private static Pattern generic_versionHostNamePattern3 = Pattern.compile("^(.*)\\s+up.*hours");
    private static Pattern generic_versionHostNamePattern4 = Pattern.compile("^.*Device name:(.*)");
    private static Pattern generic_versionHostNamePattern5 = Pattern.compile("^(.*)up.*year.*");
    private static Pattern generic_versionHostNamePattern6 = Pattern.compile("^(.*).*up.*hours");

    private static Pattern generic_versionHostNamePattern7 = Pattern.compile("^(.*).*up.*secs");
    private static Pattern generic_versionHostNamePattern8 = Pattern.compile("^(.*) uptime.*");
    // ----------------- Patterns to identify SCE
    // devices---------------------------------------------------------------------->

    private static Pattern sceVersion_ConfigPattern1 = Pattern.compile("^RDR-formatter (.*)");
    // --------------------- Patterns to identify IOS devices----------------------------------------------------->

    private static Pattern iosxrConfigPattern = Pattern.compile("^[ \t]*interface.*CPU0.*$");
    private static Pattern iosxrConfigPattern1 = Pattern.compile(".*IOS XR Configuration (.*)");
    private static Pattern iosxrVersion_ShowVersionPattern = Pattern
            .compile("^Cisco IOS XR Software, Version (.*)");

    private static Pattern iosVersionPattern1 = Pattern.compile("^.*Cisco.*IOS Software.*");

    private static Pattern iosVersionPattern2 = Pattern.compile("^Cisco IOS.*");
    // -----Patterns to identify ASR5k devices------------------------------------------------------------->
    private static Pattern asr5k_ConfigPattern1 = Pattern.compile("^[ \t]*license key.*");
    private static Pattern asr5k_ConfigPattern2 = Pattern.compile("^[ \t]*aaa large-configuration");
    private static Pattern asr5k_ConfigPattern3 = Pattern.compile("^[ \t]*require active-charging");
    private static Pattern asr5kHostName_ConfigPattern = Pattern.compile("^[ \t]*system hostname (.*)");
    private static Pattern asr5kVersion_Pattern = Pattern.compile("^[ \t]*  Image Version:\\s+(.*)\\s.*");
    // --------------------- Patterns to identify CAT-OS device ------------------------------------------------------>
    private static Pattern catosHostName_ConfigPattern1 = Pattern.compile("^set system name (.*)");
    private static Pattern catosVersion_ShowVersionPattern = Pattern.compile(".*Version.*SW: [ \t]*(.*)");
    // ----------------------- Patterns to identify PIX devices
    // -------------------------------------------------------------------------------------->

    private static Pattern PIXVersion_ConfigPattern = Pattern.compile("^.*PIX Version (.*)");
    private static Pattern pixVersion_ShowVersionPattern = Pattern.compile("^Cisco PIX .* Version (.*)");
    // ----------------------------------------------------------------- Patterns to identify Juniper devices
    // --------------------------------------------------------/
    private static Pattern juniper_ConfigPattern = Pattern.compile("^[\t\\s]*root-authentication[\t\\s]*.*");
    private static Pattern juniper_ConfigPattern1 = Pattern.compile(".*[jJ]uniper Networks.*");
    private static Pattern juniper_VersionPattern1 = Pattern.compile("^.*JUNOS Base .*");
    private static Pattern juniperVersion_ShowVersionPattern1 = Pattern
            .compile("^.*JUNOS Routing Software Suite\\s+(.*)");
    // Patterns to identify NXOS
    // devices---------------------------------------------------------------------------------------------------------------------------------------------------------------/

    private static Pattern nxosConfigPattern1 = Pattern.compile("^[ \t]*interface cmp-mgmt.*$");
    private static Pattern nxosConfigPattern2 = Pattern.compile("^[ \t]*role name.*$");
    private static Pattern nxosVersion_ShowVersionPattern3 = Pattern.compile("^.*kickstart:.*version(.*).*");
    // Some NXOS configurations dont have cpm-mgmt or role name patterns. But they have username .... role network-admin
    private static Pattern nxosConfigPattern3 = Pattern.compile("^[ \t]*username .* role network-admin.*$");
    private static Pattern nxosConfigPattern4 = Pattern.compile("^[ \t]*username .* role vdc-admin.*$");
    private static Pattern nxosConfigPattern5 = Pattern.compile("^feature\\s+(telnet|bgp|udld|lacp|dhcp)");
    private static Pattern nxosConfigPattern6 = Pattern.compile("^boot\\s+kickstart\\s+bootflash.*");
    private static Pattern nxosConfigPattern7 = Pattern.compile("^vdc.*");
    private static Pattern nxosHostName_VersionPattern = Pattern.compile("^[ \t]*Device name:[ \t]+(.*)$");

    private static Pattern nxosVersion_ShowVersionPattern = Pattern
            .compile("[ \t]*system:[ \t]+version\\s+(\\S+).*");
    private static Pattern nxosVersion_ShowVersionPattern2 = Pattern
            .compile("^[\\s]*NXOS:[\\s]*version\\s+(\\S+).*");

    private static Pattern nxosVersionPattern1 = Pattern.compile("^Cisco Nexus Operating System.*");

    // Patterns to identify WLC devices
    // -------------------------------------------------------------------------------------------------------------------------------------------------------------------//

    private static Pattern wlcConfigPattern1 = Pattern.compile("^[ \t]*System Inventory.*");
    private static Pattern wlcConfigPattern2 = Pattern.compile("^[ \t]*.*WLAN Controller.*");
    private static Pattern wlcConfigPattern3 = Pattern.compile("^[ \t]*.*mgmtuser[ \t]+add.*");
    private static Pattern wlcConfigPattern4 = Pattern.compile("^[ \t]*.*wlan[ \t]+enable.*");
    private static Pattern wlcConfigPattern5 = Pattern.compile("^Web\\s+Mode\\.*");
    private static Pattern wlcConfigPattern6 = Pattern.compile("^Fast\\s+SSID\\s+Change\\s+\\.*");
    private static Pattern wlcConfigPattern7 = Pattern.compile("^Apple\\s+Talk\\s+\\.*");
    private static Pattern WLCHostName_ConfigPattern = Pattern.compile("System Name\\.+[ \t]+(.*)");
    private static Pattern WLCHostName_ConfigPattern1 = Pattern.compile("^[ \t]*sysname[ \t]+(.*)");
    private static Pattern WLCVersion_Pattern = Pattern.compile("Product Version\\.*[ \t]+(.*)");
    // --------------------------------- Patterns to identify IPS devices
    // ------------------------------------------------------------------>

    private static Pattern ipsVersion_ShowVersionPattern = Pattern
            .compile("^Cisco Intrusion Prevention System, Version (.*)");

    private static Pattern ips_ConfigPattern1 = Pattern.compile("^virtual-sensor.*");
    private static Pattern ips_ConfigPattern2 = Pattern.compile(".*Signature Update.*");

    // ----------------------------------- Patterns to identify ASA devices
    // ------------------------------------------------------->

    private static Pattern ASAVersion_ConfigPattern = Pattern.compile("^.*ASA Version (.*)");
    private static Pattern asaVersion_ShowVersionPattern1 = Pattern.compile("^Cisco ASA.* Version (.*)");
    private static Pattern asaVersion_ShowVersionPattern2 = Pattern
            .compile("^Cisco Adaptive Security Appliance.* Version (.*)");

    // ----------------------------- Patterns to identify FWSM devices
    // --------------------------------------------------------->
    private static Pattern fwsmVersionPattern = Pattern.compile("^[ \t]*This FWSM has a.*");
    private static Pattern FWSMVersion_ConfigPattern = Pattern.compile("^FWSM Version (.*)");
    private static Pattern FWSMVersion_ShowVersionPattern = Pattern.compile("^.*FWSM Firewall Version (.*)");
    // ------------------------ Patterns to identify MDS devices
    // ---------------------------------------------------------->

    // Added config and version patterns for MDS devices

    private static Pattern mds_versionPattern1 = Pattern.compile("^Cisco Strorage Area.*");
    private static Pattern mds_versionPattern2 = Pattern.compile("^[ \t]*system:[ \t]*version (.*)");
    private static Pattern mdshostname_versionPattern3 = Pattern.compile("^(.*)[ \t]*kernel uptime.*");

    private static Pattern mds_configPattern2 = Pattern.compile("^kernel core target.*");
    private static Pattern mds_configPattern3 = Pattern.compile("^kernel core limit.*");

    // ---------------------------------------------------------------------------------------------------------------------------->
    private static Pattern bannerStartPattern = Pattern.compile("^[\",]*banner .*\\^[Cc].*");
    private static Pattern bannerStartPattern1 = Pattern.compile("^[\",]*banner .*");
    private static Pattern bannerSameLinePattern = Pattern.compile("^.*\\^[Cc].*\\^[Cc].*");
    private static Pattern bannerEndPattern = Pattern.compile("^.*\\^[Cc]");

    // Note: Show tech gathered from Cisco Works contains " and , chars before and after the command.
    private static Pattern showTechCommandPattern = Pattern.compile("^[\",]*[-*]+ (.*[a-zA-Z0-9]{1,}.*) [-*]+.*$");
    private static Pattern nxosshowTechCommandPattern = Pattern.compile("^[\",]*`(.*[a-zA-Z0-9]{1,}.*)`.*$");
    private static Pattern showTechStartingPattern = Pattern
            .compile("^.*#?[sS][hH][oO]?[wW]?[ \t]+[Tt][Ee][Cc]?[Hh]?.*");
    private static Pattern nxosShowTechStartingPattern = Pattern.compile("^.*---- show tech-support ----.*");
    private static Pattern ipAddrFromShowTech = Pattern
            .compile("^[\",]*Report for ([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+) .*$");
    private static Pattern ipsshowTechCommandPattern = Pattern.compile("^Output from (.*)");
    // BUG: 4528
    private static Pattern ipAddrFromFileName = Pattern.compile("^\\D*([0-9]+\\.[0-9]+\\.[0-9+]\\.[0-9]+).*$");

    private static final Pattern[] shFlashPatterns = new Pattern[] {
            Pattern.compile("(.*) bytes of processor board System flash.*") };

    private static final Pattern[] shFileSysPatterns = new Pattern[] {
            Pattern.compile(".*\\*[ \t][ \t]*([0-9]+)[ \t].*flash:.*") };

    private static Charset charset = Charset.forName("UTF-8");

    private static final Pattern[] verFlashPatterns = new Pattern[] {
            Pattern.compile("(.*) bytes of flash-simulated non-volatile configuration memor.*"),
            Pattern.compile("(.*) bytes of processor board System flash.*"),
            Pattern.compile("(.*) bytes of processor board Boot flash.*"),
            Pattern.compile("(.*) bytes of flash on board.*"), Pattern.compile("(.*) bytes of ATA CompactFlash.*"),
            Pattern.compile("(.*) bytes of Flash internal SIMM.*") };

    public static Map<String /* command */, Map<String /* PCB Attributes */, String[]/* Applicable OS Names */>> datasetMap;

    static {
        datasetMap = new HashMap<String, Map<String, String[]>>();
        HashMap<String, String[]> attrs = new HashMap<String, String[]>();
        attrs.put("showInterfaces", null);
        attrs.put("DeviceIntfStats", null);
        datasetMap.put("show interfaces", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("showInterfaces", null);
        attrs.put("DeviceIntfStats", null);
        attrs.put("DevicePixInterface", new String[] { "PIX", "ASA" });
        datasetMap.put("show interface", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("showInventory", null);
        datasetMap.put("show inventory", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("showDiag", null);
        datasetMap.put("show diag", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("PixMemory", new String[] { "PIX", "ASA" });
        datasetMap.put("show memory", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("PixConnCount", new String[] { "PIX", "ASA" });
        datasetMap.put("show conn count", attrs);

        attrs = new HashMap<String, String[]>();
        attrs.put("DeviceNeighbors", null);
        datasetMap.put("show cdp neighbors detail", attrs);

    }

    private static class FileInfo {
        String ostype;
        ZIPFileType fileType;
        String hostName;
        String version;
        String entryName;
    }

    private HashMap<String, String> showVerFileMap = new HashMap<String, String>();
    private HashMap<String/* deviceName */, String/* tmpFile */> showVerMap = new HashMap<String, String>();

    private HashMap<String, String> showTechFileMap = new HashMap<String, String>();
    private HashMap<String, HashMap<String, String>> cmdOutputMap = new HashMap<String, HashMap<String, String>>();

    private HashMap<String, String> runConfigFileMap = new HashMap<String, String>();
    private HashMap<String, String> runConfigMap = new HashMap<String, String>();

    private HashMap<String, String> osTypeMap = new HashMap<String, String>();
    private HashMap<String, String> versionNumberMap = new HashMap<String, String>();
    private HashMap<String, String> ipAddressMap = new HashMap<String, String>();

    private HashMap<String, HashSet<String>> dupVersionsFileMap = new HashMap<String, HashSet<String>>();
    private HashMap<String, HashSet<String>> dupConfigsFileMap = new HashMap<String, HashSet<String>>();

    private HashMap<String, FileInfo> versionFileInfoMap = new HashMap<String, FileInfo>();
    private HashMap<String, FileInfo> configFileInfoMap = new HashMap<String, FileInfo>();

    private LinkedHashMap<String/* fileName */, ZIPFileResult> fileResultMap = new LinkedHashMap<String, ZIPFileResult>();
    private int numEntries = 0;
    private int currentEntryIdx = 0;
    private String currentEntryName = null;
    private String fileName = "";

    private String errMsg = null;
    private String warnMsg = null;
    private ZIPProcessorProgressListener progressIf = null;
    private File zipFile = null;
    private boolean inProgress = false;
    private boolean isCancelled = false;

    private File tmpRoot = null;

    private boolean isIOSXRtechfile = false;

    private int customerId = -1;

    public int getCustomerId() {
        return customerId;
    }

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    private ZIPProcessor(String name) {
        this.fileName = name;
    }

    public LinkedHashMap<String, ZIPFileResult> getFileResultMap() {
        return fileResultMap;
    }

    public static ZIPProcessor open(File zipFile, int custId) {
        return open(zipFile, null, custId);
    }

    public static ZIPProcessor openShowTechFile(final File shTechFile) {
        ZIPProcessor zipProcessor = new ZIPProcessor(shTechFile.getName());
        zipProcessor.inProgress = true;
        zipProcessor.zipFile = shTechFile;
        InputStream inStream = null;
        try {
            inStream = new FileInputStream(shTechFile);
        } catch (Exception ex) {
            logger.error("Unable to open file: " + shTechFile + " for reading", ex);
            zipProcessor.errMsg = "Unable to open file: " + shTechFile + " for reading";
            return zipProcessor;
        } finally {

            try {
                if (inStream != null) {
                    inStream.close();
                }

            } catch (Exception ex) {
            }
        }
        ZIPFileType fileType = ZIPFileType.UNKNOWN;
        try {
            // fileType = zipProcessor.processZipEntry(inStream, shTechFile.getName());
            zipProcessor.processShowTechFile(shTechFile.getName(), false, new InputStreamGetter() {

                @Override
                public InputStream getInputStream() throws IOException {
                    return new FileInputStream(shTechFile);
                }
            }, null);
            ZIPFileResult fileResult = zipProcessor.fileResultMap.get(shTechFile.getName());
            if (fileResult != null) {
                fileType = fileResult.fileType;
            }
        } catch (IOException e) {
            logger.error("Unable to process zip file: " + shTechFile, e);
            zipProcessor.errMsg = "Unable to process zip file: " + shTechFile;
            return zipProcessor;
        }
        if (fileType != ZIPFileType.SHOW_TECH) {
            logger.debug("Passed file: " + shTechFile + " is not a valid show tech file");
            zipProcessor.errMsg = "Passed file: " + shTechFile + " is not a valid show tech file";
            return zipProcessor;
        }
        return zipProcessor;
    }

    public static ZIPProcessor open(File zipFile, ZIPProcessorProgressListener progressIf, int custId) {
        ZIPProcessor zipProcessor = new ZIPProcessor(zipFile.getName());
        zipProcessor.inProgress = true;
        zipProcessor.zipFile = zipFile;
        zipProcessor.progressIf = progressIf;
        zipProcessor.setCustomerId(custId);
        if (progressIf != null) {
            zipProcessor.start();
        } else {
            zipProcessor.process(true);
        }
        return zipProcessor;
    }

    public void cacelProcessing() {
        isCancelled = true;
    }

    public boolean isCancelledProcessing() {
        return isCancelled;
    }

    public boolean isCompleted() {
        return !inProgress;
    }

    public int percentCompleted() {
        if (numEntries == 0) {
            return 100;
        }
        return (currentEntryIdx * 100) / numEntries;
    }

    public String getFileName() {
        return fileName;
    }

    public int getCurrentEntryIdx() {
        return currentEntryIdx;
    }

    public String getCurrentEntryName() {
        return currentEntryName;
    }

    public int getNumEntries() {
        return numEntries;
    }

    public String[] getDeviceNames() {
        if (runConfigMap.isEmpty()) {
            return null;
        }
        return runConfigMap.keySet().toArray(new String[runConfigMap.size()]);
    }

    public String getErrorMessage() {
        return errMsg;
    }

    public String getWarningMessage() {
        return warnMsg;
    }

    public String getIpAddress(String dname) {
        if (ipAddressMap == null) {
            return null;
        }
        return ipAddressMap.get(dname);
    }

    public String[] getCommands(String dname) {
        if (cmdOutputMap == null) {
            return new String[0];
        }
        HashMap<String, String> cmds = cmdOutputMap.get(dname);
        if (cmds != null) {
            return cmds.keySet().toArray(new String[cmds.size()]);
        }
        return new String[0];
    }

    public String getCommandOutput(String dname, String cmd) {
        if (cmdOutputMap == null) {
            return null;
        }
        HashMap<String, String> cmds = cmdOutputMap.get(dname);
        if (cmds != null) {
            String fName = cmds.get(cmd);
            if (fName != null) {
                try {
                    File f = new File(fName);
                    return readFileContents(new FileInputStream(f));
                } catch (Exception ex) {
                    return null;
                }
            }
        }
        return null;
    }

    public String getConfiguration(String dname) {
        String fName = runConfigMap.get(dname);
        if (fName != null) {
            try {
                File f = new File(fName);
                return readFileContents(new FileInputStream(f));
            } catch (Exception ex) {
                return null;
            }
        }
        return null;
    }

    public String getConfigFileName(String dname) {
        return runConfigFileMap.get(dname);
    }

    public String getShowVersion(String dname) {
        String fName = showVerMap.get(dname);
        if (fName != null) {
            try {
                File f = new File(fName);
                return readFileContents(new FileInputStream(f));
            } catch (Exception ex) {
                return null;
            }
        }
        return null;
    }

    public String getShowTechFileName(String dname) {
        return showTechFileMap.get(dname);
    }

    public String getShowVersionFileName(String dname) {
        return showVerFileMap.get(dname);
    }

    public String getOsType(String dname) {
        if (osTypeMap.containsKey(dname)) {
            return osTypeMap.get(dname);
        } else {
            return "IOS";
        }
    }

    public String getVersion(String dname) {
        return versionNumberMap.get(dname);
    }

    @Override
    public void run() {
        process(false);
    }

    public void process(boolean blocking) {
        tmpRoot = new File("TEMP" + File.separator + "ZIP_TMP_" + System.nanoTime());
        tmpRoot.mkdirs();
        long start = System.currentTimeMillis();
        if (!zipFile.exists()) {
            errMsg = "File " + fileName + " does not exist";
            setCompleted();
            return;
        }
        if (!zipFile.canRead()) {
            errMsg = "Unable to read the contents of the file " + fileName;
            setCompleted();
            return;
        }
        try {
            ZipFile inZip = new ZipFile(zipFile);
            numEntries = inZip.size();

            Enumeration<? extends ZipEntry> entryEnumeration = inZip.entries();
            if (numEntries == 0) {
                errMsg = "Empty ZIP file.";
                setCompleted();
                return;
            }
            while (entryEnumeration.hasMoreElements()) {
                ZipEntry entry = entryEnumeration.nextElement();
                currentEntryName = entry.getName();
                if (entry.isDirectory()) {
                    if (numEntries > 1) {
                        numEntries--;
                    }
                    continue;
                }
                currentEntryIdx++;
                if (currentEntryIdx % 100 == 0) {
                    System.gc();
                    NCCMObserver.getInstance().logMemoryUsage(
                            "After handling " + currentEntryIdx + " files in Zip Processor, Memory Usage");
                }
                InputStream ipStream = inZip.getInputStream(entry);
                String fileName = entry.getName();
                System.err.println("Processing file: " + fileName);

                String line = null;
                try {
                    BufferedReader br = new BufferedReader(new InputStreamReader(ipStream));
                    line = br.readLine();
                    CharsetDetector detector = new CharsetDetector();
                    if (entry.getSize() == 0) {
                        logger.error("No Contents found in the file");
                        continue;
                    } else {
                        detector.setText(line.getBytes());
                        charset = Charset.forName(detector.detect().getName());
                    }
                } catch (Exception ex) {
                    logger.error("Error while getting the charset encoding of the file");
                } finally {
                    try {
                        ipStream.close();
                    } catch (Exception e) {
                        logger.error("Exception while closing the stream");
                    }
                }
                ipStream = inZip.getInputStream(entry);

                processZipEntry(ipStream, fileName, entry, inZip);
                if (progressIf != null) {
                    progressIf.updateProgress(currentEntryName, currentEntryIdx, numEntries);
                }
                if (fileResultMap.get(fileName) == null) {
                    ZIPFileResult fr = new ZIPFileResult(fileName);
                    fr.fileType = ZIPFileType.UNKNOWN;
                    fr.msg = "Unable to process the file.";
                    fileResultMap.put(fileName, fr);
                }
                try {
                    ipStream.close();
                } catch (Exception ex) {
                    logger.warn("Unable to close the inputstream for entry " + entry.getName(), ex);
                    ex.printStackTrace();
                }
                if (isCancelled) {
                    break;
                }
                if (!blocking) {
                    Thread.sleep(100 /* msec */);
                }
                if (isCancelled) {
                    break;
                }
            }
            if (!isCancelled) {
                processCatOsVersionFiles(inZip);
                processFileResult();
            }
            inZip.close();
        } catch (ZipException e) {
            errMsg = "File is not a valid Zip file";
            logger.error("Exception while processing ZipFile: " + fileName, e);
        } catch (IOException e) {
            errMsg = "Unable to parse Zip file ";
            logger.error("IOException while processing ZipFile: " + fileName, e);
        } catch (InterruptedException e) {
            errMsg = "Zip processing Interrupted internally.";
            logger.error("Interrupted while processing ZipFile: " + fileName, e);
        } catch (Exception e) {
            errMsg = "Exception while processing zip file.";
            logger.error("Exception while processing ZipFile: " + fileName, e);
        }

        logger.debug("Done with : " + numEntries + " in " + (System.currentTimeMillis() - start) + " msecs");
        String[] devNames = getDeviceNames();
        if (devNames == null || devNames.length == 0) {
            addWarning("No valid devices found in the specified Zip file.");
        }
        setCompleted();
        return;
    }

    private void processFileResult() {
        for (String dname : showVerFileMap.keySet()) {
            if (getConfiguration(dname) == null) {
                String fileName = showVerFileMap.get(dname);
                ZIPFileResult fileResult = fileResultMap.get(fileName);
                if (fileResult == null) {
                    fileResult = new ZIPFileResult(fileName);
                    fileResult.fileType = ZIPFileType.VERSION;
                    fileResultMap.put(fileName, fileResult);
                }
                if (fileResult.msg == null) {
                    fileResult.msg = "";
                }
                fileResult.msg += " No corresponding configuration file found. Device not added.";
            }
        }
    }

    private void processCatOsVersionFiles(ZipFile inZip) {
        // CatOS show version files dont have hostnames in them.
        // Hence, we have to use some heuristics to marry the version files to corresponding config files.
        Map<String/* fileName */, Set<String>/* set of matching hostnames */> file2HostNameMap = new HashMap<String, Set<String>>();
        Map<String/* hostName */, Set<String>/* set of matching filenames */> hostName2fileMap = new HashMap<String, Set<String>>();
        // Step 1: Match the os version number in show version to corresponding version number in config.
        for (String fileName : versionFileInfoMap.keySet()) {
            FileInfo fileInfo = versionFileInfoMap.get(fileName);
            if ((fileInfo == null) || (fileInfo.ostype == null) || (!fileInfo.ostype.equals("CATOS"))) {
                continue;
            }
            String osVersion = fileInfo.version;
            for (String f : configFileInfoMap.keySet()) {
                FileInfo cfgFileInfo = configFileInfoMap.get(f);
                if ((cfgFileInfo == null) || (cfgFileInfo.ostype == null) || (!cfgFileInfo.ostype.equals("CATOS"))
                        || (cfgFileInfo.version == null)) {
                    continue;
                }
                if (cfgFileInfo.version.equals(osVersion)) {
                    String hostName = cfgFileInfo.hostName;
                    Set<String> hnSet = file2HostNameMap.get(fileName);
                    if (hnSet == null) {
                        hnSet = new HashSet<String>();
                        file2HostNameMap.put(fileName, hnSet);
                    }
                    hnSet.add(hostName);

                    Set<String> fnSet = hostName2fileMap.get(hostName);
                    if (fnSet == null) {
                        fnSet = new HashSet<String>();
                        hostName2fileMap.put(hostName, fnSet);
                    }
                    fnSet.add(fileName);
                }
            }
        }

        // Step 2: Once the filename 2 hostname is uniquely resolved,
        // That gets the higher priority. Remove that hostname from other lists.
        Map<String/* hostName */, String /* FileName */> uniqHn2fnMap = new HashMap<String, String>();
        trimWithHostAndFileNames(file2HostNameMap, hostName2fileMap);
        Map<String/* hostName */, String /* FileName */> newUniqHn2fnMap = getUniqMap(uniqHn2fnMap,
                file2HostNameMap, hostName2fileMap);
        while (!newUniqHn2fnMap.isEmpty()) {
            processUniqMaps(newUniqHn2fnMap, file2HostNameMap, hostName2fileMap);
            trimWithHostAndFileNames(file2HostNameMap, hostName2fileMap);
            newUniqHn2fnMap = getUniqMap(uniqHn2fnMap, file2HostNameMap, hostName2fileMap);
            for (String hn : newUniqHn2fnMap.keySet()) {
                uniqHn2fnMap.put(hn, newUniqHn2fnMap.get(hn));
            }
        }

        for (String fileName : file2HostNameMap.keySet()) {
            Set<String> hnSet = file2HostNameMap.get(fileName);
            if (hnSet.size() == 1) {
                String hostName = hnSet.iterator().next();
                Set<String> fnSet = hostName2fileMap.get(hostName);
                if (fnSet.size() == 1) {
                    String fn = fnSet.iterator().next();
                    if (fn.equals(fileName)) {
                        FileInfo fileInfo = versionFileInfoMap.get(fileName);
                        fileInfo.hostName = hostName;
                        ZIPFileResult fileResult = fileResultMap.get(fileName);
                        if (fileResult == null) {
                            fileResult = new ZIPFileResult(fileName);
                            fileResultMap.put(fileName, fileResult);
                            fileResult.fileType = ZIPFileType.VERSION;
                            fileResult.osType = "CATOS";
                        }
                        if (fileResult.msg == null) {
                            fileResult.msg = "";
                        }
                        fileResult.msg += " Setting hostname as " + hostName + " version match.";
                        processVersionFile(fileName, fileInfo, null, inZip);
                    }
                }
            }
        }
    }

    private void processUniqMaps(Map<String, String> newUniqHn2fnMap, Map<String, Set<String>> file2HostNameMap,
            Map<String, Set<String>> hostName2fileMap) {
        for (String hostName : newUniqHn2fnMap.keySet()) {
            String fileName = newUniqHn2fnMap.get(hostName);
            for (String fn : file2HostNameMap.keySet()) {
                if (fn.equals(fileName)) {
                    continue;
                }
                Set<String> hnSet = file2HostNameMap.get(fn);
                hnSet.remove(hostName);
            }
            for (String hn : hostName2fileMap.keySet()) {
                if (hn.equals(hostName)) {
                    continue;
                }
                Set<String> fnSet = hostName2fileMap.get(hn);
                fnSet.remove(fileName);
            }
        }
    }

    private void trimWithHostAndFileNames(Map<String, Set<String>> file2HostNameMap,
            Map<String, Set<String>> hostName2fileMap) {
        for (String fileName : file2HostNameMap.keySet()) {
            Set<String> hnSet = file2HostNameMap.get(fileName);
            if (hnSet.size() > 1) {
                Set<String> matchingHnSet = new HashSet<String>();
                for (String hn : hnSet) {
                    if (fileName.contains(hn)) {
                        matchingHnSet.add(hn);
                    }
                }
                if (matchingHnSet.size() == 1) {
                    String matchingHn = matchingHnSet.iterator().next();
                    hnSet.clear();
                    hnSet.add(matchingHn);
                }
            }
        }
        for (String hostName : hostName2fileMap.keySet()) {
            Set<String> fnSet = hostName2fileMap.get(hostName);
            if (fnSet.size() > 1) {
                Set<String> matchingFnSet = new HashSet<String>();
                for (String fn : fnSet) {
                    if (fn.contains(hostName)) {
                        matchingFnSet.add(fn);
                    }
                }
                if (matchingFnSet.size() == 1) {
                    String matchingFn = matchingFnSet.iterator().next();
                    fnSet.clear();
                    fnSet.add(matchingFn);
                }
            }
        }

    }

    private Map<String, String> getUniqMap(Map<String, String> uniqHn2fnMap,
            Map<String, Set<String>> file2HostNameMap, Map<String, Set<String>> hostName2fileMap) {
        Map<String, String> newMap = new HashMap<String, String>();
        for (String fileName : file2HostNameMap.keySet()) {
            Set<String> hnSet = file2HostNameMap.get(fileName);
            if (hnSet.size() == 1) {
                String hostName = hnSet.iterator().next();
                Set<String> fnSet = hostName2fileMap.get(hostName);
                if (fnSet == null || fnSet.size() == 1) {
                    if (uniqHn2fnMap.get(hostName) == null) {
                        newMap.put(hostName, fileName);
                    }
                }
            }
        }
        return newMap;
    }

    private void setCompleted() {
        inProgress = false;
        if (progressIf != null) {
            progressIf.processCompleted();
        }

    }

    private void setVersionIfNull(FileInfo fileInfo, String version) {
        if (fileInfo.version != null && fileInfo.version.length() > 0) {
            return;
        }
        Matcher m = validVersionPattern.matcher(version);
        if (m.matches()) {
            version = m.group(1);
            fileInfo.version = version;
        } else {
            logger.warn("Illegal version string: " + version);
        }
    }

    private void setVersion(FileInfo fileInfo, String version) {

        Matcher m = validVersionPattern.matcher(version);
        if (m.matches()) {
            version = m.group(1);
            fileInfo.version = version;
        } else {
            logger.warn("Illegal version string: " + version);
        }
    }

    private void handleVersionLine(FileInfo fileInfo, String line, DSPZipImportData d) {
        Matcher m;
        // Handle Version from show version checks.

        if (d != null) {
            Map<String, Object> map = d.getAttributes();
            Iterator entries = map.entrySet().iterator();
            while (entries.hasNext()) {
                Entry thisEntry = (Entry) entries.next();
                String pattern = thisEntry.getKey().toString();
                m = Pattern.compile(pattern).matcher(line);
                if (m.matches()) {
                    DevProperties prop = (DevProperties) thisEntry.getValue();
                    Map<String, String> prop1 = prop.getProperty();
                    Iterator it = prop1.entrySet().iterator();
                    boolean test = false;
                    while (it.hasNext()) {
                        Entry thisEntry1 = (Entry) it.next();

                        if (thisEntry1.getKey().toString().equals("hostName")) {
                            if (fileInfo.hostName == null) {
                                fileInfo.hostName = m.group(1).trim();
                                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
                            }

                        } else if (thisEntry1.getKey().toString().equals("command")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("showTechCommandPattern")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("showTechStartPattern")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("osType")) {
                            fileInfo.ostype = prop.getProperty("osType");
                        } else if (thisEntry1.getKey().toString().equals("version")) {
                            setVersion(fileInfo, m.group(1).trim());
                        } else if (thisEntry1.getKey().toString().equals("fileType")) {
                            if (prop.getProperty("fileType").equals("Configuration")) {
                                fileInfo.fileType = ZIPFileType.CONFIG;
                            } else if (prop.getProperty("fileType").equals("Version")) {
                                fileInfo.fileType = ZIPFileType.VERSION;
                            }
                        }

                    }
                    if (!test) {
                        return;
                    }

                }

            }

        }

        // -----------To identify IOSXR devices----------------------------------->

        m = iosxrVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IOSXR";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        m = iosVersionPattern1.matcher(line);
        if (m.matches()) {
            if (fileInfo.ostype == null) {
                fileInfo.ostype = "IOS";
            }
            if (fileInfo.fileType == null) {
                fileInfo.fileType = ZIPFileType.VERSION;
            }
            return;
        }

        m = iosVersionPattern2.matcher(line);
        if (m.matches()) {
            if (fileInfo.ostype == null) {
                fileInfo.ostype = "IOS";
            }
            if (fileInfo.fileType == null) {
                fileInfo.fileType = ZIPFileType.VERSION;
            }
            return;
        }

        // To identify Juniper Version File
        m = juniper_VersionPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "JunOS";
            fileInfo.fileType = ZIPFileType.VERSION;
            return;
        }

        m = juniperVersion_ShowVersionPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        // To identify NXOS version Files

        m = nxosVersionPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.VERSION;
            return;
        }

        m = nxosHostName_VersionPattern.matcher(line);
        if (m.matches()) {

            if (fileInfo.hostName == null) {
                fileInfo.hostName = fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }
            fileInfo.ostype = "NXOS";
            return;

        }

        m = nxosVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.fileType = ZIPFileType.VERSION;
            // setVersionIfNull(fileInfo, m.group(1).trim());
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        m = nxosVersion_ShowVersionPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.VERSION;
            fileInfo.version = m.group(1).trim();
            return;
        }

        m = nxosVersion_ShowVersionPattern3.matcher(line);
        if (m.matches()) {

            fileInfo.fileType = ZIPFileType.VERSION;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        // To identify WLC device Version ----------------------------------------------------->

        m = WLCVersion_Pattern.matcher(line);
        if (m.matches()) {
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        // ------------------------- To identify FWSM devices----------------------------------------->
        m = FWSMVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "FWSM";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        m = fwsmVersionPattern.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "FWSM";
            fileInfo.fileType = ZIPFileType.VERSION;
            return;
        }

        // ------------------- To identify MDS devices ---------------------------------------------->
        m = mds_versionPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SAN-OS";
            fileInfo.fileType = ZIPFileType.VERSION;
            return;
        }

        m = mds_versionPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SAN-OS";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        m = mdshostname_versionPattern3.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SAN-OS";
            fileInfo.fileType = ZIPFileType.VERSION;
            fileInfo.hostName = (fileInfo.hostName == null) ? m.group(1).trim() : fileInfo.hostName;
            return;
        }

        // ---------- To Identify IPS Devices ---------------------------------------------------->

        m = ipsVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IPS";
            fileInfo.fileType = ZIPFileType.VERSION;
            fileInfo.version = m.group(1).trim();
            return;
        }

        // --------------To identify ASA Devices --------------------------------------------------->

        m = asaVersion_ShowVersionPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "ASA";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        m = asaVersion_ShowVersionPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "ASA";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        // ----------- To identify PIX devices ------------->
        m = pixVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "PIX";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        // -------------- To identify CATOS devices---------------------------->
        m = catosVersion_ShowVersionPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "CATOS";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }
        // -------------------------To identify ASR5k/STAROS devices------------------------->
        m = asr5kVersion_Pattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "STAROS";
            fileInfo.fileType = ZIPFileType.VERSION;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        // Generic Patterns to get hostname, fileType, Version

        m = generic_versionHostNamePattern1.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_versionHostNamePattern2.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {

                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }
            fileInfo.fileType = ZIPFileType.VERSION;

        }

        m = generic_versionHostNamePattern3.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_versionHostNamePattern4.matcher(line);
        if (m.matches()) {

            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");

        }

        m = generic_versionHostNamePattern5.matcher(line);
        if (m.matches()) {

            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_versionHostNamePattern6.matcher(line);
        if (m.matches()) {

            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_versionHostNamePattern7.matcher(line);
        if (m.matches()) {

            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_versionHostNamePattern8.matcher(line);
        if (m.matches()) {

            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");

        }

    }

    private void handleConfigurationLine(FileInfo fileInfo, String line, DSPZipImportData d) {
        Matcher m;
        // Handle Version from Configuration

        if (d != null) {
            Map<String, Object> map = d.getAttributes();
            Iterator entries = map.entrySet().iterator();
            while (entries.hasNext()) {
                Entry thisEntry = (Entry) entries.next();
                String pattern = thisEntry.getKey().toString();
                m = Pattern.compile(pattern).matcher(line);
                if (m.matches()) {
                    DevProperties prop = (DevProperties) thisEntry.getValue();
                    Map<String, String> prop1 = prop.getProperty();
                    Iterator it = prop1.entrySet().iterator();
                    boolean test = false;
                    while (it.hasNext()) {
                        Entry thisEntry1 = (Entry) it.next();

                        if (thisEntry1.getKey().toString().equals("hostName")) {
                            if (fileInfo.hostName == null) {
                                fileInfo.hostName = m.group(1).trim();
                                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
                            }
                        } else if (thisEntry1.getKey().toString().equals("command")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("showTechCommandPattern")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("showTechStartPattern")) {
                            test = true;
                        } else if (thisEntry1.getKey().toString().equals("osType")) {
                            fileInfo.ostype = prop.getProperty("osType");
                        } else if (thisEntry1.getKey().toString().equals("version")) {
                            setVersion(fileInfo, m.group(1).trim());
                        } else if (thisEntry1.getKey().toString().equals("fileType")) {
                            if (prop.getProperty("fileType").equals("Configuration")) {
                                fileInfo.fileType = ZIPFileType.CONFIG;
                            } else if (prop.getProperty("fileType").equals("Version")) {
                                fileInfo.fileType = ZIPFileType.VERSION;
                            }
                        }
                        System.out.println("Gaurav getting the object" + prop);
                    }
                    if (!test) {
                        return;
                    }

                }

            }

        }

        // -------------To identify IOSXR devices--------------------------------------------->

        m = iosxrConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IOSXR";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }
        m = iosxrConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IOSXR";
            fileInfo.fileType = ZIPFileType.CONFIG;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        // --------- For Identifying Juniper Devices ------------------------------->
        m = juniper_ConfigPattern.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "JunOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = juniper_ConfigPattern1.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "JunOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        // ------------For Identifying NXOS devices
        // --------------------------------------------------------------------------------->

        m = nxosConfigPattern1.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern2.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern3.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern4.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern5.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern6.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = nxosConfigPattern7.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "NXOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        // ---------------- For Identifying WLC devices ------------------------------------------------>

        m = wlcConfigPattern1.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern2.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern3.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern4.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern5.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern6.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = wlcConfigPattern7.matcher(line);
        if (m.matches()) {

            fileInfo.ostype = "WLC";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = WLCHostName_ConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            return;

        }

        m = WLCHostName_ConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            return;
        }

        m = WLCVersion_Pattern.matcher(line);
        if (m.matches()) {
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        // ---------------------- To identify FWSM devices-------------------------------------->
        m = FWSMVersion_ConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "FWSM";
            fileInfo.fileType = ZIPFileType.CONFIG;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }

        // ---------------------To identify MDS devices ------------------------------------->
        m = mds_configPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SAN-OS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = mds_configPattern3.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SAN-OS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        // --------------------- Patterns to idntify IPS devices
        // ------------------------------------------------------------------->

        m = ips_ConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IPS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        m = ips_ConfigPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "IPS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }

        // Patterns to identify ASA devices------------------------------------->

        m = ASAVersion_ConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "ASA";
            fileInfo.fileType = ZIPFileType.CONFIG;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }

        // -- Patterns to identify SCE devices ------------------------------------------->

        m = sceVersion_ConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "SCOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            setVersion(fileInfo, m.group(1).trim());
            return;
        }
        // ----------------- Patterns to identify PIX devices --------------------------------------->
        m = PIXVersion_ConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "PIX";
            fileInfo.fileType = ZIPFileType.CONFIG;
            setVersionIfNull(fileInfo, m.group(1).trim());
            return;
        }
        // -------------------- Patterns to identify CATOS devices----------------------------------------->
        m = catosHostName_ConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "CATOS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            return;
        }

        // -------------------- Patterns to identify ASR5K/STAROS devices----------------------------------------->
        m = asr5k_ConfigPattern1.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "STAROS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }
        m = asr5k_ConfigPattern2.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "STAROS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }
        m = asr5k_ConfigPattern3.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = "STAROS";
            fileInfo.fileType = ZIPFileType.CONFIG;
            return;
        }
        m = asr5kHostName_ConfigPattern.matcher(line);
        if (m.matches()) {
            fileInfo.ostype = (fileInfo.ostype == null) ? "STAROS" : fileInfo.ostype;
            fileInfo.fileType = ZIPFileType.CONFIG;
            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            setVersionIfNull(fileInfo, "14.0"); // As version is not present in config file.
            return;
        }

        // ----------------------- Generic Patterns ----------------------------------------------->

        m = generic_configHostNamePattern2.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {

                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_configHostNamePattern3.matcher(line);
        if (m.matches()) {

            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");

            fileInfo.fileType = ZIPFileType.CONFIG;

        }

        m = generic_configHostNamePattern4.matcher(line);
        if (m.matches()) {

            fileInfo.hostName = m.group(1).trim();
            fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");

        }

        m = generic_configHostNamePattern5.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_configHostNamePattern1.matcher(line);
        if (m.matches()) {
            if (fileInfo.hostName == null) {
                fileInfo.hostName = m.group(1).trim();
                fileInfo.hostName = fileInfo.hostName.replaceAll("\"", "");
            }

        }

        m = generic_configVersionPattern1.matcher(line);
        if (m.matches()) {

            setVersionIfNull(fileInfo, m.group(1).trim());

        }

        m = generic_VersionPattern2.matcher(line);
        if (m.matches()) {

            setVersionIfNull(fileInfo, m.group(1).trim());

        }

        m = generic_configVersionPattern3.matcher(line);
        if (m.matches()) {
            setVersionIfNull(fileInfo, m.group(1).trim());

        }

        m = generic_configVersionPattern4.matcher(line);
        if (m.matches()) {
            setVersionIfNull(fileInfo, m.group(1).trim());

        }

        m = generic_VersionPattern2.matcher(line);
        if (m.matches()) {

            setVersionIfNull(fileInfo, m.group(1).trim());

        }

    }

    private ZIPFileType processZipEntry(InputStream inStream, String fileName, ZipEntry entry, ZipFile inZip)
            throws IOException {
        return processZipEntryInternal(inStream, fileName, false, entry, inZip);
    }

    private ZIPFileType processZipEntryInternal(InputStream inStream, String fileName, boolean ignoreBanner,
            final ZipEntry entry, final ZipFile inZip) throws IOException {
        // logger.debug("" + fileName + "...");
        FileInfo fileInfo = new FileInfo();
        ZIPFileResult fileResult = new ZIPFileResult(fileName);
        long start = System.currentTimeMillis();
        boolean insideBanner = false;
        int linesInsideBanner = 0;

        fileInfo.fileType = ZIPFileType.UNKNOWN;
        String line = null;
        DSPHandler dspHandler = new ZipImportDSPHandler();
        DSPZipImportData data = new DSPZipImportData();

        List<ScriptInfo> sysScripts = DeviceScriptManagerImpl.getInstance()
                .getSystemDefinedZipPackages(PackageType.ZipInventory, "System");
        dspHandler.handlePackages(data, sysScripts);

        List<ScriptInfo> userScripts = DeviceScriptManagerImpl.getInstance()
                .getUserDefinedZipPackages(PackageType.ZipInventory, customerId, "User");
        dspHandler.handlePackages(data, userScripts);

        BufferedReader br = new BufferedReader(new InputStreamReader(inStream, charset));
        int lineno = 0;
        while ((line = br.readLine()) != null) {
            lineno++;
            if (line.length() >= 35000) // CSCup58209 - Changed from 30000 to 35000 as some lines were very lengthy.
            {
                fileResult.fileType = ZIPFileType.UNKNOWN;
                fileResult.msg = "Not an ASCII file.";
                this.errMsg = "Length of one or more lines is greater than 35K";
                fileResultMap.put(fileName, fileResult);
                // Most probably, not an ascii file
                logger.debug("\tNot an ASCII file. Length of one or more lines is greater than 35K. Done in "
                        + (System.currentTimeMillis() - start) + " msecs");

                return ZIPFileType.UNKNOWN;
            }

            if (!ignoreBanner) {
                // note: If the configuration is
                // pulled using tftp copy, then the banner contains some unprintable characters (ETX=003)
                // instead of ^C.
                if (insideBanner) {
                    if (bannerEndPattern.matcher(line).matches()) {
                        insideBanner = false;
                    } else {
                        int idx = line.indexOf(3);
                        if (idx >= 0) {
                            insideBanner = false;
                        }
                    }
                    linesInsideBanner++;
                    continue;
                } else {
                    if (bannerStartPattern.matcher(line).matches()) {
                        insideBanner = true;
                        if (bannerSameLinePattern.matcher(line).matches()) {
                            insideBanner = false;
                        }
                    } else if (bannerStartPattern1.matcher(line).matches()) {
                        int idx1 = line.indexOf(3);
                        if (idx1 >= 0) {
                            insideBanner = true;
                            int idx2 = line.lastIndexOf(3);
                            if (idx2 > idx1) {
                                insideBanner = false;
                            }
                        }
                        continue;
                    }
                }
            }

            if (data != null) {
                Map<String, Object> map = data.getAttributes();
                Iterator entries = map.entrySet().iterator();
                while (entries.hasNext()) {
                    Matcher m;

                    Entry thisEntry = (Entry) entries.next();
                    String pattern = thisEntry.getKey().toString();
                    m = Pattern.compile(pattern).matcher(line);
                    if (m.matches()) {
                        DevProperties prop = (DevProperties) thisEntry.getValue();
                        Map<String, String> prop1 = prop.getProperty();
                        Iterator it = prop1.entrySet().iterator();
                        while (it.hasNext()) {
                            Entry thisEntry1 = (Entry) it.next();

                            if (thisEntry1.getKey().toString().equals("fileType")) {
                                if (prop.getProperty("fileType").equals("ShowTech")) {
                                    fileInfo.fileType = ZIPFileType.SHOW_TECH;

                                }

                            }

                        }

                    }
                }
            }

            if (fileInfo.fileType == ZIPFileType.SHOW_TECH) {
                break;
            }

            Matcher m = showTechCommandPattern.matcher(line);
            boolean matched = m.matches();
            if (matched) {
                String cmd = m.group(1);
                String cmdLC = cmd.toLowerCase();
                if (cmdLC.contains("show version") || cmdLC.contains("show running-")
                        || cmdLC.contains("show config")) {
                    fileInfo.fileType = ZIPFileType.SHOW_TECH;
                    // logger.debug("Found out to be show tech file.");
                    // If we figure out it is a Show tech output, that overrides everything.
                    break;
                }
            }
            m = nxosshowTechCommandPattern.matcher(line);
            matched = m.matches();
            if (matched) {
                String cmd = m.group(1);
                String cmdLC = cmd.toLowerCase();
                if (cmdLC.contains("show version") || cmdLC.contains("show running-")
                        || cmdLC.contains("show config")) {
                    fileInfo.fileType = ZIPFileType.SHOW_TECH;
                    // If we figure out it is a Show tech output, that overrides everything.
                    break;
                }
            }
            m = ipsshowTechCommandPattern.matcher(line);
            matched = m.matches();
            if (matched) {
                String cmd = m.group(1);
                String cmdLC = cmd.toLowerCase();
                if (cmdLC.contains("show version") || cmdLC.contains("show configuration")) {
                    fileInfo.fileType = ZIPFileType.SHOW_TECH;
                    // If we figure out it is a Show tech output, that overrides everything.
                    break;
                }
            }

            handleConfigurationLine(fileInfo, line, data);

            handleVersionLine(fileInfo, line, data);

        }
        if (!ignoreBanner) {
            if (insideBanner) {
                // Something is wrong! We never found the end of a banner. Something wrong with
                // the end-of-banner detection code. Let us try it one more time, this time
                // let us ignore the banner.. just in case.
                logger.warn("File: " + fileName + " Unable to find end of banner commands. "
                        + "Running once more and ignoring banner commands now.");
                try {
                    inStream.close();
                } catch (Exception ex) {
                }
                inStream = inZip.getInputStream(entry);
                return processZipEntryInternal(inStream, fileName, true, entry, inZip);
            } else {
                if (lineno > 0) {
                    int percentLinesInsideBanner = (linesInsideBanner * 100) / lineno;
                    if (percentLinesInsideBanner > 85) {
                        // Something wrong. Somehow, looks like 85% of the file is under banner commands!
                        // Let us try it one more time, this time
                        // let us ignore the banner.. just in case.
                        logger.warn("File: " + fileName + " major portion of the file: (" + percentLinesInsideBanner
                                + "%) "
                                + "is found to be inside banner commands. Trying again by ignoring the banners.");
                        try {
                            inStream.close();
                        } catch (Exception ex) {
                        }
                        inStream = inZip.getInputStream(entry);
                        return processZipEntryInternal(inStream, fileName, true, entry, inZip);
                    }
                }
            }
        }
        try {
            inStream.close();
        } catch (Exception ex) {

        }
        switch (fileInfo.fileType) {
        case CONFIG: {
            if (fileInfo.ostype != null) {
                if (fileInfo.ostype.equals("CATOS")) {
                    // BUG: 0005383
                    if (fileInfo.hostName == null || fileInfo.hostName.trim().length() == 0) {
                        fileInfo.hostName = "Switch";
                    }
                    // END BUG: 0005383
                    configFileInfoMap.put(fileName, fileInfo);
                }
                if (fileInfo.ostype.equals("FWSM")) {
                    if (fileInfo.hostName == null || fileInfo.hostName.trim().length() == 0) {
                        fileInfo.hostName = "FWSM";
                    }
                }
                if (fileInfo.ostype.equals("PIX")) {
                    if (fileInfo.hostName == null || fileInfo.hostName.trim().length() == 0) {
                        fileInfo.hostName = "PIX";
                    }
                }
                if (fileInfo.ostype.equals("ASA")) {
                    if (fileInfo.hostName == null || fileInfo.hostName.trim().length() == 0) {
                        fileInfo.hostName = "ASA";
                    }
                }
                if (fileInfo.ostype.equals("WLC")) {
                    if (fileInfo.hostName == null || fileInfo.hostName.trim().length() == 0) {
                        fileInfo.hostName = "Cisco Controller";
                    }
                }
            }
            processConiguration(fileName, fileInfo, entry, inZip);
            logger.debug("\t" + fileInfo.ostype + " Configuration. Done in " + (System.currentTimeMillis() - start)
                    + " msecs");
            return fileInfo.fileType;
        }
        case VERSION: {
            fileInfo.entryName = entry.getName();
            if ((fileInfo.ostype != null) && (fileInfo.ostype.equals("CATOS"))) {
                versionFileInfoMap.put(fileName, fileInfo);
            }
            processVersionFile(fileName, fileInfo, entry, inZip);
            logger.debug("\t" + fileInfo.ostype + " Version. Done in " + (System.currentTimeMillis() - start)
                    + " msecs");
            return fileInfo.fileType;
        }
        case SHOW_TECH: {
            try {
                InputStreamGetter isGetter = new InputStreamGetter() {

                    @Override
                    public InputStream getInputStream() throws IOException {
                        return inZip.getInputStream(entry);
                    }
                };
                processShowTechFile(fileName, ignoreBanner, isGetter, data);
            } catch (Exception ex) {
                logger.error("Exception while processing show tech file: " + fileName, ex);
                fileResult.fileType = ZIPFileType.UNKNOWN;
                fileResult.msg = "Exception while processing file:" + ex.getMessage();
                fileResultMap.put(fileName, fileResult);
                return fileInfo.fileType;
            }
            // logger.debug("\t show tech. Done in " + (System.currentTimeMillis() - start) + " msecs");
            return fileInfo.fileType;
        }
        case UNKNOWN:
        }
        fileResult.fileType = ZIPFileType.UNKNOWN;
        fileResult.msg = "Not a valid file.";
        fileResultMap.put(fileName, fileResult);

        logger.debug("\t Invalid file. Done in " + (System.currentTimeMillis() - start) + " msecs");
        return fileInfo.fileType;
    }

    private boolean stopParsing(FileInfo f) {
        boolean osType = false;
        boolean hostName = false;
        boolean version = false;
        boolean fileType = false;

        if (f.fileType != ZIPFileType.UNKNOWN) {
            fileType = true;
        }
        if (f.hostName != null) {
            hostName = true;
        }

        if (f.version != null) {
            version = true;
        }

        if (f.ostype != null) {
            osType = true;
        }
        return (fileType && hostName && version && osType);

    }

    private void processShowTechFile(String fileName, boolean ignoreBanner, InputStreamGetter isGetter,
            DSPZipImportData d) throws IOException {
        String cmd = "unknown";
        boolean cmdNeeded = true;
        StringBuffer cmdOutput = new StringBuffer();
        HashMap<String /* cmd */, byte[] /* response */> cmdOutputs = new HashMap<String, byte[]>();
        String ipAddress = null;
        String newIpAddress = null;
        boolean isnxos = false;
        boolean firstcmd = true;

        // System.err.println("*** Processing " + contents.size() + " lines");
        int lineno = 0;
        boolean insideBanner = false;
        int linesInsideBanner = 0;
        InputStream is = null;

        try {
            is = isGetter.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line = null;
            while ((line = reader.readLine()) != null) {
                if (!ignoreBanner) {
                    // note: If the configuration is
                    // pulled using tftp copy, then the banner contains some unprintable characters (ETX=003)
                    // instead of ^C.
                    if (insideBanner) {
                        if (bannerEndPattern.matcher(line).matches()) {
                            insideBanner = false;
                        } else {
                            int idx = line.indexOf(3);
                            if (idx >= 0) {
                                insideBanner = false;
                            }
                        }
                        linesInsideBanner++;
                        if (cmdNeeded) {
                            cmdOutput.append(trimShowTechLine(line));
                        }
                        continue;
                    } else {
                        if (bannerStartPattern.matcher(line).matches()) {
                            insideBanner = true;
                            if (bannerSameLinePattern.matcher(line).matches()) {
                                insideBanner = false;
                            }
                        } else if (bannerStartPattern1.matcher(line).matches()) {
                            int idx1 = line.indexOf(3);
                            if (idx1 >= 0) {
                                insideBanner = true;
                                int idx2 = line.lastIndexOf(3);
                                if (idx2 > idx1) {
                                    insideBanner = false;
                                }
                            }
                            if (cmdNeeded) {
                                cmdOutput.append(trimShowTechLine(line));
                            }
                            continue;
                        }
                    }
                }

                lineno++;
                Matcher m1;
                boolean showTechStart = false;
                boolean showTechCommand = false;
                String matchingPattern = null;

                if (d != null) {
                    Map<String, Object> map = d.getAttributes();
                    Iterator entries = map.entrySet().iterator();
                    while (entries.hasNext()) {
                        Entry thisEntry = (Entry) entries.next();
                        String pattern = thisEntry.getKey().toString();

                        m1 = Pattern.compile(pattern).matcher(line);
                        if (m1.matches()) {
                            DevProperties prop = (DevProperties) thisEntry.getValue();
                            Map<String, String> prop1 = prop.getProperty();
                            Iterator it = prop1.entrySet().iterator();
                            while (it.hasNext()) {
                                Entry thisEntry1 = (Entry) it.next();

                                if (thisEntry1.getKey().toString().equals("showTechStartPattern")) {
                                    showTechStart = true;
                                } else if (thisEntry1.getKey().toString().equals("showTechCommandPattern")) {
                                    showTechCommand = true;
                                    matchingPattern = pattern;
                                }

                            }

                        }

                    }

                }

                boolean matched = false;
                if (line.contains("!! IOS XR Configuration")) {
                    isIOSXRtechfile = true;
                }

                // if (line.contains("Cisco Adaptive Security Appliance Software Version") ||
                // line.contains("Cisco PIX"))
                // {
                // showTechStart = true;

                // }

                if (showTechStart) {
                    if (firstcmd) {
                        // Done with current device. Another show tech starts now.
                        // Add the device that is read so far.
                        addCmdOutput(fileName, cmd, cmdOutput, cmdOutputs);
                        if (!cmdOutputs.isEmpty()) {
                            addShowTechFile(fileName, cmdOutputs, ipAddress, d);
                        }
                        // cmdOutputs = new HashMap<String, byte[]>();
                        cmd = "unknown";
                        cmdNeeded = true;
                        cmdOutput = new StringBuffer();
                        ipAddress = newIpAddress;
                        newIpAddress = null;
                        firstcmd = false;

                        continue;
                    }

                }

                m1 = ipAddrFromShowTech.matcher(line);
                matched = m1.matches();

                if (matched) {
                    newIpAddress = m1.group(1).trim();
                }
                boolean cmdstart = false;

                matched = showTechCommand;
                if (matched) {

                    cmdstart = true;
                }

                else {
                    Matcher m = ipsshowTechCommandPattern.matcher(line);
                    if (m.matches()) {
                        if (firstcmd) {
                            isnxos = false;
                            firstcmd = false;
                        }
                        cmdstart = true;
                    }
                }

                String command = null;
                if (cmdstart) {
                    // Done with current command. Another command starts now.
                    // Add this command to the hashmap. If it is already present,
                    // overwrite it.

                    if (matchingPattern != null) {
                        Pattern p = Pattern.compile(matchingPattern);
                        Matcher m = p.matcher(line);
                        if (m.matches()) {
                            try {
                                command = m.group(1).trim().toLowerCase();
                                command = command.trim();
                                if (d != null) {
                                    Map<String, Object> map = d.getAttributes();
                                    Iterator entries = map.entrySet().iterator();
                                    while (entries.hasNext()) {
                                        Entry thisEntry = (Entry) entries.next();
                                        String pattern = thisEntry.getKey().toString();
                                        boolean test = false;
                                        m1 = Pattern.compile(pattern).matcher(line);
                                        if (m1.matches()) {
                                            DevProperties prop = (DevProperties) thisEntry.getValue();
                                            Map<String, String> prop1 = prop.getProperty();
                                            Iterator it = prop1.entrySet().iterator();
                                            while (it.hasNext()) {
                                                Entry thisEntry1 = (Entry) it.next();

                                                if (thisEntry1.getKey().toString().equals("command")) {
                                                    command = prop.getProperty("command");
                                                    test = true;

                                                }

                                            }

                                        }
                                        if (test) {
                                            break;
                                        }

                                    }

                                }

                            } catch (Exception e) {
                                if (d != null) {
                                    Map<String, Object> map = d.getAttributes();
                                    Iterator entries = map.entrySet().iterator();
                                    while (entries.hasNext()) {
                                        Entry thisEntry = (Entry) entries.next();
                                        String pattern = thisEntry.getKey().toString();
                                        boolean test = false;
                                        m1 = Pattern.compile(pattern).matcher(line);
                                        if (m1.matches()) {
                                            DevProperties prop = (DevProperties) thisEntry.getValue();
                                            Map<String, String> prop1 = prop.getProperty();
                                            Iterator it = prop1.entrySet().iterator();
                                            while (it.hasNext()) {
                                                Entry thisEntry1 = (Entry) it.next();

                                                if (thisEntry1.getKey().toString().equals("command")) {
                                                    command = prop.getProperty("command");
                                                    test = true;

                                                }

                                            }

                                        }
                                        if (test) {
                                            break;
                                        }

                                    }

                                }

                            }
                        }

                        if ((command.length() > 0) && !command.equals(" ")) {
                            // IOS XR show tech has the command as "show running-config (no password)
                            if (command.equals("show running-config (no password)")
                                    && !cmdOutputs.containsKey("show running-config")) {
                                command = "show running-config";
                            }
                            addCmdOutput(fileName, cmd, cmdOutput, cmdOutputs);
                            cmd = command;
                            cmdNeeded = commandNeedsToBeSaved(cmd);
                            // for NXOS, the show version appears multiple times. First time for chassis and later for
                            // the
                            // modules.
                            // We should ignore the other show versions.
                            cmdNeeded = (cmdNeeded) && (!cmdOutputs.containsKey(cmd));
                            cmdOutput = new StringBuffer();
                            continue;
                        }
                    }
                }

                // if (line.contains("Cisco Adaptive Security Appliance Software Version") ||
                // line.contains("Cisco PIX"))
                // {
                // command = "show version";
                // addCmdOutput(fileName, cmd, cmdOutput, cmdOutputs);
                // cmd = command;
                // cmdNeeded = commandNeedsToBeSaved(cmd);
                // for NXOS, the show version appears multiple times. First time for chassis and later for
                // the
                // modules.
                // We should ignore the other show versions.
                // cmdNeeded = (cmdNeeded) && (!cmdOutputs.containsKey(cmd));
                // cmdOutput = new StringBuffer();
                // continue;
                // }

                if (cmdNeeded) {
                    cmdOutput.append(trimShowTechLine(line));
                }
            }
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    logger.error("Error while closing stream", e);
                }
            }
        }
        if (!ignoreBanner) {
            if (insideBanner) {
                // Something is wrong! We never found the end of a banner. Something wrong with
                // the end-of-banner detection code. Let us try it one more time, this time
                // let us ignore the banner.. just in case.
                logger.warn("File: " + fileName + " Unable to find end of banner commands. "
                        + "Running once more and ignoring banner commands now.");
                processShowTechFile(fileName, true, isGetter, d);
                return;
            } else {
                int percentLinesInsideBanner = (linesInsideBanner * 100) / lineno;
                if (percentLinesInsideBanner > 85) {
                    // Something wrong. Somehow, looks like 85% of the file is under banner commands!
                    // Let us try it one more time, this time
                    // let us ignore the banner.. just in case.
                    logger.warn("File: " + fileName + " major portion of the file: (" + percentLinesInsideBanner
                            + "%) "
                            + "is found to be inside banner commands. Trying again by ignoring the banners.");
                    processShowTechFile(fileName, true, isGetter, d);
                    return;
                }
            }
        }
        addCmdOutput(fileName, cmd, cmdOutput, cmdOutputs);
        addShowTechFile(fileName, cmdOutputs, ipAddress, d);
    }

    private void addCmdOutput(String fileName, String cmd, StringBuffer cmdOutput,
            HashMap<String, byte[]> cmdOutputs) {
        String output = (cmdOutput == null) ? null : cmdOutput.toString();
        if (output == null || output.trim().isEmpty()) {
            return;
        }
        if (cmd.equals("unknown")) {

            if (output.trim().startsWith("FWSM") || output.trim().startsWith("Cisco Adaptive Security")
                    || output.trim().startsWith("Cisco PIX Security"))

            {
                // For FWSM the show tech starts with show version but without the command header ---- show version ----
                cmd = "show version";

            } else {
                return;
            }
        }
        if (!commandNeedsToBeSaved(cmd)) {
            return;
        }
        if (cmdOutputs.containsKey(cmd)) {
            return;
        }
        try {
            byte b1[] = CompressionUtils.getCompressedString(cmdOutput.toString());
            cmdOutputs.put(cmd, b1);
        } catch (Exception ex) {
            logger.warn("Exception while compression " + cmd + " for file: " + fileName);
        }
    }

    private String trimShowTechLine(String line) {
        // Ordinary line. Some of the show tech outputs, (eg. Cisco Works output)
        // has " and ' before and after the line. Strip them.
        if (line.startsWith("\"")) {
            char c = line.charAt(0);
            int i = 0;
            while (((c == '"') || (c == ','))) {
                i++;
                if (i >= line.length()) {
                    break;
                }
                c = line.charAt(i);
            }
            if (i < line.length()) {
                line = line.substring(i);
            } else {
                line = "";
            }
        }
        if (line.endsWith("\"") && (line.length() > 1)) {
            line = line.substring(0, line.length() - 1);
        }
        return line += "\n";
    }

    private boolean commandNeedsToBeSaved(String cmd) {
        if (datasetMap.get(cmd) != null) {
            return true;
        }
        // for NXOS, show tech contains a bunch of commands that start with "show version | inc....."
        // We dont want to save them.
        // if (cmd.startsWith("show version"))
        if (cmd.equals("show version")) {
            return true;
        }
        // for NXOS, show tech contains a bunch of show running-config commands like show running-config ip etc
        // if (cmd.startsWith("show running-config"))
        // for Nexus-7K series contains command as show running
        if (cmd.equals("show running-config") || cmd.equals("show running")) {
            return true;
        }
        if (cmd.startsWith("show config")) {
            return true;
        }
        return false;
    }

    private void addShowTechFile(String fileName, HashMap<String, byte[]> cmdOutputs, String ipAddress,
            DSPZipImportData data) {
        ZIPFileResult fileResult = new ZIPFileResult(fileName);

        fileResult.fileType = ZIPFileType.SHOW_TECH;
        fileResult.msg = "";
        byte show_version[] = cmdOutputs.get("show version");
        byte show_config[] = cmdOutputs.get("show running-config");

        // For IOS XR tech-support file, sometimes we don't have the show version command
        // Ignoring to check for this command in case of IOS XR devices
        if (show_version == null && isIOSXRtechfile == false) {
            fileResult.msg = "No Show version found.";
            fileResultMap.put(fileName, fileResult);
            return;
        }
        String shVer = null;
        try {
            if (show_version != null) {
                shVer = CompressionUtils.getUncompressedString(show_version);
            }
        } catch (Exception ex) {
            logger.error("Exception while uncompressing show version for device: " + ipAddress);
            fileResult.msg = "No Show version found.";
            fileResultMap.put(fileName, fileResult);
            return;
        }
        if (show_config == null) {
            show_config = cmdOutputs.get("show configuration");
        }
        // For Nexus-7K series we have the command as show running
        // 10:10:24.587 CET Wed Nov 06 2013
        // `show running`
        //
        // !Command: show running-config
        // !Time: Wed Nov 6 10:10:24 2013
        //
        // version 6.1(4)
        if (show_config == null) {
            show_config = cmdOutputs.get("show running");
        }
        String cfg = null;
        try {
            cfg = CompressionUtils.getUncompressedString(show_config);
        } catch (Exception ex) {
            logger.error("Exception while uncompressing config for device: " + ipAddress);
        }
        FileInfo showVerFileInfo = new FileInfo();
        if (shVer != null) {

            showVerFileInfo.fileType = ZIPFileType.VERSION;
            // Proces show version
            String[] verLines = shVer.split("\r*\n");
            for (String line : verLines) {
                handleVersionLine(showVerFileInfo, line, data);
            }
        }

        // Proces show config
        FileInfo configFileInfo = new FileInfo();
        if (show_config == null) {
            // For CATOS devices, the command is "show config"
            show_config = cmdOutputs.get("show config");
            if (show_config == null) {
                fileResult.msg += "No running configuration found.";
                return;
            } else {
                try {
                    cfg = CompressionUtils.getUncompressedString(show_config);
                } catch (IOException e) {
                }
                configFileInfo.ostype = "CATOS";
            }
        }
        configFileInfo.fileType = ZIPFileType.CONFIG;

        String[] cfgLines = (cfg == null) ? null : cfg.split("\r*\n");
        if (cfgLines != null) {
            for (String line : cfgLines) {
                handleConfigurationLine(configFileInfo, line, data);
            }
        }

        String cfg_host_name = configFileInfo.hostName;
        String cfg_osType = configFileInfo.ostype;
        String cfg_version = configFileInfo.version;
        String osType = showVerFileInfo.ostype;
        String hostName = showVerFileInfo.hostName;
        String version = showVerFileInfo.version;

        if (cfg_osType != null) {
            if ((osType != null) && !cfg_osType.equals(osType)) {
                fileResult.msg += "Warning: OS Type gathered from show version: (" + osType
                        + ") is not the same as the OS Type gathered from configuration (" + cfg_osType + ")";
                addWarning("OS Type gathered from show version: (" + osType
                        + ") is not the same as the OS Type gathered from configuration (" + cfg_osType
                        + ") while processing show tech file: " + fileName);
            }
            osType = cfg_osType;
        }
        if (cfg_host_name != null) {
            if ((hostName != null) && !cfg_host_name.equals(hostName)) {
                fileResult.msg += "Warning: host name gathered from show version: (" + hostName
                        + ") is not the same as the host name gathered from configuration (" + cfg_host_name + ")";
                addWarning("host name gathered from show version: (" + hostName
                        + ") is not the same as the host name gathered from configuration (" + cfg_host_name
                        + ") while processing show tech file: " + fileName);
            }
            hostName = cfg_host_name;
        }

        if (version == null) {
            version = cfg_version;
        }
        if (hostName == null) {
            if ((osType != null) && osType.equals("CATOS")) {
                hostName = "Switch";
            }
        }
        if (hostName == null) {
            fileResult.msg += " Unable to determine the host name from show tech";
            addWarning("Unable to determine the host name from show tech: " + fileName);
            return;
        }
        if (ipAddress == null) {
            Matcher m1 = ipAddrFromFileName.matcher(fileName);
            if (m1.matches()) {
                ipAddress = m1.group(1).trim();
            }
        }
        fileResult.hostName = hostName;
        fileResult.osType = osType;
        // Everything is good. Add this to the list.
        showTechFileMap.put(hostName, fileName);
        saveCommandOutputs(hostName, cmdOutputs);
        if (runConfigMap.get(hostName) != null) {
            fileResult.msg += " Duplicate hostname: " + hostName;
            addWarning("Duplicate hostname : " + hostName);
        }
        try {
            File f = copyEntry(new ByteArrayInputStream(cfg.getBytes()), hostName, "Config");
            if (f != null) {
                runConfigMap.put(hostName, f.getAbsolutePath());
            }
        } catch (Exception ex) {
            fileResult.msg += " Unable to uncompress configuration";
            logger.error("Exception while uncompressing configuration for device: " + hostName, ex);
        }
        osTypeMap.put(hostName, osType);
        versionNumberMap.put(hostName, version);
        if (shVer != null) {
            try {
                File f = copyEntry(new ByteArrayInputStream(shVer.getBytes()), hostName, "Version");
                if (f != null) {
                    showVerMap.put(hostName, f.getAbsolutePath());
                }
            } catch (Exception ex) {
                fileResult.msg += " Unable to uncompress version";
                logger.error("Exception while uncompressing version for device: " + hostName, ex);
            }
        }
        if (ipAddress != null) {
            logger.debug("Device: " + hostName + " IP Address: " + ipAddress);
            ipAddressMap.put(hostName, ipAddress);
        } else {
            // logger.debug("Device: " + hostName + " has NO IP Address");
        }
        fileResultMap.put(fileName, fileResult);
    }

    private void saveCommandOutputs(String hostName, HashMap<String, byte[]> cmdOutputs) {

        for (String cmd : cmdOutputs.keySet()) {
            byte[] b = cmdOutputs.get(cmd);
            if (!cmd.equals("show version") && !cmd.equals("show running-config")) {
                try {
                    String output = CompressionUtils.getUncompressedString(b);
                    File f = copyEntry(new ByteArrayInputStream(output.getBytes()), hostName, cmd);
                    if (f != null) {
                        HashMap<String, String> map = cmdOutputMap.get(hostName);
                        if (map == null) {
                            map = new HashMap<String, String>();
                            cmdOutputMap.put(hostName, map);
                        }
                        map.put(cmd, f.getAbsolutePath());
                    }
                } catch (Exception ex) {
                    logger.error("Exception while saving cmd: " + cmd + " for " + hostName, ex);
                }
            }
        }
    }

    private void addRunConfig(String hostName, ZipEntry entry, ZipFile inZip) throws IOException {
        File f = copyEntry(entry, inZip, hostName, "Config");
        if (f != null) {
            runConfigMap.put(hostName, f.getAbsolutePath());
        }
    }

    private File copyEntry(ZipEntry entry, ZipFile inZip, String hostName, String cmd) throws IOException {
        InputStream inStream = inZip.getInputStream(entry);
        return copyEntry(inStream, hostName, cmd);
    }

    private File copyEntry(InputStream inStream, String hostName, String cmd) throws IOException {
        OutputStream os = null;
        try {
            // CSCul29590 - Removing special characters from hostName as File/Dir can't be created if it has Special
            // characters and VSEM file cannot be created and device import fails.
            hostName = hostName.replaceAll("[^A-Za-z0-9_]", "_");
            File d = new File(tmpRoot, hostName);
            d.mkdirs();
            cmd = cmd.replaceAll("[^A-Za-z0-9_]", "_");
            File c = new File(d, cmd);
            byte b[] = new byte[1024];
            int len = 0;
            os = new FileOutputStream(c);
            while ((len = inStream.read(b)) > 0) {
                os.write(b, 0, len);
            }
            return c;
        } finally {
            try {
                inStream.close();
            } catch (Exception ex) {

            }
            try {
                os.close();
            } catch (Exception ex) {

            }
        }
    }

    private void addShowVersion(String hostName, ZipEntry entry, ZipFile inZip) throws IOException {
        File f = copyEntry(entry, inZip, hostName, "Version");
        if (f != null) {
            showVerMap.put(hostName, f.getAbsolutePath());
        }
    }

    private void addWarning(String string) {
        if (warnMsg == null) {
            warnMsg = "";
        }
        warnMsg += string + "\r\n";
    }

    private void processVersionFile(String fileName, FileInfo fileInfo, ZipEntry entry, ZipFile inZip) {
        String hostName = fileInfo.hostName;
        String osType = fileInfo.ostype;
        String version = fileInfo.version;

        ZIPFileResult fileResult = new ZIPFileResult(fileName);
        fileResult.hostName = fileInfo.hostName;
        fileResult.osType = fileInfo.ostype;
        fileResult.fileType = fileInfo.fileType;
        if (hostName == null) {
            fileResult.msg = "Unable to parse hostname";
            fileResultMap.put(fileName, fileResult);
            return;
        } else {
            if (hostName.contains("=")) {
                fileResult.msg = "Illegal hostname. Should not contain '='";
                fileResult.hostName = hostName;
                fileResultMap.put(fileName, fileResult);
                return;
            }
        }
        String currOsType = osTypeMap.get(hostName);
        if ((currOsType != null) && (!currOsType.equals(osType))) {
            // TODO:
            // Different OS types from different files. Handle this later
        }
        osTypeMap.put(hostName, osType);
        if (showVerMap.containsKey(hostName)) {
            logger.debug("\tDuplicate version for : " + hostName);
            fileResult.msg = "Duplicate version for: " + hostName;
            // HostName already exists. Duplicate hostname.
            String oldFileName = showVerFileMap.get(hostName);
            HashSet<String> hs = dupVersionsFileMap.get(hostName);
            if (hs == null) {
                hs = new HashSet<String>();
                dupVersionsFileMap.put(hostName, hs);
            }
            hs.add(oldFileName);
            hs.add(fileName);
            showVerFileMap.remove(hostName);
            showVerMap.remove(hostName);
        } else {
            // Host name does not exist in show versions list. Check if it exists in the duplicates.
            HashSet<String> hs = dupVersionsFileMap.get(hostName);
            if ((hs != null) && !hs.isEmpty()) {
                fileResult.msg = "Duplicate version for: " + hostName;
                logger.debug("\tDuplicate version for : " + hostName);
                hs.add(fileName);
            } else {
                // It does not exist in the duplicates either.
                try {
                    if (entry == null && fileInfo.entryName != null) {
                        entry = inZip.getEntry(fileInfo.entryName);
                    }
                    addShowVersion(hostName, entry, inZip);
                    showVerFileMap.put(hostName, fileName);
                    if (version != null) {
                        versionNumberMap.put(hostName, version);
                    }
                } catch (Exception ex) {
                    logger.error("Exception while saving version for " + hostName, ex);
                }
            }
        }
        fileResultMap.put(fileName, fileResult);
    }

    private void processConiguration(String fileName, FileInfo fileInfo, ZipEntry entry, ZipFile inZip) {
        String hostName = fileInfo.hostName;
        String osType = fileInfo.ostype;
        String version = fileInfo.version;
        ZIPFileResult fileResult = new ZIPFileResult(fileName);
        if (hostName == null) {
            fileResult.msg = "Unable to parse hostname";
            fileResultMap.put(fileName, fileResult);
            return;
        } else {
            if (hostName.contains("=")) {
                fileResult.msg = "Illegal hostname. Should not contain '='";
                fileResult.hostName = hostName;
                fileResultMap.put(fileName, fileResult);
                return;
            }
        }

        fileResult.fileType = fileInfo.fileType;
        fileResult.hostName = fileInfo.hostName;
        fileResult.osType = fileInfo.ostype;
        String currOsType = osTypeMap.get(hostName);
        if ((currOsType != null) && (!currOsType.equals(osType))) {
            // TODO:
            // Different OS types from different files. Handle this later
        }
        osTypeMap.put(hostName, osType);
        if (runConfigMap.containsKey(hostName)) {
            fileResult.msg = "Duplicate Configuration for: " + hostName;
            logger.debug("\tDuplicate config for : " + hostName);
            // HostName already exists. Duplicate hostname.
            String oldFileName = runConfigFileMap.get(hostName);
            HashSet<String> hs = dupConfigsFileMap.get(hostName);
            if (hs == null) {
                hs = new HashSet<String>();
                dupConfigsFileMap.put(hostName, hs);
            }
            hs.add(oldFileName);
            hs.add(fileName);
            runConfigFileMap.remove(hostName);
            runConfigMap.remove(hostName);
        } else {
            // Host name does not exist in running config. Check if it exists in the duplicates.
            HashSet<String> hs = dupConfigsFileMap.get(hostName);
            if ((hs != null) && !hs.isEmpty()) {
                logger.debug("\tDuplicate config for : " + hostName);
                fileResult.msg = "Duplicate Configuration for: " + hostName;

                // It exists in the duplicates. Add it to that list.
                hs.add(fileName);
            } else {
                // It does not exist in the duplicates either.
                try {
                    addRunConfig(hostName, entry, inZip);
                    runConfigFileMap.put(hostName, fileName);
                    if ((version != null) && (versionNumberMap.get(hostName) == null)) {
                        versionNumberMap.put(hostName, version);
                    }
                } catch (Exception ex) {
                    logger.error("Exception while saving running config for device " + hostName, ex);
                }
            }
        }
        fileResultMap.put(fileName, fileResult);
    }

    public String readFileContents(InputStream inStream) throws IOException {
        BufferedReader r = new BufferedReader(new InputStreamReader(inStream));
        StringBuilder b = new StringBuilder();
        String line = null;

        while ((line = r.readLine()) != null) {
            try {
                b.append(line + "\n");
            } catch (Exception ex) {

            }

        }

        r.close();
        return b.toString();
    }

    public static void main(String[] argv) throws Exception {
        BasicConfigurator.configure();
        if (argv.length < 1) {
            System.err.println("Provide zip file name to process");
            System.exit(1);
        }

        File pcbFile = null;
        String key = null;
        if (argv.length > 1) {
            if (argv.length < 3) {
                System.err.println("Usage: <ZIP FILE> [<PCBFILE> <CustomerKey>]");
                System.exit(1);
            }
            pcbFile = new File(argv[1]);
            key = argv[2];
        }

        String zipFileName = argv[0];
        File zipFile = new File(zipFileName);
        long time = System.currentTimeMillis();
        ZIPProcessor zipProcessor = ZIPProcessor.open(zipFile, -1);
        while (zipProcessor.inProgress) {
            System.out.println("Opened " + zipProcessor.currentEntryIdx + " files");
            Thread.sleep(10000);
        }
        System.out.println("Processed in " + (System.currentTimeMillis() - time) + " msec");
        String errors = zipProcessor.getErrorMessage();

        if (errors != null) {
            System.err.println("Errors: ");
            System.err.println(errors);
            System.exit(1);
        }

        String warnings = zipProcessor.getWarningMessage();
        if (warnings != null) {
            System.out.println("Warnings:");
            System.out.println(warnings);
        }

        String[] deviceNames = zipProcessor.getDeviceNames();
        if ((deviceNames == null) || (deviceNames.length == 0)) {
            System.out.println("No devices found.");
        } else {

            System.out.println(
                    "Found: " + deviceNames.length + " devices in " + zipProcessor.getNumEntries() + " entries.");
        }
        for (String fileName : zipProcessor.fileResultMap.keySet()) {
            ZIPFileResult fr = zipProcessor.fileResultMap.get(fileName);
            System.out
                    .println(fileName + "\t" + fr.hostName + "\t" + fr.fileType + "\t" + fr.osType + "\t" + fr.msg);
        }

        if ((pcbFile != null) && (key != null)) {
            System.out.println("Creating PCB File");
        }
        zipProcessor.cleanup();

    }

    public void cleanup() {
        try {
            if (tmpRoot != null) {
                FileUtils.deleteDirectory(tmpRoot);
            }
        } catch (Exception ex) {
            logger.error("Exception while deleting deleting directory: " + tmpRoot.getName(), ex);
            ex.printStackTrace();
        }
    }

    public static void zipDirectory(String directoryName, String outFileName) throws IOException {

        FileOutputStream fos = null;
        ZipOutputStream zout = null;
        File inDir = null;
        try {
            inDir = new File(directoryName);
            if (!inDir.isDirectory()) {
                return;
            }
            fos = new FileOutputStream(new File(outFileName));
            zout = new ZipOutputStream(fos);
            File files[] = inDir.listFiles();
            for (File f : files) {
                writeToZip(f, f.getName(), zout);
            }
            zout.close();
            fos.close();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            try {
                if (zout != null) {
                    zout.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private static void writeToZip(File f, String fileName, ZipOutputStream zout) throws IOException {
        FileInputStream fis = null;
        try {

            if (f.isDirectory()) {
                File files[] = f.listFiles();
                for (File f1 : files) {
                    writeToZip(f1, fileName + "/" + f1.getName(), zout);
                }
                return;
            }
            ZipEntry ze = new ZipEntry(fileName);
            zout.putNextEntry(ze);
            byte b[] = new byte[1024];
            fis = new FileInputStream(f);
            int n = 0;

            while ((n = fis.read(b)) >= 0) {
                zout.write(b, 0, n);
            }
            fis.close();
            zout.closeEntry();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    @Override
    public String getDeviceProperty(Object id, String propertyName) {
        if (propertyName.equalsIgnoreCase(PCBFile.ATTR_CONFIG_FILE)) {
            return getConfiguration(id.toString());
        } else if (propertyName.equalsIgnoreCase(PCBFile.OS_NAME)) {
            return getOsType(id.toString());
        } else if (propertyName.equalsIgnoreCase(PCBFile.ATTR_FULL_VERSION)) {
            return getShowVersion(id.toString());
        } else if (propertyName.equalsIgnoreCase(PCBFile.OS_VERSION)) {
            return getVersion(id.toString());
        }
        return null;
        // return getConfiguration(id.toString());
    }

    private interface InputStreamGetter {
        InputStream getInputStream() throws IOException;
    }
}