class JavaPropertiesResource extends ResourceFilter {

    @Override
    public void merge(InputStream baseStream, OutputStream outStream, LanguageBundle languageBundle,
            FilterOptions options) throws IOException, ResourceFilterException {

        Map<String, String> kvMap = Utils.createKeyValueMap(languageBundle.getResourceStrings());

        BufferedReader baseReader = new BufferedReader(new InputStreamReader(baseStream, getCharset()));
        PrintWriter outWriter = new PrintWriter(new OutputStreamWriter(outStream, getCharset()));

        BreakIterator brkItr = Utils.getWordBreakIterator(options);

        String line = null;
        StringBuilder logicalLineBuf = new StringBuilder();
        List<String> orgLines = new ArrayList<String>(8); // default size - up
                                                          // to 8 continuous
                                                          // lines
        do {
            // logical line that may define a single property, or empty line
            String logicalLine = null;

            line = baseReader.readLine();

            if (line == null) {
                // End of the file - emit lines not yet processed.
                if (!orgLines.isEmpty()) {
                    logicalLine = logicalLineBuf.toString();
                }
            } else {
                String normLine = stripLeadingSpaces(line);

                if (orgLines.isEmpty()) {
                    // No continuation marker in the previous line
                    if (normLine.startsWith("#") || normLine.startsWith("!")) {
                        // Comment line - print the original line
                        outWriter.println(line);
                    } else if (isContinuationLine(normLine)) {
                        // Continue to the next line
                        logicalLineBuf.append(normLine, 0, normLine.length() - 1);
                        orgLines.add(line);
                    } else {
                        logicalLine = line;
                    }
                } else {
                    // Continued from the previous line
                    if (normLine.endsWith("\\")) {
                        // continues to the next line
                        logicalLineBuf.append(normLine.substring(0, normLine.length() - 1));
                        orgLines.add(line); // preserve the original line
                    } else {
                        // terminating the current logical property line
                        logicalLineBuf.append(normLine);
                        orgLines.add(line);
                        logicalLine = logicalLineBuf.toString();
                    }
                }
            }

            if (logicalLine != null) {
                PropDef pd = PropDef.parseLine(logicalLine);
                if (pd != null && kvMap.containsKey(pd.getKey())) {
                    // Preserve original leading spaces
                    String firstLine = orgLines.isEmpty() ? line : orgLines.get(0);
                    int len = getLeadingSpacesLength(firstLine);
                    if (len > 0) {
                        outWriter.print(firstLine.substring(0, len));
                    }
                    // Write the property key and value
                    String key = pd.getKey();
                    String value = escapeMessagePattern(kvMap.get(key), msgPatEsc);
                    PropDef modPd = new PropDef(key, value , pd.getSeparator(), null);
                    modPd.print(outWriter, brkItr, (enc == Encoding.UTF_8));
                } else {
                    if (orgLines.isEmpty()) {
                        // Single line
                        outWriter.println(line);
                    } else {
                        // Multiple lines
                        for (String orgLine : orgLines) {
                            outWriter.println(orgLine);
                        }
                    }
                }

                // Clear continuation data
                orgLines.clear();
                logicalLineBuf.setLength(0);
            }
        } while (line != null);

        outWriter.flush();
    }

    public  JavaPropertiesResource(Encoding enc, MessagePatternEscape msgPatEsc);
    public  JavaPropertiesResource();

}