public void convert(
     final Document document,
     Element server,
     Set<DataSource> from,
     Properties catalinaProperties) {
   final List<Element> globalNamingResourcesList =
       getChildElements(server, "GlobalNamingResources");
   if (globalNamingResourcesList.size() > 1) {
     throw new InvalidNodeException(
         "Unable to determine existing DataSources.  Found multiple GlobalNamingResource Elements in server.xml");
   }
   final Set<String> dataSourceIds = new HashSet<String>(from.size());
   for (DataSource dataSource : from) {
     dataSourceIds.add(dataSource.getId());
   }
   final Map<String, Element> dataSourceElements = new HashMap<String, Element>();
   Element globalNamingResources;
   if (globalNamingResourcesList.isEmpty()) {
     globalNamingResources = document.createElement("GlobalNamingResources");
     server.appendChild(globalNamingResources);
   } else {
     globalNamingResources = globalNamingResourcesList.get(0);
     final List<Element> resources = getChildElements(globalNamingResources, "Resource");
     for (int i = 0; i < resources.size(); i++) {
       Element resource = (Element) resources.get(i);
       if (DATA_SOURCE_TYPE.equals(resource.getAttribute("type"))) {
         final String name = parseProperties(resource.getAttribute("name"), catalinaProperties);
         if (dataSourceIds.contains(name)) {
           dataSourceElements.put(name, resource);
         } else if (dataSourceConverter.isDataSourceFactorySupported(
             resource, catalinaProperties)) {
           globalNamingResources.removeChild(resource);
         }
       }
     }
   }
   for (DataSource dataSource : from) {
     if (dataSourceElements.get(dataSource.getId()) == null) {
       final Element dataSourceElement = document.createElement("Resource");
       dataSourceElement.setAttribute("type", DATA_SOURCE_TYPE);
       dataSourceConverter.convert(document, dataSourceElement, dataSource, catalinaProperties);
       globalNamingResources.appendChild(dataSourceElement);
     } else {
       dataSourceConverter.convert(
           document, dataSourceElements.get(dataSource.getId()), dataSource, catalinaProperties);
     }
   }
 }
 public Set<DataSource> convert(final Element server, Properties catalinaProperties) {
   final List<Element> globalNamingResourcesList =
       getChildElements(server, "GlobalNamingResources");
   if (globalNamingResourcesList.size() == 0) {
     return EMPTY_DATA_SOURCES;
   }
   if (globalNamingResourcesList.size() > 1) {
     logger.warn(
         "Unable to determine existing DataSources.  Found multiple GlobalNamingResource Elements in server.xml");
     return EMPTY_DATA_SOURCES;
   }
   final Element globalNamingResources = (Element) globalNamingResourcesList.get(0);
   final Set<DataSource> dataSources = new LinkedHashSet<DataSource>();
   final List<Element> resources = getChildElements(globalNamingResources, "Resource");
   for (int i = 0; i < resources.size(); i++) {
     Element resource = (Element) resources.get(i);
     if (DATA_SOURCE_TYPE.equals(resource.getAttribute("type"))) {
       try {
         final DataSource dataSource = dataSourceConverter.convert(resource, catalinaProperties);
         if (dataSource != null) {
           dataSources.add(dataSource);
         }
       } catch (AttributeNotFoundException e) {
         logger.warn(
             "Error reading tc Runtime configuration.  Ignoring invalid Data Source found in server.xml.  Cause: "
                 + e.getMessage());
       }
     }
   }
   return dataSources;
 }