docs: @SuppressWarnings("checkstyle:npathcomplexity")
      public static IClasspathEntry[][] decodeClasspath(String projectName, IPath projectRootAbsoluteFullPath, String xmlClasspath,
              Map<IPath, UnknownXmlElements> unknownElements) throws IOException, ClasspathEntry.AssertionFailedException {
  
          final List<IClasspathEntry> paths = new ArrayList<>();
          IClasspathEntry defaultOutput = null;
          final Element cpElement;
  
          try (StringReader reader = new StringReader(xmlClasspath);) {
              final DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
              cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
          } catch (SAXException e) {
              throw new IOException(Messages.file_badFormat);
          } catch (ParserConfigurationException e) {
              throw new IOException(Messages.file_badFormat);
          }
  
          if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
              throw new IOException(Messages.file_badFormat);
          }
          NodeList list = cpElement.getElementsByTagName(ClasspathEntry.TAG_CLASSPATHENTRY);
          int length = list.getLength();
  
          for (int i = 0; i < length; ++i) {
              final Node node = list.item(i);
              if (node.getNodeType() == Node.ELEMENT_NODE) {
                  final IClasspathEntry entry = elementDecode((Element) node, projectName, projectRootAbsoluteFullPath, unknownElements);
                  if (entry != null) {
                      if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
                          // separate output
                          defaultOutput = entry;
                      } else {
                          paths.add(entry);
                      }
                  }
              }
          }
          final int pathSize = paths.size();
          final IClasspathEntry[][] entries = new IClasspathEntry[2][];
          entries[0] = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
          paths.toArray(entries[0]);
          if (defaultOutput != null) {
              // ensure output is last item
              entries[0][pathSize] = defaultOutput;
          }
          paths.clear();
          list = cpElement.getElementsByTagName(ClasspathEntry.TAG_REFERENCED_ENTRY);
          length = list.getLength();
  
          for (int i = 0; i < length; ++i) {
              final Node node = list.item(i);
              if (node.getNodeType() == Node.ELEMENT_NODE) {
                  final IClasspathEntry entry = elementDecode((Element) node, projectName, projectRootAbsoluteFullPath, unknownElements);
                  if (entry != null) {
                      paths.add(entry);
                  }
              }
          }
          entries[1] = new IClasspathEntry[paths.size()];
          paths.toArray(entries[1]);
  
          return entries;
      }