@Override
  public void writeExternal(Element rootElement) throws WriteExternalException {
    LOG.assertTrue(!isDisposed(), "Already disposed!");

    Element element = new Element(ELEMENT);
    if (myName != null) {
      element.setAttribute(LIBRARY_NAME_ATTR, myName);
    }
    if (myKind != null) {
      element.setAttribute(LIBRARY_TYPE_ATTR, myKind.getKindId());
      final Object state = myProperties.getState();
      if (state != null) {
        final Element propertiesElement = XmlSerializer.serialize(state, SERIALIZATION_FILTERS);
        if (propertiesElement != null
            && (!propertiesElement.getContent().isEmpty()
                || !propertiesElement.getAttributes().isEmpty())) {
          element.addContent(propertiesElement.setName(PROPERTIES_ELEMENT));
        }
      }
    }
    ArrayList<OrderRootType> storableRootTypes = new ArrayList<OrderRootType>();
    storableRootTypes.addAll(Arrays.asList(OrderRootType.getAllTypes()));
    if (myKind != null) {
      storableRootTypes.addAll(Arrays.asList(myKind.getAdditionalRootTypes()));
    }
    for (OrderRootType rootType : sortRootTypes(storableRootTypes)) {
      final VirtualFilePointerContainer roots = myRoots.get(rootType);
      if (roots.size() == 0 && rootType.skipWriteIfEmpty()) continue; // compatibility iml/ipr
      final Element rootTypeElement = new Element(rootType.name());
      roots.writeExternal(rootTypeElement, ROOT_PATH_ELEMENT);
      element.addContent(rootTypeElement);
    }
    myJarDirectories.writeExternal(element);
    rootElement.addContent(element);
  }
  public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    final LibraryImpl library = (LibraryImpl) o;

    if (!myJarDirectories.equals(library.myJarDirectories)) return false;
    if (myName != null ? !myName.equals(library.myName) : library.myName != null) return false;
    if (myRoots != null ? !myRoots.equals(library.myRoots) : library.myRoots != null) return false;
    if (myKind != null ? !myKind.equals(library.myKind) : library.myKind != null) return false;
    if (myProperties != null
        ? !myProperties.equals(library.myProperties)
        : library.myProperties != null) return false;

    return true;
  }
 private LibraryImpl(
     @NotNull LibraryImpl from, LibraryImpl newSource, ModifiableRootModel rootModel) {
   this(from.myLibraryTable, rootModel, newSource, from.myName, from.myKind);
   assert !from.isDisposed();
   if (from.myKind != null && from.myProperties != null) {
     myProperties = myKind.createDefaultProperties();
     //noinspection unchecked
     myProperties.loadState(from.myProperties.getState());
   }
   for (OrderRootType rootType : getAllRootTypes()) {
     final VirtualFilePointerContainer thisContainer = myRoots.get(rootType);
     final VirtualFilePointerContainer thatContainer = from.myRoots.get(rootType);
     thisContainer.addAll(thatContainer);
   }
   myJarDirectories.copyFrom(from.myJarDirectories);
 }