Example usage for java.lang StringIndexOutOfBoundsException printStackTrace

List of usage examples for java.lang StringIndexOutOfBoundsException printStackTrace

Introduction

In this page you can find the example usage for java.lang StringIndexOutOfBoundsException printStackTrace.

Prototype

public void printStackTrace() 

Source Link

Document

Prints this throwable and its backtrace to the standard error stream.

Usage

From source file:Main.java

private static String replaceInside(String content, String character, String format) {
    try {//from  ww  w  . j a  va2s .  c om
        int index;
        while ((index = content.indexOf(character)) >= 0) {
            int endIndex = content.indexOf(character, index + 1);
            String inside = String.format(Locale.getDefault(), format, content.substring(index + 1, endIndex));
            content = content.replace(content.substring(index, endIndex + 1), inside);
        }
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
    }

    return content;
}

From source file:com.ibm.wala.cast.js.translator.RangePosition.java

public static int getCol(String content, int line, int offset) {
    if (line == 1) {
        return offset + 1;
    }/*w  w  w  . j av a2 s.c o  m*/
    int pos = -1;
    for (int i = 0; i < line - 1; i++) {
        pos = content.indexOf('\n', pos + 1);
    }

    try {
        String lineBeginning = content.substring(pos, offset);
        int nrOfTabs = lineBeginning.length() - lineBeginning.replace("\t", "").length();
        return offset - pos + (TABSIZE - 1) * nrOfTabs;
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
        return -1;
    }
}

From source file:com.javielinux.utils.Utils.java

