class XmlXPathReplace extends TransformationOperation<XmlXPathReplace> {

    @Override
    protected TOExecutionResult execution(File transformedAppFolder, TransformationContext transformationContext) {
        File fileToBeChanged = getAbsoluteFile(transformedAppFolder, transformationContext);
        TOExecutionResult result = null;
        NodeList nodes = null;

        try {
            File readFile = getOrCreateReadFile(transformedAppFolder, transformationContext);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(readFile);
            nodes = (NodeList) xpathExpression.evaluate(doc, XPathConstants.NODESET);

            if (nodes.getLength() > 0) {
                for (int idx = 0; idx < nodes.getLength(); idx++) {
                    Node node = nodes.item(idx);
                    switch (mode) {
                        case TextReplace:
                            node.setTextContent((String) replacementObject);
                            break;
                        case ElementReplace:
                            Node newNode = doc.importNode((Element) replacementObject, true);
                            node.getParentNode().replaceChild(newNode, node);
                            break;
                        case Removal:
                            node.getParentNode().removeChild(node);
                            break;
                    }
                }
                Transformer xformer = TransformerFactory.newInstance().newTransformer();
                xformer.transform(new DOMSource(doc), new StreamResult(fileToBeChanged));
            }
        } catch (ParserConfigurationException | SAXException | IOException e) {
            result = TOExecutionResult.error(this,
                    new TransformationOperationException("File content could not be parsed properly in XML format", e));
        } catch (TransformerException e) {
            result = TOExecutionResult.error(this, e);
        } catch (XPathExpressionException e) {
            result = TOExecutionResult.error(this,
                    new TransformationOperationException("XPathExpression could not be evaluated correctly", e));
        }

        if (result == null) {
            if (nodes != null) {
                String details = String.format(
                        "File %s has had %d node(s) where modification was applied based on xml xpath expression '%s'",
                        getRelativePath(), nodes.getLength(), xpathExpressionString);
                if (nodes.getLength() > 0) {
                    result = TOExecutionResult.success(this, details);
                } else {
                    result = TOExecutionResult.noOp(this, details);
                }
            } else {
                result = TOExecutionResult.error(this,
                        new TransformationOperationException("XPathExpression could not be evaluated correctly"));
            }
        }
        return result;
    }

    public  XmlXPathReplace(String xpathExpressionString);
    public  XmlXPathReplace(String xpathExpressionString, Element replacementElement);
    public  XmlXPathReplace(String xpathExpressionString, String replacementString);

}