/* package */ static UserLibrary createFromString(Reader reader) throws IOException {
    Element cpElement;
    try {
      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);
    } finally {
      reader.close();
    }

    if (!cpElement.getNodeName().equalsIgnoreCase(TAG_USERLIBRARY)) {
      throw new IOException(Messages.file_badFormat);
    }
    // String version= cpElement.getAttribute(TAG_VERSION);
    // in case we update the format: add code to read older versions

    boolean isSystem = Boolean.valueOf(cpElement.getAttribute(TAG_SYSTEMLIBRARY)).booleanValue();

    NodeList list = cpElement.getChildNodes();
    int length = list.getLength();

    ArrayList res = new ArrayList(length);
    for (int i = 0; i < length; ++i) {
      Node node = list.item(i);

      if (node.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element) node;
        if (element.getNodeName().equals(TAG_ARCHIVE)) {
          String path = element.getAttribute(TAG_PATH);
          IPath sourceAttach =
              element.hasAttribute(TAG_SOURCEATTACHMENT)
                  ? new Path(element.getAttribute(TAG_SOURCEATTACHMENT))
                  : null;
          IPath sourceAttachRoot =
              element.hasAttribute(TAG_SOURCEATTACHMENTROOT)
                  ? new Path(element.getAttribute(TAG_SOURCEATTACHMENTROOT))
                  : null;
          NodeList children = element.getElementsByTagName("*"); // $NON-NLS-1$
          boolean[] foundChildren = new boolean[children.getLength()];
          NodeList attributeList =
              ClasspathEntry.getChildAttributes(
                  ClasspathEntry.TAG_ATTRIBUTES, children, foundChildren);
          IIncludePathAttribute[] extraAttributes =
              ClasspathEntry.decodeExtraAttributes(attributeList);
          attributeList =
              ClasspathEntry.getChildAttributes(
                  ClasspathEntry.TAG_ACCESS_RULES, children, foundChildren);
          IAccessRule[] accessRules = ClasspathEntry.decodeAccessRules(attributeList);
          IIncludePathEntry entry =
              JavaScriptCore.newLibraryEntry(
                  new Path(path),
                  sourceAttach,
                  sourceAttachRoot,
                  accessRules,
                  extraAttributes,
                  false /*not exported*/);
          res.add(entry);
        }
      }
    }

    IIncludePathEntry[] entries =
        (IIncludePathEntry[]) res.toArray(new IIncludePathEntry[res.size()]);

    return new UserLibrary(entries, isSystem);
  }