public static List<Configurable> buildConfigurablesList(
      final ConfigurableEP<Configurable>[] extensions,
      final Configurable[] components,
      @Nullable ConfigurableFilter filter) {
    final List<Configurable> result = new ArrayList<Configurable>();
    for (Configurable component : components) {
      if (!isSuppressed(component, filter)) {
        result.add(component);
      }
    }

    final Map<String, ConfigurableWrapper> idToConfigurable =
        new HashMap<String, ConfigurableWrapper>();
    for (ConfigurableEP<Configurable> ep : extensions) {
      final Configurable configurable = ConfigurableWrapper.wrapConfigurable(ep);
      if (isSuppressed(configurable, filter)) continue;
      if (configurable instanceof ConfigurableWrapper) {
        final ConfigurableWrapper wrapper = (ConfigurableWrapper) configurable;
        idToConfigurable.put(wrapper.getId(), wrapper);
      } else {
        //        dumpConfigurable(configurablesExtensionPoint, ep, configurable);
        ContainerUtil.addIfNotNull(configurable, result);
      }
    }
    // modify configurables (append children)
    for (final String id : idToConfigurable.keySet()) {
      final ConfigurableWrapper wrapper = idToConfigurable.get(id);
      final String parentId = wrapper.getParentId();
      if (parentId != null) {
        final ConfigurableWrapper parent = idToConfigurable.get(parentId);
        if (parent != null) {
          idToConfigurable.put(parentId, parent.addChild(wrapper));
        } else {
          LOG.debug("Can't find parent for " + parentId + " (" + wrapper + ")");
        }
      }
    }
    // leave only roots (i.e. configurables without parents)
    for (final Iterator<String> iterator = idToConfigurable.keySet().iterator();
        iterator.hasNext(); ) {
      final String key = iterator.next();
      final ConfigurableWrapper wrapper = idToConfigurable.get(key);
      final String parentId = wrapper.getParentId();
      if (parentId != null && idToConfigurable.containsKey(parentId)) {
        iterator.remove(); // remove only processed parents
      }
    }
    ContainerUtil.addAll(result, idToConfigurable.values());

    return result;
  }
 @Nullable
 public static <T> T cast(@NotNull Class<T> type, UnnamedConfigurable configurable) {
   if (configurable instanceof ConfigurableWrapper) {
     ConfigurableWrapper wrapper = (ConfigurableWrapper) configurable;
     if (wrapper.myConfigurable == null) {
       Class<?> configurableType = wrapper.getExtensionPoint().getConfigurableType();
       if (configurableType != null) {
         if (!type.isAssignableFrom(configurableType)) {
           return null; // do not create configurable that cannot be cast to the specified type
         }
       } else if (type == Configurable.Assistant.class || type == OptionalConfigurable.class) {
         return null; // do not create configurable from ConfigurableProvider which replaces
                      // OptionalConfigurable
       }
     }
     configurable = wrapper.getConfigurable();
   }
   return type.isInstance(configurable) ? type.cast(configurable) : null;
 }