@SuppressWarnings("unchecked")
  default T mergeIgnoringDuplicates(Archive<?> source, String base, Filter<ArchivePath> filter) {
    if (!base.startsWith("/")) {
      base = "/" + base;
    }
    // Get existing contents from source archive
    final Map<ArchivePath, Node> sourceContent = source.getContent();

    // Add each asset from the source archive
    for (final Map.Entry<ArchivePath, Node> contentEntry : sourceContent.entrySet()) {
      final Node node = contentEntry.getValue();
      ArchivePath nodePath = contentEntry.getKey();
      if (!nodePath.get().startsWith(base)) {
        continue;
      }
      if (!filter.include(nodePath)) {
        continue;
      }
      if (contains(nodePath)) {
        continue;
      }
      nodePath = new BasicPath(nodePath.get().replaceFirst(base, ""));
      // Delegate
      if (node.getAsset() == null) {
        addAsDirectory(nodePath);
      } else {
        add(node.getAsset(), nodePath);
      }
    }
    return (T) this;
  }
  /**
   * {@inheritDoc}
   *
   * @see org.jboss.shrinkwrap.api.Archive#getContent(org.jboss.shrinkwrap.api.Filter)
   */
  @Override
  public Map<ArchivePath, Node> getContent(Filter<ArchivePath> filter) {
    Validate.notNull(filter, "Filter must be specified");

    Map<ArchivePath, Node> filteredContent = new HashMap<ArchivePath, Node>();
    for (Map.Entry<ArchivePath, NodeImpl> contentEntry : content.entrySet()) {
      if (filter.include(contentEntry.getKey())) {
        if (!contentEntry.getKey().equals(new BasicPath("/"))) {
          filteredContent.put(contentEntry.getKey(), contentEntry.getValue());
        }
      }
    }
    return filteredContent;
  }