class MissingElementsMerger extends AbstractElementMerger {

    @Override
    public void mergeNodes(List<Node> fromParents, Element toParent, Document toDocument) throws PDUStitchingException {
        final String threshold = fromParents.get(0).getAttributes().getNamedItem("threshold").getNodeValue();
        toParent.setAttribute("threshold", threshold);
        final NumberFormatter numberFormatter = getNumberFormatter();
        final Map<String, List<Node>> globalInfoNodesListMap = collectNodes(fromParents, GLOBAL_INFO_NAME);
        Map<String, Double> overs = new HashMap<>();
        for (Map.Entry<String, List<Node>> globalInfoNodesEntry : globalInfoNodesListMap.entrySet()) {
            final String[] key = globalInfoNodesEntry.getKey().split(SEPARATOR);
            final String gridValue = key[0];
            final String viewValue = key[1];
            int value = 0;
            int over = 0;
            final List<Node> globalInfoNodes = globalInfoNodesEntry.getValue();
            for (Node globalInfoNode : globalInfoNodes) {
                final Node valueNode = globalInfoNode.getAttributes().getNamedItem("value");
                final Node overNode = globalInfoNode.getAttributes().getNamedItem("over");
                if (valueNode != null && overNode != null) {
                    value += Integer.parseInt(valueNode.getNodeValue());
                    final int over1 = Integer.parseInt(overNode.getNodeValue());
                    over += over1;
                }
            }
            String percentage;
            try {
                overs.put(globalInfoNodesEntry.getKey(), (double) over);
                final double percentageAsDouble = ((double) value / over) * 100;
                percentage = numberFormatter.valueToString(percentageAsDouble);
            } catch (ParseException e) {
                throw new PDUStitchingException("Could not format number: " + e.getMessage());
            }
            final Element globalInfoElement = toDocument.createElement(GLOBAL_INFO_NAME);
            globalInfoElement.setAttribute("grid", gridValue);
            globalInfoElement.setAttribute("view", viewValue);
            globalInfoElement.setAttribute("value", String.valueOf(value));
            globalInfoElement.setAttribute("over", String.valueOf(over));
            globalInfoElement.setAttribute("percentage", percentage);
            toParent.appendChild(globalInfoElement);
        }

        final List<NewNode> newMissingNodes = getNewMissingNodes(fromParents);
        final List<NewNode> sortedNodes = new ArrayList<>();
        for (NewNode newNode : newMissingNodes) {
            boolean inserted = false;
            for (int j = 0; j < sortedNodes.size(); j++) {
                final NewNode sortedNode = sortedNodes.get(j);
                if (newNode.startTime.before(sortedNode.startTime)) {
                    sortedNodes.add(j, newNode);
                    inserted = true;
                    break;
                }
            }
            if (!inserted) {
                sortedNodes.add(newNode);
            }
        }
        for (NewNode node : sortedNodes) {
            String key = node.gridValue.split(",")[0].trim() + SEPARATOR + node.viewValue;
            double over = overs.get(key);
            try {
                final String percentage = numberFormatter.valueToString((node.value / over) * 100);
                addNode(toDocument, toParent, node, percentage);
            } catch (ParseException e) {
                throw new PDUStitchingException("Could not format number: " + e.getMessage());
            }
        }
    }

}