public void listRemoved(String listName) {
   FavoritesListener[] listeners =
       myListeners.toArray(new FavoritesListener[myListeners.size()]);
   for (FavoritesListener listener : listeners) {
     listener.listRemoved(listName);
   }
 }
  private <T> boolean findListToRemoveFrom(
      @NotNull String name,
      @NotNull final List<T> elements,
      final Convertor<T, AbstractUrl> convertor) {
    Collection<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name);
    if (elements.size() > 1) {
      final List<T> sublist = elements.subList(0, elements.size() - 1);
      for (T obj : sublist) {
        AbstractUrl objUrl = convertor.convert(obj);
        final TreeItem<Pair<AbstractUrl, String>> item = findNextItem(objUrl, list);
        if (item == null || item.getChildren() == null) return false;
        list = item.getChildren();
      }
    }

    TreeItem<Pair<AbstractUrl, String>> found = null;
    AbstractUrl url = convertor.convert(elements.get(elements.size() - 1));
    if (url == null) return false;
    for (TreeItem<Pair<AbstractUrl, String>> pair : list) {
      if (url.equals(pair.getData().getFirst())) {
        found = pair;
        break;
      }
    }

    if (found != null) {
      list.remove(found);
      fireListeners.rootsChanged(name);
      return true;
    }
    return false;
  }
 public void rootsChanged(String listName) {
   FavoritesListener[] listeners =
       myListeners.toArray(new FavoritesListener[myListeners.size()]);
   for (FavoritesListener listener : listeners) {
     listener.rootsChanged(listName);
   }
 }
 public void removeRootByIndexes(String name, List<Integer> elementsIndexes) {
   List<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name);
   assert list != null;
   for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) {
     assert index >= 0 && index < list.size();
     final TreeItem<Pair<AbstractUrl, String>> item = list.get(index);
     list = item.getChildren();
   }
   assert list != null && !list.isEmpty();
   list.remove(elementsIndexes.get(elementsIndexes.size() - 1).intValue());
   fireListeners.rootsChanged(name);
 }
  private static void readFavoritesOneLevel(
      Element list, Project project, Collection<TreeItem<Pair<AbstractUrl, String>>> result) {
    final List listChildren = list.getChildren(FAVORITES_ROOT);
    if (listChildren == null || listChildren.isEmpty()) return;

    for (Object favorite : listChildren) {
      final Element favoriteElement = (Element) favorite;
      final String className = favoriteElement.getAttributeValue(CLASS_NAME);
      final AbstractUrl abstractUrl = readUrlFromElement(favoriteElement, project);
      if (abstractUrl != null) {
        final TreeItem<Pair<AbstractUrl, String>> treeItem =
            new TreeItem<Pair<AbstractUrl, String>>(Pair.create(abstractUrl, className));
        result.add(treeItem);
        readFavoritesOneLevel(favoriteElement, project, treeItem.getChildren());
      }
    }
  }
 public synchronized boolean removeRoot(
     @NotNull String name, @NotNull List<AbstractTreeNode> elements) {
   final Convertor<AbstractTreeNode, AbstractUrl> convertor =
       new Convertor<AbstractTreeNode, AbstractUrl>() {
         @Override
         public AbstractUrl convert(AbstractTreeNode obj) {
           return createUrlByElement(obj.getValue(), myProject);
         }
       };
   boolean result = true;
   for (AbstractTreeNode element : elements) {
     final List<AbstractTreeNode> path =
         TaskDefaultFavoriteListProvider.getPathToUsualNode(element);
     result &= findListToRemoveFrom(name, path.subList(1, path.size()), convertor);
   }
   return result;
 }
 public synchronized boolean editRoot(
     @NotNull String name,
     @NotNull List<Integer> elementsIndexes,
     final AbstractTreeNode newElement) {
   List<TreeItem<Pair<AbstractUrl, String>>> list = getFavoritesListRootUrls(name);
   assert list != null;
   for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) {
     assert index >= 0 && index < list.size();
     final TreeItem<Pair<AbstractUrl, String>> item = list.get(index);
     list = item.getChildren();
   }
   assert list != null && !list.isEmpty();
   final Object value = newElement.getValue();
   final AbstractUrl urlByElement = createUrlByElement(value, myProject);
   if (urlByElement == null) return false;
   list.set(
       elementsIndexes.get(elementsIndexes.size() - 1).intValue(),
       new TreeItem<Pair<AbstractUrl, String>>(
           Pair.create(urlByElement, newElement.getClass().getName())));
   return true;
 }
 public synchronized void removeFavoritesListener(FavoritesListener listener) {
   myListeners.remove(listener);
 }
 public synchronized void addFavoritesListener(FavoritesListener listener) {
   myListeners.add(listener);
 }
  public synchronized boolean addRoot(
      @NotNull String name,
      @NotNull List<AbstractTreeNode> parentElements,
      final AbstractTreeNode newElement,
      @Nullable AbstractTreeNode sibling) {
    final List<TreeItem<Pair<AbstractUrl, String>>> items = myName2FavoritesRoots.get(name);
    if (items == null) return false;
    AbstractUrl url = createUrlByElement(newElement.getValue(), myProject);
    if (url == null) return false;
    final TreeItem<Pair<AbstractUrl, String>> newItem =
        new TreeItem<Pair<AbstractUrl, String>>(Pair.create(url, newElement.getClass().getName()));

    if (parentElements.isEmpty()) {
      // directly to list
      if (sibling != null) {
        TreeItem<Pair<AbstractUrl, String>> after = null;
        AbstractUrl siblingUrl = createUrlByElement(sibling.getValue(), myProject);
        int idx = -1;
        for (int i = 0; i < items.size(); i++) {
          TreeItem<Pair<AbstractUrl, String>> item = items.get(i);
          if (item.getData().getFirst().equals(siblingUrl)) {
            idx = i;
            break;
          }
        }
        if (idx != -1) {
          items.add(idx, newItem);
        } else {
          items.add(newItem);
        }
      } else {
        items.add(newItem);
      }

      fireListeners.rootsChanged(name);
      return true;
    }

    Collection<TreeItem<Pair<AbstractUrl, String>>> list = items;
    TreeItem<Pair<AbstractUrl, String>> item = null;
    for (AbstractTreeNode obj : parentElements) {
      AbstractUrl objUrl = createUrlByElement(obj.getValue(), myProject);
      item = findNextItem(objUrl, list);
      if (item == null) return false;
      list = item.getChildren();
    }

    if (sibling != null) {
      TreeItem<Pair<AbstractUrl, String>> after = null;
      AbstractUrl siblingUrl = createUrlByElement(sibling.getValue(), myProject);
      for (TreeItem<Pair<AbstractUrl, String>> treeItem : list) {
        if (treeItem.getData().getFirst().equals(siblingUrl)) {
          after = treeItem;
          break;
        }
      }
      if (after == null) {
        item.addChild(newItem);
      } else {
        item.addChildAfter(newItem, after);
      }
    } else {
      item.addChild(newItem);
    }
    fireListeners.rootsChanged(name);
    return true;
  }