src/main/java/net/wasdev/wlp/common/plugins/util/InstallFeatureUtil.java
private Set<String> getServerXmlFeatures(Set<String> origResult, File serverFile, List<File> parsedXmls) {
        Set<String> result = origResult;
        List<File> updatedParsedXmls = parsedXmls != null ? parsedXmls : new ArrayList<File>();
        File canonicalServerFile;
        try {
            canonicalServerFile = serverFile.getCanonicalFile();
        } catch (IOException e) {
            // skip this server.xml if its path cannot be queried
            warn("The server file " + serverFile + " cannot be accessed. Skipping its features.");
            debug(e);
            return result;
        }
        updatedParsedXmls.add(canonicalServerFile);
        if (canonicalServerFile.exists()) {
            try {
                Document doc = new XmlDocument() {
                    public Document getDocument(File file) throws IOException, ParserConfigurationException, SAXException {
                        createDocument(file);
                        return doc;
                    }
                }.getDocument(canonicalServerFile);
                Element root = doc.getDocumentElement();
                NodeList nodes = root.getChildNodes();

                for (int i = 0; i < nodes.getLength(); i++) {
                    if (nodes.item(i) instanceof Element) {
                        Element child = (Element) nodes.item(i);
                        if ("featureManager".equals(child.getNodeName())) {
                            if (result == null) {
                                result = new HashSet<String>();
                            }
                            result.addAll(parseFeatureManagerNode(child));
                        } else if ("include".equals(child.getNodeName())){
                            result = parseIncludeNode(result, canonicalServerFile, child, updatedParsedXmls);
                        }
                    }
                }
            } catch (IOException | ParserConfigurationException | SAXException e) {
                // just skip this server.xml if it cannot be parsed
                warn("The server file " + serverFile + " cannot be parsed. Skipping its features.");
                debug(e);
                return result;
            }
        }
        return result;
    }
private Set<String> getServerXmlFeatures(Set<String> origResult, File serverFile, List<File> parsedXmls) {
        Set<String> result = origResult;
        List<File> updatedParsedXmls = parsedXmls != null ? parsedXmls : new ArrayList<File>();
        File canonicalServerFile;
        try {
            canonicalServerFile = serverFile.getCanonicalFile();
        } catch (IOException e) {
            // skip this server.xml if its path cannot be queried
            warn("The server file " + serverFile + " cannot be accessed. Skipping its features.");
            debug(e);
            return result;
        }
        updatedParsedXmls.add(canonicalServerFile);
        if (canonicalServerFile.exists()) {
            try {
                Document doc = new XmlDocument() {
                    public Document getDocument(File file) throws IOException, ParserConfigurationException, SAXException {
                        createDocument(file);
                        return doc;
                    }
                }.getDocument(canonicalServerFile);
                Element root = doc.getDocumentElement();
                NodeList nodes = root.getChildNodes();

                for (int i = 0; i < nodes.getLength(); i++) {
                    if (nodes.item(i) instanceof Element) {
                        Element child = (Element) nodes.item(i);
                        if ("featureManager".equals(child.getNodeName())) {
                            if (result == null) {
                                result = new HashSet<String>();
                            }
                            result.addAll(parseFeatureManagerNode(child));
                        } else if ("include".equals(child.getNodeName())){
                            result = parseIncludeNode(result, canonicalServerFile, child, updatedParsedXmls);
                        }
                    }
                }
            } catch (IOException | ParserConfigurationException | SAXException e) {
                // just skip this server.xml if it cannot be parsed
                warn("The server file " + serverFile + " cannot be parsed. Skipping its features.");
                debug(e);
                return result;
            }
        }
        return result;
    }
Adds features from the given server file into the origResult or a new set
if origResult is null.

@param origResult
The features that have been parsed so far.
@param serverFile
The server XML file.
@param parsedXmls
The list of XML files that have been parsed so far.
@return The set of features to install, or empty set if the cumulatively
parsed xml files only have featureManager sections but no
features to install, or null if there are no valid xml files or
they have no featureManager section