class AmdJsResource extends ResourceFilter {

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

        // Load entire base content to CharSequence
        CharArrayWriter caw = new CharArrayWriter();
        try (InputStreamReader reader = new InputStreamReader(new BomInputStream(baseStream), "UTF-8")) {
            char[] buf = new char[1024];
            int len;
            while ((len = reader.read(buf)) >= 0) {
                caw.write(buf, 0, len);
            }
        }

        char[] baseContent = caw.toCharArray();
        CharArrayReader car = new CharArrayReader(baseContent);

        // Parse base JS and extract key-value data
        AstRoot root = new Parser().parse(car,  null , 1);
        KeyValueVisitor visitor = new KeyValueVisitor();
        root.visitAll(visitor);
        LinkedHashMap<String, ValueData> baseKVMap = visitor.elements;

        // Merge translated value
        Map<String, String> kvMap = Utils.createKeyValueMap(languageBundle.getResourceStrings());

        try (OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(outStream), StandardCharsets.UTF_8)) {
            int idx = 0;    // current index in baseContent
            for (Entry<String, ValueData> baseEntry : baseKVMap.entrySet()) {
                String key = baseEntry.getKey();
                ValueData valData = baseEntry.getValue();
                int start = valData.getStart();
                int end = valData.getEnd();

                if (idx < start) {
                    // write out text up to the start of the original key-value expression
                    writer.write(baseContent, idx, start - idx);
                    idx = start;
                }

                String translatedValue = kvMap.get(key);
                if (translatedValue == null) {
                    // use original value
                    writer.write(baseContent, idx, end - idx);
                } else {
                    // use translated value

                    // opening quote
                    char quote = baseContent[idx];
                    writer.write(quote);

                    // translation value
                    writer.write(escapeString(translatedValue, quote));

                    // closing quote
                    assert quote == baseContent[end - 1];
                    writer.write(quote);
                }
                idx = end;
            }
            if (idx < baseContent.length) {
                writer.write(baseContent, idx, baseContent.length - idx);
            }
        }
    }

}