public static JsonObject build(JsonObject lockJson, JsonObject packageJson,
            MultiValuedMap<String, String> dependencyMap, boolean skipDevDependencies) {
        final JsonObjectBuilder payloadBuilder = Json.createObjectBuilder();
        addProjectInfo(packageJson, payloadBuilder);

        // NPM Audit expects 'requires' to be an object containing key/value
        // pairs corresponding to the module name (key) and version (value).
        final JsonObjectBuilder requiresBuilder = Json.createObjectBuilder();

        if (packageJson.containsKey("dependencies")) {
            packageJson.getJsonObject("dependencies").entrySet()
                    .stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue,
                            (oldValue, newValue) -> newValue, TreeMap::new))
                    .forEach((key, value) -> {
                        if (NodePackageAnalyzer.shouldSkipDependency(key, ((JsonString) value).getString())) {
                            return;
                        }
                        requiresBuilder.add(key, value);
                        dependencyMap.put(key, value.toString());
                    });
        }

        if (!skipDevDependencies && packageJson.containsKey("devDependencies")) {
            packageJson.getJsonObject("devDependencies").entrySet()
                    .stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue,
                            (oldValue, newValue) -> newValue, TreeMap::new))
                    .forEach((key, value) -> {
                        if (NodePackageAnalyzer.shouldSkipDependency(key, ((JsonString) value).getString())) {
                            return;
                        }
                        requiresBuilder.add(key, value);
                        dependencyMap.put(key, value.toString());
                    });
        }

        payloadBuilder.add("requires", requiresBuilder.build());

        final JsonObjectBuilder dependenciesBuilder = Json.createObjectBuilder();
        final int lockJsonVersion = lockJson.containsKey("lockfileVersion") ? lockJson.getInt("lockfileVersion") : 1;
        JsonObject dependencies = lockJson.getJsonObject("dependencies");
        if (lockJsonVersion >= 2 && dependencies == null) {
            dependencies = lockJson.getJsonObject("packages");
        }

        if (dependencies != null) {
            dependencies.forEach((k, value) -> {
                String key = k;
                final int indexOfNodeModule = key.lastIndexOf(NodePackageAnalyzer.NODE_MODULES_DIRNAME + "/");
                if (indexOfNodeModule >= 0) {
                    key = key.substring(indexOfNodeModule + NodePackageAnalyzer.NODE_MODULES_DIRNAME.length() + 1);
                }

                JsonObject dep = ((JsonObject) value);

                //After Version 3, dependencies can't be taken directly from package-lock.json
                if (lockJsonVersion > 2 && dep.containsKey("dependencies") && dep.get("dependencies") instanceof JsonObject) {
                    JsonObjectBuilder depBuilder = Json.createObjectBuilder(dep);
                    depBuilder.remove("dependencies");
                    depBuilder.add("requires", dep.get("dependencies"));
                    dep = depBuilder.build();
                }
                
                final String version = dep.getString("version", "");
                final boolean isDev = dep.getBoolean("dev", false);
                if (skipDevDependencies && isDev) {
                    return;
                }
                if (NodePackageAnalyzer.shouldSkipDependency(key, version)) {
                    return;
                }
                dependencyMap.put(key, version);
                dependenciesBuilder.add(key, buildDependencies(dep, dependencyMap));
            });
        }
        payloadBuilder.add("dependencies", dependenciesBuilder.build());

        addConstantElements(payloadBuilder);
        return payloadBuilder.build();
    }
@Test
    public void testSanitizePackage() {
        InputStream in = BaseTest.getResourceAsStream(this, "nodeaudit/package-lock.json");
        final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
        try (JsonReader jsonReader = Json.createReader(in)) {
            JsonObject packageJson = jsonReader.readObject();
            JsonObject sanitized = NpmPayloadBuilder.build(packageJson, dependencyMap, false);

            Assert.assertTrue(sanitized.containsKey("name"));
            Assert.assertTrue(sanitized.containsKey("version"));
            Assert.assertTrue(sanitized.containsKey("dependencies"));
            Assert.assertTrue(sanitized.containsKey("requires"));

            JsonObject requires = sanitized.getJsonObject("requires");
            Assert.assertTrue(requires.containsKey("bcrypt-nodejs"));
            Assert.assertEquals("^0.0.3", requires.getString("bcrypt-nodejs"));

            Assert.assertFalse(sanitized.containsKey("lockfileVersion"));
            Assert.assertFalse(sanitized.containsKey("random"));
        }
    }