static public String getIconGeneric(Context cnt, String name) {
    if (name.startsWith("#")) {
        return "drawable/letter_hash";
    }/*w  w  w  . j av  a 2s.c om*/
    if (name.startsWith("@")) {
        return "drawable/letter_user";
    }
    int id = 0;
    String c = null;
    try {
        c = name.toLowerCase().substring(0, 1);
        Log.d(Utils.TAG, "es: " + c);
        id = cnt.getResources().getIdentifier(Utils.packageName + ":drawable/letter_" + c, null, null);
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (id > 0 && c != null) {
        return "drawable/letter_" + c;
    } else {
        return "drawable/letter_az";
    }
}

From source file:jade.lang.acl.StringACLCodec.java

/**
 * if there was an automatical Base64 encoding, then it performs
 * automatic decoding.//  ww w.  j  a  va  2  s .co m
 **/
private void checkBase64Encoding(ACLMessage msg) {
    String encoding = msg.getUserDefinedParameter(BASE64ENCODING_KEY);
    if (CaseInsensitiveString.equalsIgnoreCase(BASE64ENCODING_VALUE, encoding)) {
        try { // decode Base64
            String content = msg.getContent();
            if ((content != null) && (content.length() > 0)) {
                //char[] cc = new char[content.length()];
                //content.getChars(0,content.length(),cc,0);
                msg.setByteSequenceContent(Base64.decodeBase64(content.getBytes("US-ASCII")));
                msg.removeUserDefinedParameter(BASE64ENCODING_KEY); // reset the slot value for encoding
            }
        } catch (java.lang.StringIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (java.lang.NullPointerException e2) {
            e2.printStackTrace();
        } catch (java.lang.NoClassDefFoundError jlncdfe) {
            System.err.println("\t\t===== E R R O R !!! =======\n");
            System.err.println("Missing support for Base64 conversions");
            System.err.println("Please refer to the documentation for details.");
            System.err.println("=============================================\n\n");
            try {
                Thread.currentThread().sleep(3000);
            } catch (InterruptedException ie) {
            }
        } catch (UnsupportedEncodingException e3) {
            System.err.println("\t\t===== E R R O R !!! =======\n");
            System.err.println("Missing support for US-ASCII encoding for Base64 conversions");
        }
    } //end of if CaseInsensitiveString
}

From source file:com.prgpascal.qrdatatransfer.TransferActivity.java

/**
 * Manipulate the incoming message.//  ww  w .  j a  va 2 s .c  om
 * The message can be a regular message or an ACK message.
 * If the Server receives an incorrect ACK, finish the Activity with an error.
 * If the Client receives an incorrect message, retry reading the same QR.
 *
 * @param message the incoming message.
 */
public void messageReceived(String message) {

    if (iAmTheServer) {
        // I'm the Server and a ACK has received (via Wifi Direct)

        if (message.equals(attendedAck)) {
            // The Ack is correct.
            // If available, next QR will be created by ServerAckReceiver.

            // Now, check if I've reached the EOT.
            if (isFinishingTransmission) {
                // EOT ack received, End of Transmission reached.
                // Finish the transmission with success.
                finishTransmissionWithSuccess();
            }

        } else {
            // The Ack is incorrect (irreversible error).
            // Finish the Activity.
            finishTransmissionWithError();
        }

    } else {
        // I'm the client and a message has received (via QR code scan)
        try {
            // Message received
            String ack = MyUtils.getAckFromMessage(message);
            String content = MyUtils.getContentFromMessage(message);
            String digest = MyUtils.getDigestFromMessage(message);

            // Check the digest
            if (digest.equals(MyUtils.calculateDigest(content))) {
                // Digest OK.
                // Check the content.
                if (content.startsWith(TAG_MAC)) {
                    // MAC message, the First QR code of the transmission.
                    // It contains the Server MAC address.
                    // Start the connection with the Server.
                    // DISABLE further QR codes scan, until connection is not established.
                    makeQRscanAvailable(false);
                    String mac = content.substring(TAG_MAC.length());
                    connect(mac);

                } else if (content.equals(TAG_EOT)) {
                    // EOT message, End of Transmission reached
                    // Send the last ACK message and finish the Activity with success.
                    isFinishingTransmission = true;

                    sendAck(ack);
                    finishTransmissionWithSuccess();

                } else {
                    // Regular message, add it to the messages ArrayList
                    messages.add(content);
                    sendAck(ack);
                }

            } else {
                // Digest error.
                throw new StringIndexOutOfBoundsException();
            }

        } catch (StringIndexOutOfBoundsException e) {
            // The message received is smaller than expected or error on digest.
            e.printStackTrace();

            // Allow the QR to be read again
            clientFragment.resetPreviousMessage();
        }
    }
}

From source file:com.smi.travel.monitor.MonitorAmadeus.java

protected String getField(String name, String targetLine) {
    String val = null;
    MAmadeus ama = amadeusMap.get(name);
    if (StringUtils.isEmpty(ama.getSection())) {
        return null;
    }/*  w  w w  . j  a  v a 2  s  . c  om*/
    try {
        int node = Integer.parseInt(ama.getNodlm());
        targetLine = targetLine.substring(ama.getSection().length());
        String[] lines = targetLine.split(NODE_SEPARATOR);
        String line = lines[node - 1];

        if (ama.getLength() > 0) {
            val = line.substring(ama.getStartlength() - 1, ama.getStartlength() - 1 + ama.getLength());
        } else {
            val = line.substring(ama.getStartlength() - 1);
        }
        System.out.println("Key [" + name + "], Value [" + val + "]");
    } catch (StringIndexOutOfBoundsException se) {
        System.err.println("Cannot parse key[" + ama.toString() + "] ,line[" + targetLine + "]");
        val = "";
        se.printStackTrace();
    }
    return val;
}

From source file:jos.parser.Parser.java

private Declaration processDeclaration(final boolean isProtocol, String line, final boolean isOptional) {
    /*//w  w w  . ja  v a 2  s . c o  m
     * boolean debug = false; if (line.indexOf("6_0") != -1) { debug = true;
     * }
     */

    if (limit != null) {
        if (!hasLimitKeyword(line)) {
            return null;
        }
        if (line.indexOf(limit) == -1) {
            return null;
        }
    }

    final boolean appearance = (line.indexOf("UI_APPEARANCE_SELECTOR") != -1);
    line = cleanDeclaration(line);
    if (line.length() == 0) {
        return null;
    }

    final boolean isAbstract = isProtocol && !isOptional;

    if (line.startsWith("@property")) {
        if (isAbstract) {
            gencs.println("\t@Abstract");
        }
        processProperty(line, appearance);
        return null;
    }
    log("PROCESSING: %s", line);
    boolean isStatic = line.startsWith("+");
    int p, q;
    p = line.indexOf('(');
    if (p == -1) {
        return null;
    }
    q = line.indexOf(')');
    log("->%s\np=%d q-p=%d", line, p, q - p);
    String retval = null;
    try {
        retval = remapType(line.substring(p + 1, p + 1 + q - p - 1));
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
    }
    p = line.indexOf(';');
    String signature = null;
    try {
        signature = StringUtils.strip(line.substring(q + 1, q + 1 + p - q), " ;");
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
    }
    log("SIG: %s %d", line, p);
    final String selector = makeSelector(signature);
    final String parameters = makeParameters(signature);

    log("signature: %s", signature);
    log("selector: %s", selector);
    return new Declaration(selector, retval, parameters, isAbstract, isStatic, appearance);
}

From source file:com.xmobileapp.rockplayer.LastFmAlbumArtImporter.java

/*******************************
 * /*from  ww w .j a  va2 s .co m*/
 * filterString
 * 
 *******************************/
private String filterString(String original) {
    String filtered = original;

    try {
        /* Remove anything within () or []*/
        int init = original.indexOf('(');
        int stop = original.indexOf(')', init);
        if (init != -1 && stop != -1) {
            String addInfo = original.substring(init, stop + 1);
            filtered = original.substring(0, init) + original.substring(stop + 1, original.length());
            //filtered = original.replaceAll(addInfo, "");
        }
        init = filtered.indexOf('[');
        stop = filtered.indexOf(']', init);
        if (init != -1 && stop != -1) {
            String addInfo = filtered.substring(init, stop + 1);
            filtered = filtered.substring(0, init) + filtered.substring(stop + 1, filtered.length());
            //filtered = original.replaceAll(addInfo, "");
        }

        /* Remove common album name garbage */
        filtered = filtered.replace("CD1", "");
        filtered = filtered.replace("CD2", "");
        filtered = filtered.replace("cd1", "");
        filtered = filtered.replace("cd2", "");

        /* Remove strange characters */
        filtered = filtered.replace(',', ' ');
        filtered = filtered.replace('.', ' ');
        filtered = filtered.replace('+', ' ');
        filtered = filtered.replace('/', ' ');
        filtered = filtered.replace('<', ' ');
        filtered = filtered.replace('>', ' ');
        filtered = filtered.replace('?', ' ');
        filtered = filtered.replace('|', ' ');
        filtered = filtered.replace('#', ' ');
        filtered = filtered.replace('&', ' ');
        filtered = filtered.replace('%', ' ');

        Log.i("filter", filtered);

        return filtered;
    } catch (StringIndexOutOfBoundsException e) {
        e.printStackTrace();
        return original;
    }
}

From source file:com.pironet.tda.SunJDKParser.java

/**
 * parse the next thread dump from the stream passed with the constructor.
 *
 * @return null if no more thread dumps were found.
 *///from ww w.  j a va 2 s . co m
public MutableTreeNode parseNext() {
    if (nextDump != null) {
        MutableTreeNode tmpDump = nextDump;
        nextDump = null;
        return (tmpDump);
    }
    boolean retry = false;
    String line = null;

    do {

        try {
            Map<String, String> threads = new HashMap<>();
            ThreadDumpInfo overallTDI = new ThreadDumpInfo("Dump No. " + counter++, 0);
            if (withCurrentTimeStamp) {
                overallTDI.setStartTime((new Date(System.currentTimeMillis())).toString());
            }
            DefaultMutableTreeNode threadDump = new DefaultMutableTreeNode(overallTDI);

            DefaultMutableTreeNode catThreads = new DefaultMutableTreeNode(
                    new TableCategory("Threads", IconFactory.THREADS));
            threadDump.add(catThreads);

            DefaultMutableTreeNode catWaiting = new DefaultMutableTreeNode(
                    new TableCategory("Threads waiting for Monitors", IconFactory.THREADS_WAITING));

            DefaultMutableTreeNode catSleeping = new DefaultMutableTreeNode(
                    new TableCategory("Threads sleeping on Monitors", IconFactory.THREADS_SLEEPING));

            DefaultMutableTreeNode catLocking = new DefaultMutableTreeNode(
                    new TableCategory("Threads locking Monitors", IconFactory.THREADS_LOCKING));

            // create category for monitors with disabled filtering.
            // NOTE:  These strings are "magic" in that the methods
            // TDA#displayCategory and TreeCategory#getCatComponent both
            // checks these literal strings and the behavior differs.
            DefaultMutableTreeNode catMonitors = new DefaultMutableTreeNode(
                    new TreeCategory("Monitors", IconFactory.MONITORS, false));
            DefaultMutableTreeNode catMonitorsLocks = new DefaultMutableTreeNode(
                    new TreeCategory("Monitors without locking thread", IconFactory.MONITORS_NO_LOCKS, false));
            DefaultMutableTreeNode catBlockingMonitors = new DefaultMutableTreeNode(
                    new TreeCategory("Threads blocked by Monitors", IconFactory.THREADS_LOCKING, false));

            String title = null;
            String dumpKey = null;
            StringBuffer content = null;
            boolean inLocking = false;
            boolean inSleeping = false;
            boolean inWaiting = false;
            int threadCount = 0;
            int waiting = 0;
            int locking = 0;
            int sleeping = 0;
            boolean locked = true;
            boolean finished = false;
            final MonitorMap mmap = new MonitorMap();
            final Stack<String> monitorStack = new Stack<>();
            long startTime = 0;
            int singleLineCounter = 0;
            boolean concurrentSyncsFlag = false;
            Matcher matched = getDm().getLastMatch();

            while (getBis().ready() && !finished) {
                line = getNextLine();
                lineCounter++;
                singleLineCounter++;
                if (locked) {
                    if (line.contains("Full thread dump")) {
                        locked = false;
                        if (!withCurrentTimeStamp) {
                            overallTDI.setLogLine(lineCounter);

                            if (startTime != 0) {
                                startTime = 0;
                            } else if (matched != null && matched.matches()) {

                                String parsedStartTime = matched.group(1);
                                if (!getDm().isDefaultMatches() && isMillisTimeStamp()) {
                                    try {
                                        // the factor is a hack for a bug in oc4j timestamp printing (pattern timeStamp=2342342340)
                                        if (parsedStartTime.length() < 13) {
                                            startTime = Long.parseLong(parsedStartTime)
                                                    * (long) Math.pow(10, 13 - parsedStartTime.length());
                                        } else {
                                            startTime = Long.parseLong(parsedStartTime);
                                        }
                                    } catch (NumberFormatException nfe) {
                                        startTime = 0;
                                    }
                                    if (startTime > 0) {
                                        overallTDI.setStartTime((new Date(startTime)).toString());
                                    }
                                } else {
                                    overallTDI.setStartTime(parsedStartTime);
                                }
                                matched = null;
                                getDm().resetLastMatch();
                            }
                        }
                        dumpKey = overallTDI.getName();
                    } else if (!getDm().isPatternError() && (getDm().getRegexPattern() != null)) {
                        Matcher m = getDm().checkForDateMatch(line);
                        if (m != null) {
                            matched = m;
                        }
                    }
                } else {
                    if (line.startsWith("\"")) {
                        // We are starting a group of lines for a different thread
                        // First, flush state for the previous thread (if any)
                        concurrentSyncsFlag = false;
                        String stringContent = content != null ? content.toString() : null;
                        if (title != null) {
                            threads.put(title, content.toString());
                            content.append("</pre></pre>");
                            addToCategory(catThreads, title, null, stringContent, singleLineCounter, true);
                            threadCount++;
                        }
                        if (inWaiting) {
                            addToCategory(catWaiting, title, null, stringContent, singleLineCounter, true);
                            inWaiting = false;
                            waiting++;
                        }
                        if (inSleeping) {
                            addToCategory(catSleeping, title, null, stringContent, singleLineCounter, true);
                            inSleeping = false;
                            sleeping++;
                        }
                        if (inLocking) {
                            addToCategory(catLocking, title, null, stringContent, singleLineCounter, true);
                            inLocking = false;
                            locking++;
                        }
                        singleLineCounter = 0;
                        while (!monitorStack.empty()) {
                            mmap.parseAndAddThread(monitorStack.pop(), title, content.toString());
                        }

                        // Second, initialize state for this new thread
                        title = line;
                        content = new StringBuffer("<body bgcolor=\"ffffff\"><pre><font size="
                                + TDA.getFontSizeModifier(-1) + '>');
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("at ")) {
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("java.lang.Thread.State")) {
                        content.append(line);
                        content.append('\n');
                        if (title.indexOf("t@") > 0) {
                            // in this case the title line is missing state informations
                            String state = line.substring(line.indexOf(':') + 1).trim();
                            if (state.indexOf(' ') > 0) {
                                title += " state=" + state.substring(0, state.indexOf(' '));
                            } else {
                                title += " state=" + state;
                            }
                        }
                    } else if (line.contains("Locked ownable synchronizers:")) {
                        concurrentSyncsFlag = true;
                        content.append(line);
                        content.append('\n');
                    } else if (line.contains("- waiting on")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inSleeping = true;
                        content.append('\n');
                    } else if (line.contains("- parking to wait")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inSleeping = true;
                        content.append('\n');
                    } else if (line.contains("- waiting to")) {
                        content.append(linkifyMonitor(line));
                        monitorStack.push(line);
                        inWaiting = true;
                        content.append('\n');
                    } else if (line.contains("- locked")) {
                        content.append(linkifyMonitor(line));
                        inLocking = true;
                        monitorStack.push(line);
                        content.append('\n');
                    } else if (line.contains("- ")) {
                        if (concurrentSyncsFlag) {
                            content.append(linkifyMonitor(line));
                            monitorStack.push(line);
                        } else {
                            content.append(line);
                        }
                        content.append('\n');
                    }

                    // last thread reached?
                    if ((line.contains("\"Suspend Checker Thread\""))
                            || (line.contains("\"VM Periodic Task Thread\""))
                            || (line.contains("<EndOfDump>"))) {
                        finished = true;
                        getBis().mark(getMarkSize());
                        if ((checkForDeadlocks(threadDump)) == 0) {
                            // no deadlocks found, set back original position.
                            getBis().reset();
                        }

                        if (!checkThreadDumpStatData(overallTDI)) {
                            // no statistical data found, set back original position.
                            getBis().reset();
                        }

                        getBis().mark(getMarkSize());
                        if (!(foundClassHistograms = checkForClassHistogram(threadDump))) {
                            getBis().reset();
                        }
                    }
                }
            }
            // last thread
            String stringContent = content != null ? content.toString() : null;
            if (title != null) {
                threads.put(title, content.toString());
                content.append("</pre></pre>");
                addToCategory(catThreads, title, null, stringContent, singleLineCounter, true);
                threadCount++;
            }
            if (inWaiting) {
                addToCategory(catWaiting, title, null, stringContent, singleLineCounter, true);
                waiting++;
            }
            if (inSleeping) {
                addToCategory(catSleeping, title, null, stringContent, singleLineCounter, true);
                sleeping++;
            }
            if (inLocking) {
                addToCategory(catLocking, title, null, stringContent, singleLineCounter, true);
                locking++;
            }
            while (!monitorStack.empty()) {
                mmap.parseAndAddThread(monitorStack.pop(), title, content.toString());
            }

            int monitorCount = mmap.size();

            int monitorsWithoutLocksCount = 0;
            int contendedMonitors = 0;
            int blockedThreads = 0;
            // dump monitors 
            if (mmap.size() > 0) {
                int[] result = dumpMonitors(catMonitors, catMonitorsLocks, mmap);
                monitorsWithoutLocksCount = result[0];
                overallTDI.setOverallThreadsWaitingWithoutLocksCount(result[1]);

                result = dumpBlockingMonitors(catBlockingMonitors, mmap);
                contendedMonitors = result[0];
                blockedThreads = result[1];
            }

            // display nodes with stuff to display
            if (waiting > 0) {
                overallTDI.setWaitingThreads((Category) catWaiting.getUserObject());
                threadDump.add(catWaiting);
            }

            if (sleeping > 0) {
                overallTDI.setSleepingThreads((Category) catSleeping.getUserObject());
                threadDump.add(catSleeping);
            }

            if (locking > 0) {
                overallTDI.setLockingThreads((Category) catLocking.getUserObject());
                threadDump.add(catLocking);
            }

            if (monitorCount > 0) {
                overallTDI.setMonitors((Category) catMonitors.getUserObject());
                threadDump.add(catMonitors);
            }

            if (contendedMonitors > 0) {
                overallTDI.setBlockingMonitors((Category) catBlockingMonitors.getUserObject());
                threadDump.add(catBlockingMonitors);
            }

            if (monitorsWithoutLocksCount > 0) {
                overallTDI.setMonitorsWithoutLocks((Category) catMonitorsLocks.getUserObject());
                threadDump.add(catMonitorsLocks);
            }
            overallTDI.setThreads((Category) catThreads.getUserObject());

            ((Category) catThreads.getUserObject())
                    .setName(catThreads.getUserObject() + " (" + threadCount + " Threads overall)");
            ((Category) catWaiting.getUserObject())
                    .setName(catWaiting.getUserObject() + " (" + waiting + " Threads waiting)");
            ((Category) catSleeping.getUserObject())
                    .setName(catSleeping.getUserObject() + " (" + sleeping + " Threads sleeping)");
            ((Category) catLocking.getUserObject())
                    .setName(catLocking.getUserObject() + " (" + locking + " Threads locking)");
            ((Category) catMonitors.getUserObject())
                    .setName(catMonitors.getUserObject() + " (" + monitorCount + " Monitors)");
            ((Category) catBlockingMonitors.getUserObject()).setName(catBlockingMonitors.getUserObject() + " ("
                    + blockedThreads + " Threads blocked by " + contendedMonitors + " Monitors)");
            ((Category) catMonitorsLocks.getUserObject()).setName(
                    catMonitorsLocks.getUserObject() + " (" + monitorsWithoutLocksCount + " Monitors)");
            // add thread dump to passed dump store.
            if ((threadCount > 0) && (dumpKey != null)) {
                threadStore.put(dumpKey.trim(), threads);
            }

            // check custom categories
            addCustomCategories(threadDump);

            return (threadCount > 0 ? threadDump : null);
        } catch (StringIndexOutOfBoundsException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null,
                    "Error during parsing of a found thread dump, skipping to next one!\n"
                            + "Check for possible broken dumps, sometimes, stream flushing mixes the logged data.\n"
                            + "Error Message is \"" + e.getLocalizedMessage() + "\". \n"
                            + (line != null ? "Last line read was \"" + line + "\". \n" : ""),
                    "Error during Parsing Thread Dump", JOptionPane.ERROR_MESSAGE);
            retry = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    } while (retry);

    return (null);
}

From source file:com.maxl.java.aips2sqlite.RealExpertInfo.java

public void process() {

    // Get stop words first
    getStopWords();/*w  w  w .ja va  2 s.  co m*/

    // Extract EPha SwissmedicNo5 to ATC map
    extractSwissmedicNo5ToAtcMap();

    // Extract package information (this is the heavy-duty bit)
    extractPackageInfo();

    // Extract Swiss DRG information
    extractSwissDRGInfo();

    try {
        // Load CSS file: used only for self-contained xml files
        String amiko_style_v1_str = FileOps.readCSSfromFile(Constants.FILE_STYLE_CSS_BASE + "v1.css");

        // Create error report file
        ParseReport parse_errors = null;
        if (CmlOptions.GENERATE_REPORTS == true) {
            parse_errors = new ParseReport(Constants.FILE_PARSE_REPORT, CmlOptions.DB_LANGUAGE, "html");
            if (CmlOptions.DB_LANGUAGE.equals("de"))
                parse_errors.addHtmlHeader("Schweizer Arzneimittel-Kompendium", Constants.FI_DB_VERSION);
            else if (CmlOptions.DB_LANGUAGE.equals("fr"))
                parse_errors.addHtmlHeader("Compendium des Mdicaments Suisse", Constants.FI_DB_VERSION);
        }

        // Create indications report file
        BufferedWriter bw_indications = null;
        Map<String, String> tm_indications = new TreeMap<String, String>();
        if (CmlOptions.INDICATIONS_REPORT == true) {
            ParseReport indications_report = new ParseReport(Constants.FILE_INDICATIONS_REPORT,
                    CmlOptions.DB_LANGUAGE, "txt");
            bw_indications = indications_report.getBWriter();
        }

        /*
         * Add pseudo Fachinfos to SQLite database
         */
        int tot_pseudo_counter = 0;
        if (CmlOptions.ADD_PSEUDO_FI == true) {
            PseudoExpertInfo pseudo_fi = new PseudoExpertInfo(m_sql_db, CmlOptions.DB_LANGUAGE, m_map_products);
            // Process
            tot_pseudo_counter = pseudo_fi.process();
            System.out.println("");
        }

        /*
         * Add real Fachinfos to SQLite database
         */
        // Initialize counters for different languages
        int med_counter = 0;
        int tot_med_counter = 0;
        int missing_regnr_str = 0;
        int missing_pack_info = 0;
        int missing_atc_code = 0;
        int errors = 0;
        String fi_complete_xml = "";

        // First pass is always with DB_LANGUAGE set to German! (most complete information)
        // The file dumped in ./reports is fed to AllDown.java to generate a multilingual ATC code / ATC class file, e.g. German - French
        Set<String> atccode_set = new TreeSet<String>();

        // Treemap for owner error report (sorted by key)
        TreeMap<String, ArrayList<String>> tm_owner_error = new TreeMap<String, ArrayList<String>>();

        HtmlUtils html_utils = null;

        System.out.println("Processing real Fachinfos...");

        for (MedicalInformations.MedicalInformation m : m_med_list) {
            // --> Read FACHINFOS! <--            
            if (m.getLang().equals(CmlOptions.DB_LANGUAGE) && m.getType().equals("fi")) {
                // Database contains less than 5000 medis - this is a safe upperbound!
                if (tot_med_counter < 5000) {
                    // Trim titles of leading and trailing spaces
                    m.setTitle(m.getTitle().trim());
                    // Extract section titles and section ids
                    MedicalInformations.MedicalInformation.Sections med_sections = m.getSections();
                    List<MedicalInformations.MedicalInformation.Sections.Section> med_section_list = med_sections
                            .getSection();
                    String ids_str = "";
                    String titles_str = "";
                    for (MedicalInformations.MedicalInformation.Sections.Section s : med_section_list) {
                        ids_str += (s.getId() + ",");
                        titles_str += (s.getTitle() + ";");
                    }

                    Document doc = Jsoup.parse(m.getContent());
                    doc.outputSettings().escapeMode(EscapeMode.xhtml);

                    html_utils = new HtmlUtils(m.getContent());
                    html_utils.setLanguage(CmlOptions.DB_LANGUAGE);
                    html_utils.clean();

                    // Extract registration number (swissmedic no5)
                    String regnr_str = "";
                    if (CmlOptions.DB_LANGUAGE.equals("de"))
                        regnr_str = html_utils.extractRegNrDE(m.getTitle());
                    else if (CmlOptions.DB_LANGUAGE.equals("fr"))
                        regnr_str = html_utils.extractRegNrFR(m.getTitle());

                    // Pattern matcher for regnr command line option, (?s) searches across multiple lines
                    Pattern regnr_pattern = Pattern.compile("(?s).*\\b" + CmlOptions.OPT_MED_REGNR);

                    if (m.getTitle().toLowerCase().startsWith(CmlOptions.OPT_MED_TITLE.toLowerCase())
                            && regnr_pattern.matcher(regnr_str).find() && m.getAuthHolder().toLowerCase()
                                    .startsWith(CmlOptions.OPT_MED_OWNER.toLowerCase())) {

                        System.out.println(tot_med_counter + " - " + m.getTitle() + ": " + regnr_str);

                        if (regnr_str.isEmpty()) {
                            errors++;
                            if (CmlOptions.GENERATE_REPORTS == true) {
                                parse_errors.append("<p style=\"color:#ff0099\">ERROR " + errors
                                        + ": reg. nr. could not be parsed in AIPS.xml (swissmedic) - "
                                        + m.getTitle() + " (" + regnr_str + ")</p>");
                                // Add to owner errors
                                ArrayList<String> error = tm_owner_error.get(m.getAuthHolder());
                                if (error == null)
                                    error = new ArrayList<String>();
                                error.add(m.getTitle() + ";regnr");
                                tm_owner_error.put(m.getAuthHolder(), error);
                            }
                            missing_regnr_str++;
                            regnr_str = "";
                        }

                        // Associate ATC classes and subclasses (atc_map)               
                        String atc_class_str = "";
                        String atc_description_str = "";
                        // This bit is necessary because the ATC Code in the AIPS DB is broken sometimes 
                        String atc_code_str = "";

                        boolean atc_error_found = false;

                        // Use EPha ATC Codes, AIPS is fallback solution
                        String authNrs = m.getAuthNrs();
                        if (authNrs != null) {
                            // Deal with multi-swissmedic no5 case
                            String regnrs[] = authNrs.split(",");
                            // Use set to avoid duplicate ATC codes
                            Set<String> regnrs_set = new LinkedHashSet<>();
                            // Loop through EPha ATC codes
                            for (String r : regnrs) {
                                regnrs_set.add(m_smn5_atc_map.get(r.trim()));
                            }
                            // Iterate through set and format nicely
                            for (String r : regnrs_set) {
                                if (atc_code_str == null || atc_code_str.isEmpty())
                                    atc_code_str = r;
                                else
                                    atc_code_str += "," + r;
                            }
                        } else
                            atc_error_found = true;

                        // Notify any other problem with the EPha ATC codes
                        if (atc_code_str == null || atc_code_str.isEmpty())
                            atc_error_found = true;

                        // Fallback solution 
                        if (atc_error_found == true) {
                            if (m.getAtcCode() != null && !m.getAtcCode().equals("n.a.")
                                    && m.getAtcCode().length() > 1) {
                                atc_code_str = m.getAtcCode();
                                atc_code_str = atc_code_str.replaceAll("&ndash;", "(");
                                atc_code_str = atc_code_str.replaceAll("Code", "").replaceAll("ATC", "")
                                        .replaceAll("&nbsp", "").replaceAll("\\(.*", "").replaceAll("/", ",")
                                        .replaceAll("[^A-Za-z0-9,]", "");
                                if (atc_code_str.charAt(1) == 'O') {
                                    // E.g. Ascosal Brausetabletten
                                    atc_code_str = atc_code_str.substring(0, 1) + '0'
                                            + atc_code_str.substring(2);
                                }
                                if (atc_code_str.length() > 7) {
                                    if (atc_code_str.charAt(7) != ',' || atc_code_str.length() != 15)
                                        atc_code_str = atc_code_str.substring(0, 7);
                                }
                            } else {
                                // Work backwards using m_atc_map and m.getSubstances()
                                String substances = m.getSubstances();
                                if (substances != null) {
                                    if (m_atc_map.containsValue(substances)) {
                                        for (Map.Entry<String, String> entry : m_atc_map.entrySet()) {
                                            if (entry.getValue().equals(substances)) {
                                                atc_code_str = entry.getKey();
                                            }
                                        }
                                    }
                                }
                            }
                            atc_error_found = false;
                        }

                        // Now let's clean the m.getSubstances()
                        String substances = m.getSubstances();
                        if ((substances == null || substances.length() < 3) && atc_code_str != null) {
                            substances = m_atc_map.get(atc_code_str);
                        }

                        // Set clean substances
                        m.setSubstances(substances);
                        // Set clean ATC Code
                        m.setAtcCode(atc_code_str);

                        // System.out.println("ATC -> " + atc_code_str + ": " + substances);

                        if (atc_code_str != null) {
                            // \\s -> whitespace character, short for [ \t\n\x0b\r\f]
                            // atc_code_str = atc_code_str.replaceAll("\\s","");
                            // Take "leave" of the tree (most precise classification)
                            String a = m_atc_map.get(atc_code_str);
                            if (a != null) {
                                atc_description_str = a;
                                atccode_set.add(atc_code_str + ": " + a);
                            } else {
                                // Case: ATC1,ATC2
                                if (atc_code_str.length() == 15) {
                                    String[] codes = atc_code_str.split(",");
                                    if (codes.length > 1) {
                                        String a1 = m_atc_map.get(codes[0]);
                                        if (a1 == null) {
                                            atc_error_found = true;
                                            a1 = "k.A.";
                                        }
                                        String a2 = m_atc_map.get(codes[1]);
                                        if (a2 == null) {
                                            atc_error_found = true;
                                            a2 = "k.A.";
                                        }
                                        atc_description_str = a1 + "," + a2;
                                    }
                                } else if (m.getSubstances() != null) {
                                    // Fallback in case nothing else works
                                    atc_description_str = m.getSubstances();
                                    // Work backwards using m_atc_map and m.getSubstances(), change ATC code
                                    if (atc_description_str != null) {
                                        if (m_atc_map.containsValue(atc_description_str)) {
                                            for (Map.Entry<String, String> entry : m_atc_map.entrySet()) {
                                                if (entry.getValue().equals(atc_description_str)) {
                                                    m.setAtcCode(entry.getKey());
                                                }
                                            }
                                        }
                                    }
                                } else {
                                    atc_error_found = true;
                                    if (CmlOptions.DB_LANGUAGE.equals("de"))
                                        atc_description_str = "k.A.";
                                    else if (CmlOptions.DB_LANGUAGE.equals("fr"))
                                        atc_description_str = "n.s.";
                                }
                            }

                            // Read out only two levels (L1, L3, L4, L5)
                            for (int i = 1; i < 6; i++) {
                                if (i != 2) {
                                    String atc_key = "";
                                    if (i <= atc_code_str.length())
                                        atc_key = atc_code_str.substring(0, i);
                                    char sep = (i >= 4) ? '#' : ';'; // #-separator between L4 and L5                              
                                    if (atc_key != null) {
                                        String c = m_atc_map.get(atc_key);
                                        if (c != null) {
                                            atccode_set.add(atc_key + ": " + c);
                                            atc_class_str += (c + sep);
                                        } else {
                                            atc_class_str += sep;
                                        }
                                    } else {
                                        atc_class_str += sep;
                                    }
                                }
                            }

                            // System.out.println("atc class = " + atc_class_str);

                            // If DRG medication, add to atc_description_str
                            ArrayList<String> drg = m_swiss_drg_info.get(atc_code_str);
                            if (drg != null) {
                                atc_description_str += (";DRG");
                            }
                        }

                        if (atc_error_found) {
                            errors++;
                            if (CmlOptions.GENERATE_REPORTS) {
                                parse_errors.append("<p style=\"color:#0000bb\">ERROR " + errors
                                        + ": Broken or missing ATC-Code-Tag in AIPS.xml (Swissmedic) or ATC index (Wido) - "
                                        + m.getTitle() + " (" + regnr_str + ")</p>");
                                // Add to owner errors
                                ArrayList<String> error = tm_owner_error.get(m.getAuthHolder());
                                if (error == null)
                                    error = new ArrayList<String>();
                                error.add(m.getTitle() + ";atccode");
                                tm_owner_error.put(m.getAuthHolder(), error);
                            }
                            System.err.println(">> ERROR: " + tot_med_counter
                                    + " - no ATC-Code found in the XML-Tag \"atcCode\" - (" + regnr_str + ") "
                                    + m.getTitle());
                            missing_atc_code++;
                        }

                        // Additional info stored in add_info_map
                        String add_info_str = ";";
                        List<String> rnr_list = Arrays.asList(regnr_str.split("\\s*, \\s*"));
                        if (rnr_list.size() > 0)
                            add_info_str = m_add_info_map.get(rnr_list.get(0));

                        // Sanitize html
                        String html_sanitized = "";
                        // First check for bad boys (version=1! but actually version>1!)
                        if (!m.getVersion().equals("1") || m.getContent().substring(0, 20).contains("xml")) {
                            for (int i = 1; i < 22; ++i) {
                                html_sanitized += html_utils.sanitizeSection(i, m.getTitle(), m.getAuthHolder(),
                                        CmlOptions.DB_LANGUAGE);
                            }
                            html_sanitized = "<div id=\"monographie\">" + html_sanitized + "</div>";
                        } else {
                            html_sanitized = m.getContent();
                        }

                        // Add author number
                        html_sanitized = html_sanitized.replaceAll("<div id=\"monographie\">",
                                "<div id=\"monographie\" name=\"" + m.getAuthNrs() + "\">");

                        // Add Footer, timestamp in RFC822 format                     
                        DateFormat dateFormat = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z",
                                Locale.getDefault());
                        Date date = new Date();
                        String footer_str = "<p class=\"footer\">Auto-generated by <a href=\"https://github.com/zdavatz/aips2sqlite\">aips2sqlite</a> on "
                                + dateFormat.format(date) + "</p>";

                        // html_sanitized += footer_str;
                        html_sanitized = html_sanitized.replaceAll("</div>$", footer_str + "</div>");

                        // Extract section indications
                        String section_indications = "";
                        if (CmlOptions.DB_LANGUAGE.equals("de")) {
                            String sstr1 = "Indikationen/Anwendungsmglichkeiten";
                            String sstr2 = "Dosierung/Anwendung";
                            if (html_sanitized.contains(sstr1) && html_sanitized.contains(sstr2)) {
                                int idx1 = html_sanitized.indexOf(sstr1) + sstr1.length();
                                int idx2 = html_sanitized.substring(idx1, html_sanitized.length())
                                        .indexOf(sstr2);
                                try {
                                    section_indications = html_sanitized.substring(idx1, idx1 + idx2);
                                } catch (StringIndexOutOfBoundsException e) {
                                    e.printStackTrace();
                                }
                            }
                        } else if (CmlOptions.DB_LANGUAGE.equals("fr")) {
                            String sstr1 = "Indications/Possibilits demploi";
                            String sstr2 = "Posologie/Mode demploi";

                            html_sanitized = html_sanitized.replaceAll("Indications/Possibilits d&apos;emploi",
                                    sstr1);
                            html_sanitized = html_sanitized.replaceAll("Posologie/Mode d&apos;emploi", sstr2);
                            html_sanitized = html_sanitized.replaceAll("Indications/possibilits demploi",
                                    sstr1);
                            html_sanitized = html_sanitized.replaceAll("Posologie/mode demploi", sstr2);

                            if (html_sanitized.contains(sstr1) && html_sanitized.contains(sstr2)) {
                                int idx1 = html_sanitized.indexOf(sstr1) + sstr1.length();
                                int idx2 = html_sanitized.substring(idx1, html_sanitized.length())
                                        .indexOf(sstr2);
                                try {
                                    section_indications = html_sanitized.substring(idx1, idx1 + idx2);
                                } catch (StringIndexOutOfBoundsException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                        // Remove all p's, div's, span's and sup's
                        section_indications = section_indications.replaceAll("\\<p.*?\\>", "")
                                .replaceAll("</p>", "");
                        section_indications = section_indications.replaceAll("\\<div.*?\\>", "")
                                .replaceAll("</div>", "");
                        section_indications = section_indications.replaceAll("\\<span.*?\\>", "")
                                .replaceAll("</span>", "");
                        section_indications = section_indications.replaceAll("\\<sup.*?\\>", "")
                                .replaceAll("</sup>", "");

                        // System.out.println(section_indications);

                        if (CmlOptions.DB_LANGUAGE.equals("fr")) {
                            // Remove apostrophes
                            section_indications = section_indications.replaceAll("l&apos;", "")
                                    .replaceAll("d&apos;", "");
                            section_indications = section_indications.replaceAll("l", "").replaceAll("d", "");
                        }
                        // Remove all URLs
                        section_indications = section_indications.replaceAll(
                                "\\b(http|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]", "");
                        // Remove list of type a) b) c) ... 1) 2) ...
                        section_indications = section_indications.replaceAll("^\\w\\)", "");
                        // Remove numbers, commas, semicolons, parentheses, etc.                        
                        section_indications = section_indications.replaceAll("[^A-Za-z\\xC0-\\xFF- ]", "");
                        // Generate long list of keywords
                        LinkedList<String> wordsAsList = new LinkedList<String>(
                                Arrays.asList(section_indications.split("\\s+")));
                        // Remove stop words
                        Iterator<String> wordIterator = wordsAsList.iterator();
                        while (wordIterator.hasNext()) {
                            // Note: This assumes there are no null entries in the list and all stopwords are stored in lower case
                            String word = wordIterator.next().trim().toLowerCase();
                            if (word.length() < 3 || m.getTitle().toLowerCase().contains(word)
                                    || m_stop_words_hash.contains(word))
                                wordIterator.remove();
                        }
                        section_indications = "";
                        for (String w : wordsAsList) {
                            // Remove any leading dash or hyphen
                            if (w.startsWith("-"))
                                w = w.substring(1);
                            section_indications += (w + ";");
                            if (CmlOptions.INDICATIONS_REPORT == true) {
                                // Add to map (key->value), word = key, value = how many times used
                                // Is word w already stored in treemap?
                                String t_str = tm_indications.get(w);
                                if (t_str == null) {
                                    t_str = m.getTitle();
                                    tm_indications.put(w, t_str);
                                } else {
                                    t_str += (", " + m.getTitle());
                                    tm_indications.put(w, t_str);
                                }
                            }
                        }

                        /*
                         * Update section "Packungen", generate packungen string for shopping cart, and extract therapeutisches index
                         */
                        List<String> mTyIndex_list = new ArrayList<String>();
                        m_list_of_packages.clear();
                        m_list_of_eancodes.clear();
                        String mContent_str = updateSectionPackungen(m.getTitle(), m.getAtcCode(),
                                m_package_info, regnr_str, html_sanitized, mTyIndex_list);

                        m.setContent(mContent_str);

                        // Check if mPackSection_str is empty AND command line option PLAIN is not active
                        if (CmlOptions.PLAIN == false && m_pack_info_str.isEmpty()) {
                            errors++;
                            if (CmlOptions.GENERATE_REPORTS) {
                                parse_errors.append("<p style=\"color:#bb0000\">ERROR " + errors
                                        + ": SwissmedicNo5 not found in Packungen.xls (Swissmedic) - "
                                        + m.getTitle() + " (" + regnr_str + ")</p>");
                                // Add to owner errors
                                ArrayList<String> error = tm_owner_error.get(m.getAuthHolder());
                                if (error == null)
                                    error = new ArrayList<String>();
                                error.add(m.getTitle() + ";swissmedic5");
                                tm_owner_error.put(m.getAuthHolder(), error);
                            }
                            System.err.println(">> ERROR: " + tot_med_counter
                                    + " - SwissmedicNo5 not found in Swissmedic Packungen.xls - (" + regnr_str
                                    + ") " + m.getTitle());
                            missing_pack_info++;
                        }

                        // Fix problem with wrong div class in original Swissmedic file
                        if (CmlOptions.DB_LANGUAGE.equals("de")) {
                            m.setStyle(m.getStyle().replaceAll("untertitel", "untertitle"));
                            m.setStyle(m.getStyle().replaceAll("untertitel1", "untertitle1"));
                        }

                        // Correct formatting error introduced by Swissmedic
                        m.setAuthHolder(m.getAuthHolder().replaceAll("&#038;", "&"));

                        // Check if substances str has a '$a' and change it to '&alpha'
                        if (m.getSubstances() != null)
                            m.setSubstances(m.getSubstances().replaceAll("\\$a", "&alpha;"));

                        if (CmlOptions.XML_FILE == true) {
                            if (!regnr_str.isEmpty()) {
                                // Generate and add hash code 
                                String html_str_no_timestamp = mContent_str
                                        .replaceAll("<p class=\"footer\">.*?</p>", "");
                                String hash_code = html_utils.calcHashCode(html_str_no_timestamp);

                                // Add header to html file
                                mContent_str = mContent_str.replaceAll("<head>", "<head>"
                                        + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" name=\"fi_"
                                        + hash_code + "\"/>" + "<style>" + amiko_style_v1_str + "</style>");

                                // Note: the following line is not necessary!
                                // m.setContent(mContent_str);

                                // Add header to xml file
                                String xml_str = html_utils.convertHtmlToXml("fi", m.getTitle(), mContent_str,
                                        regnr_str);
                                xml_str = html_utils.addHeaderToXml("singlefi", xml_str);
                                fi_complete_xml += (xml_str + "\n");

                                // Write to html and xml files to disk
                                String name = m.getTitle();
                                // Replace all "Sonderzeichen"
                                name = name.replaceAll("[^a-zA-Z0-9]+", "_");
                                if (CmlOptions.DB_LANGUAGE.equals("de")) {
                                    FileOps.writeToFile(mContent_str,
                                            Constants.FI_FILE_XML_BASE + "fi_de_html/", name + "_fi_de.html");
                                    FileOps.writeToFile(xml_str, Constants.FI_FILE_XML_BASE + "fi_de_xml/",
                                            name + "_fi_de.xml");
                                } else if (CmlOptions.DB_LANGUAGE.equals("fr")) {
                                    FileOps.writeToFile(mContent_str,
                                            Constants.FI_FILE_XML_BASE + "fi_fr_html/", name + "_fi_fr.html");
                                    FileOps.writeToFile(xml_str, Constants.FI_FILE_XML_BASE + "fi_fr_xml/",
                                            name + "_fi_fr.xml");
                                }
                            }
                        }

                        int customer_id = 0;
                        // Is the customer paying? If yes add customer id
                        // str1.toLowerCase().contains(str2.toLowerCase())
                        if (m.getAuthHolder().toLowerCase().contains("desitin"))
                            customer_id = 1;
                        /*
                        / HERE GO THE OTHER PAYING CUSTOMERS (increment customer_id respectively)
                        */

                        // Extract (O)riginal / (G)enerika info
                        String orggen_str = "";
                        if (add_info_str != null) {
                            List<String> ai_list = Arrays.asList(add_info_str.split("\\s*;\\s*"));
                            if (ai_list != null) {
                                if (!ai_list.get(0).isEmpty())
                                    orggen_str = ai_list.get(0);
                            }
                        }

                        // @maxl: 25.04.2015 -> set orggen_str to nil (we are using add_info_str for group names now...)
                        orggen_str = "";

                        /*
                         * Add medis, titles and ids to database
                         */
                        String packages_str = "";
                        for (String s : m_list_of_packages)
                            packages_str += s;
                        String eancodes_str = "";
                        for (String e : m_list_of_eancodes)
                            eancodes_str += (e + ", ");
                        if (!eancodes_str.isEmpty() && eancodes_str.length() > 2)
                            eancodes_str = eancodes_str.substring(0, eancodes_str.length() - 2);

                        m_sql_db.addExpertDB(m, packages_str, regnr_str, ids_str, titles_str,
                                atc_description_str, atc_class_str, m_pack_info_str, orggen_str, customer_id,
                                mTyIndex_list, section_indications);
                        m_sql_db.addProductDB(m, packages_str, eancodes_str, m_pack_info_str);

                        med_counter++;
                    }
                }
                tot_med_counter++;
            }
        }
        System.out.println();
        System.out.println("--------------------------------------------");
        System.out.println("Total number of real Fachinfos: " + m_med_list.size());
        System.out.println("Number of FI with package information: " + tot_med_counter);
        System.out.println("Number of FI in generated database: " + med_counter);
        System.out.println("Number of errors in db: " + errors);
        System.out.println("Number of missing reg. nr. (min): " + missing_regnr_str);
        System.out.println("Number of missing pack info: " + missing_pack_info);
        System.out.println("Number of missing atc codes: " + missing_atc_code);
        System.out.println("--------------------------------------------");
        System.out.println("Total number of pseudo Fachinfos: " + tot_pseudo_counter);
        System.out.println("--------------------------------------------");

        if (CmlOptions.XML_FILE == true) {
            fi_complete_xml = html_utils.addHeaderToXml("kompendium", fi_complete_xml);
            // Write kompendium xml file to disk
            if (CmlOptions.DB_LANGUAGE.equals("de")) {
                FileOps.writeToFile(fi_complete_xml, Constants.FI_FILE_XML_BASE, "fi_de.xml");
                if (CmlOptions.ZIP_BIG_FILES)
                    FileOps.zipToFile(Constants.FI_FILE_XML_BASE, "fi_de.xml");
            } else if (CmlOptions.DB_LANGUAGE.equals("fr")) {
                FileOps.writeToFile(fi_complete_xml, Constants.FI_FILE_XML_BASE, "fi_fr.xml");
                if (CmlOptions.ZIP_BIG_FILES)
                    FileOps.zipToFile(Constants.FI_FILE_XML_BASE, "fi_fr.xml");
            }
            // Copy stylesheet file to ./fis/ folders
            try {
                File src = new File(Constants.FILE_STYLE_CSS_BASE + "v1.css");
                File dst_de = new File(Constants.FI_FILE_XML_BASE + "fi_de_html/");
                File dst_fr = new File(Constants.FI_FILE_XML_BASE + "fi_fr_html/");
                if (src.exists()) {
                    if (dst_de.exists())
                        FileUtils.copyFileToDirectory(src, dst_de);
                    if (dst_fr.exists())
                        FileUtils.copyFileToDirectory(src, dst_fr);
                }
            } catch (IOException e) {
                // TODO: Unhandled!
            }
        }

        if (CmlOptions.GENERATE_REPORTS == true) {
            parse_errors.append("<br/>");
            parse_errors
                    .append("<p>Number of medications with package information: " + tot_med_counter + "</p>");
            parse_errors.append("<p>Number of medications in generated database: " + med_counter + "</p>");
            parse_errors.append("<p>Number of errors in database: " + errors + "</p>");
            parse_errors.append("<p>Number of missing registration number: " + missing_regnr_str + "</p>");
            parse_errors.append("<p>Number of missing package info: " + missing_pack_info + "</p>");
            parse_errors.append("<p>Number of missing atc codes: " + missing_atc_code + "</p>");
            parse_errors.append("<br/>");
            // Write and close report file
            parse_errors.writeHtmlToFile();
            parse_errors.getBWriter().close();

            // Write owner error report to file
            ParseReport owner_errors = new ParseReport(Constants.FILE_OWNER_REPORT, CmlOptions.DB_LANGUAGE,
                    "html");
            String report_style_str = FileOps.readCSSfromFile(Constants.FILE_REPORT_CSS_BASE + ".css");
            owner_errors.addStyleSheet(report_style_str);
            if (CmlOptions.DB_LANGUAGE.equals("de"))
                owner_errors.addHtmlHeader("Schweizer Arzneimittel-Kompendium", Constants.FI_DB_VERSION);
            else if (CmlOptions.DB_LANGUAGE.equals("fr"))
                owner_errors.addHtmlHeader("Compendium des Mdicaments Suisse", Constants.FI_DB_VERSION);
            owner_errors.append(owner_errors.treemapToHtmlTable(tm_owner_error));
            owner_errors.writeHtmlToFile();
            owner_errors.getBWriter().close();
            // Dump to console...
            /*
            for (Map.Entry<String, ArrayList<String>> entry : tm_owner_error.entrySet()) {
               String author = entry.getKey();
               ArrayList<String> list = entry.getValue();
               for (String error : list)
                  System.out.println(author + " -> " + error);
            }
            */
        }

        if (CmlOptions.INDICATIONS_REPORT == true) {
            // Dump everything to file
            bw_indications.write("Total number of words: " + tm_indications.size() + "\n\n");
            for (Map.Entry<String, String> entry : tm_indications.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                bw_indications.write(key + " [" + value + "]\n");
            }
            bw_indications.close();
        }

        if (CmlOptions.DB_LANGUAGE.equals("de")) {
            // Dump set to file, currently we do this only for German
            File atccodes_file = new File("./output/atc_codes_used_set.txt");
            if (!atccodes_file.exists()) {
                atccodes_file.getParentFile().mkdirs();
                atccodes_file.createNewFile();
            }
            FileWriter fwriter = new FileWriter(atccodes_file.getAbsoluteFile());
            BufferedWriter bwriter = new BufferedWriter(fwriter);

            Iterator<String> set_iterator = atccode_set.iterator();
            while (set_iterator.hasNext()) {
                bwriter.write(set_iterator.next() + "\n");
            }
            bwriter.close();
        }

        System.out.println("");

    } catch (IOException e) {
        e.printStackTrace();
    }
}