public void loadState(final Element element) {
   myInjections.clear();
   final THashMap<String, LanguageInjectionSupport> supports =
       new THashMap<String, LanguageInjectionSupport>();
   for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
     supports.put(support.getId(), support);
   }
   loadStateOld(
       element,
       supports.get(LanguageInjectionSupport.XML_SUPPORT_ID),
       supports.get(LanguageInjectionSupport.JAVA_SUPPORT_ID));
   for (Element child : (List<Element>) element.getChildren("injection")) {
     final String key = child.getAttributeValue("injector-id");
     final LanguageInjectionSupport support = supports.get(key);
     final BaseInjection injection =
         support == null ? new BaseInjection(key) : support.createInjection(child);
     injection.loadState(child);
     InjectionPlace[] places = dropKnownInvalidPlaces(injection.getInjectionPlaces());
     if (places != null) { // not all places were removed
       injection.setInjectionPlaces(places);
       myInjections.get(key).add(injection);
     }
   }
   importPlaces(getDefaultInjections());
 }
  private void mergeWithDefaultConfiguration() {
    final ArrayList<Configuration> cfgList = new ArrayList<Configuration>();
    for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
      final String config = support.getDefaultConfigUrl();
      final URL url = config == null ? null : support.getClass().getResource(config);
      if (url != null) {
        try {
          cfgList.add(load(url.openStream()));
        } catch (Exception e) {
          LOG.warn(e);
        }
      }
    }
    final THashSet<Object> visited = new THashSet<Object>();
    for (IdeaPluginDescriptor pluginDescriptor : PluginManager.getPlugins()) {
      if (pluginDescriptor instanceof IdeaPluginDescriptorImpl
          && !((IdeaPluginDescriptorImpl) pluginDescriptor).isEnabled()) continue;
      final ClassLoader loader = pluginDescriptor.getPluginClassLoader();
      if (!visited.add(loader)) continue;
      if (loader instanceof PluginClassLoader && ((PluginClassLoader) loader).getUrls().isEmpty())
        continue;
      try {
        final Enumeration<URL> enumeration = loader.getResources("META-INF/languageInjections.xml");
        if (enumeration == null) continue;
        while (enumeration.hasMoreElements()) {
          URL url = enumeration.nextElement();
          if (!visited.add(url.getFile())) continue; // for DEBUG mode
          try {
            cfgList.add(load(url.openStream()));
          } catch (Exception e) {
            LOG.warn(e);
          }
        }
      } catch (Exception e) {
        LOG.warn(e);
      }
    }

    final ArrayList<BaseInjection> originalInjections = new ArrayList<BaseInjection>();
    final ArrayList<BaseInjection> newInjections = new ArrayList<BaseInjection>();
    myDefaultInjections = new ArrayList<BaseInjection>();
    for (String supportId : InjectorUtils.getActiveInjectionSupportIds()) {
      for (Configuration cfg : cfgList) {
        final List<BaseInjection> imported = cfg.getInjections(supportId);
        myDefaultInjections.addAll(imported);
        importInjections(getInjections(supportId), imported, originalInjections, newInjections);
      }
    }
    replaceInjections(newInjections, originalInjections);
  }
  @Override
  public Configurable[] getConfigurables() {
    if (myConfigurables == null) {
      final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
      for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
        ContainerUtil.addAll(configurables, support.createSettings(myProject, myConfiguration));
      }
      Collections.sort(
          configurables,
          new Comparator<Configurable>() {
            public int compare(final Configurable o1, final Configurable o2) {
              return Comparing.compare(o1.getDisplayName(), o2.getDisplayName());
            }
          });
      myConfigurables = configurables.toArray(new Configurable[configurables.size()]);
    }

    return myConfigurables;
  }
  public void loadState(final Element element, final boolean mergeWithOriginalAndCompile) {
    final THashMap<String, LanguageInjectionSupport> supports =
        new THashMap<String, LanguageInjectionSupport>();
    for (LanguageInjectionSupport support :
        Extensions.getExtensions(LanguageInjectionSupport.EP_NAME)) {
      supports.put(support.getId(), support);
    }
    loadStateOld(
        element,
        supports.get(LanguageInjectionSupport.XML_SUPPORT_ID),
        supports.get(LanguageInjectionSupport.JAVA_SUPPORT_ID));
    for (Element child : (List<Element>) element.getChildren("injection")) {
      final String key = child.getAttributeValue("injector-id");
      final LanguageInjectionSupport support = supports.get(key);
      final BaseInjection injection =
          support == null ? new BaseInjection(key) : support.createInjection(child);
      injection.loadState(child);
      myInjections.get(key).add(injection);
    }
    setInstrumentationType(JDOMExternalizerUtil.readField(element, INSTRUMENTATION_TYPE_NAME));
    setLanguageAnnotation(JDOMExternalizerUtil.readField(element, LANGUAGE_ANNOTATION_NAME));
    setPatternAnnotation(JDOMExternalizerUtil.readField(element, PATTERN_ANNOTATION_NAME));
    setSubstAnnotation(JDOMExternalizerUtil.readField(element, SUBST_ANNOTATION_NAME));
    setResolveReferences(readBoolean(element, RESOLVE_REFERENCES, true));
    setUseDfaIfAvailable(readBoolean(element, USE_DFA_IF_AVAILABLE, false));
    setIncludeUncomputablesAsLiterals(
        readBoolean(element, INCLUDE_UNCOMPUTABLES_AS_LITERALS, false));

    if (mergeWithOriginalAndCompile) {
      mergeWithDefaultConfiguration();

      for (String supportId : InjectorUtils.getActiveInjectionSupportIds()) {
        for (BaseInjection injection : getInjections(supportId)) {
          injection.initializePlaces(true);
        }
      }
    }
  }
 public boolean setHostInjectionEnabled(
     final PsiLanguageInjectionHost host,
     final Collection<String> languages,
     final boolean enabled) {
   final ArrayList<BaseInjection> originalInjections = new ArrayList<BaseInjection>();
   final ArrayList<BaseInjection> newInjections = new ArrayList<BaseInjection>();
   for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
     for (BaseInjection injection : getInjections(support.getId())) {
       if (!languages.contains(injection.getInjectedLanguageId())) continue;
       boolean replace = false;
       final ArrayList<InjectionPlace> newPlaces = new ArrayList<InjectionPlace>();
       for (InjectionPlace place : injection.getInjectionPlaces()) {
         if (place.isEnabled() != enabled
             && place.getElementPattern() != null
             && (place.getElementPattern().accepts(host)
                 || place.getElementPattern().accepts(host.getParent()))) {
           newPlaces.add(place.enabled(enabled));
           replace = true;
         } else newPlaces.add(place);
       }
       if (replace) {
         originalInjections.add(injection);
         final BaseInjection newInjection = injection.copy();
         newInjection.setInjectionPlaces(newPlaces.toArray(new InjectionPlace[newPlaces.size()]));
         newInjections.add(newInjection);
       }
     }
   }
   if (!originalInjections.isEmpty()) {
     replaceInjectionsWithUndo(
         host.getProject(),
         newInjections,
         originalInjections,
         Collections.<PsiElement>emptyList());
     return true;
   }
   return false;
 }
  private void createActions(ToolbarDecorator decorator) {
    final Consumer<BaseInjection> consumer =
        new Consumer<BaseInjection>() {
          public void consume(final BaseInjection injection) {
            addInjection(injection);
          }
        };
    final Factory<BaseInjection> producer =
        new NullableFactory<BaseInjection>() {
          public BaseInjection create() {
            final InjInfo info = getSelectedInjection();
            return info == null ? null : info.injection;
          }
        };
    for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) {
      ContainerUtil.addAll(myAddActions, support.createAddActions(myProject, consumer));
      final AnAction action = support.createEditAction(myProject, producer);
      myEditActions.put(
          support.getId(),
          action == null
              ? AbstractLanguageInjectionSupport.createDefaultEditAction(myProject, producer)
              : action);
      mySupports.put(support.getId(), support);
    }
    Collections.sort(
        myAddActions,
        new Comparator<AnAction>() {
          public int compare(final AnAction o1, final AnAction o2) {
            return Comparing.compare(
                o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText());
          }
        });
    decorator.disableUpDownActions();
    decorator.setAddActionUpdater(
        new AnActionButtonUpdater() {
          @Override
          public boolean isEnabled(AnActionEvent e) {
            return !myAddActions.isEmpty();
          }
        });
    decorator.setAddAction(
        new AnActionButtonRunnable() {
          @Override
          public void run(AnActionButton button) {
            performAdd(button);
          }
        });
    decorator.setRemoveActionUpdater(
        new AnActionButtonUpdater() {
          @Override
          public boolean isEnabled(AnActionEvent e) {
            boolean enabled = false;
            for (InjInfo info : getSelectedInjections()) {
              if (!info.bundled) {
                enabled = true;
                break;
              }
            }
            return enabled;
          }
        });
    decorator.setRemoveAction(
        new AnActionButtonRunnable() {
          @Override
          public void run(AnActionButton button) {
            performRemove();
          }
        });

    decorator.setEditActionUpdater(
        new AnActionButtonUpdater() {
          @Override
          public boolean isEnabled(AnActionEvent e) {
            AnAction edit = getEditAction();
            if (edit != null) edit.update(e);
            return edit != null && edit.getTemplatePresentation().isEnabled();
          }
        });
    decorator.setEditAction(
        new AnActionButtonRunnable() {
          @Override
          public void run(AnActionButton button) {
            performEditAction();
          }
        });
    decorator.addExtraAction(
        new DumbAwareActionButton("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) {

          @Override
          public boolean isEnabled() {
            return getEditAction() != null;
          }

          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            final InjInfo injection = getSelectedInjection();
            if (injection != null) {
              addInjection(injection.injection.copy());
              // performEditAction(e);
            }
          }
        });

    decorator.addExtraAction(
        new DumbAwareActionButton(
            "Enable Selected Injections",
            "Enable Selected Injections",
            PlatformIcons.SELECT_ALL_ICON) {

          @Override
          public void actionPerformed(@NotNull final AnActionEvent e) {
            performSelectedInjectionsEnabled(true);
          }
        });
    decorator.addExtraAction(
        new DumbAwareActionButton(
            "Disable Selected Injections",
            "Disable Selected Injections",
            PlatformIcons.UNSELECT_ALL_ICON) {

          @Override
          public void actionPerformed(@NotNull final AnActionEvent e) {
            performSelectedInjectionsEnabled(false);
          }
        });

    new DumbAwareAction("Toggle") {
      @Override
      public void update(@NotNull AnActionEvent e) {
        SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myInjectionsTable);
        e.getPresentation().setEnabled(supply == null || !supply.isPopupActive());
      }

      @Override
      public void actionPerformed(@NotNull final AnActionEvent e) {
        performToggleAction();
      }
    }.registerCustomShortcutSet(
        new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), myInjectionsTable);

    if (myInfos.length > 1) {
      AnActionButton shareAction =
          new DumbAwareActionButton("Move to IDE Scope", null, PlatformIcons.IMPORT_ICON) {
            {
              addCustomUpdater(
                  new AnActionButtonUpdater() {
                    @Override
                    public boolean isEnabled(AnActionEvent e) {
                      CfgInfo cfg = getTargetCfgInfo(getSelectedInjections());
                      e.getPresentation()
                          .setText(
                              cfg == getDefaultCfgInfo()
                                  ? "Move to IDE Scope"
                                  : "Move to Project Scope");
                      return cfg != null;
                    }
                  });
            }

            @Override
            public void actionPerformed(@NotNull final AnActionEvent e) {
              final List<InjInfo> injections = getSelectedInjections();
              final CfgInfo cfg = getTargetCfgInfo(injections);
              if (cfg == null) return;
              for (InjInfo info : injections) {
                if (info.cfgInfo == cfg) continue;
                if (info.bundled) continue;
                info.cfgInfo.injectionInfos.remove(info);
                cfg.addInjection(info.injection);
              }
              final int[] selectedRows = myInjectionsTable.getSelectedRows();
              myInjectionsTable.getListTableModel().setItems(getInjInfoList(myInfos));
              TableUtil.selectRows(myInjectionsTable, selectedRows);
            }

            @Nullable
            private CfgInfo getTargetCfgInfo(final List<InjInfo> injections) {
              CfgInfo cfg = null;
              for (InjInfo info : injections) {
                if (info.bundled) {
                  continue;
                }
                if (cfg == null) cfg = info.cfgInfo;
                else if (cfg != info.cfgInfo) return info.cfgInfo;
              }
              if (cfg == null) return null;
              for (CfgInfo info : myInfos) {
                if (info != cfg) return info;
              }
              throw new AssertionError();
            }
          };
      shareAction.setShortcut(
          new CustomShortcutSet(
              KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)));
      decorator.addExtraAction(shareAction);
    }
    decorator.addExtraAction(
        new DumbAwareActionButton("Import", "Import", AllIcons.Actions.Install) {

          @Override
          public void actionPerformed(@NotNull final AnActionEvent e) {
            doImportAction(e.getDataContext());
            updateCountLabel();
          }
        });
    decorator.addExtraAction(
        new DumbAwareActionButton("Export", "Export", AllIcons.Actions.Export) {

          @Override
          public void actionPerformed(@NotNull final AnActionEvent e) {
            final List<BaseInjection> injections = getInjectionList(getSelectedInjections());
            final VirtualFileWrapper wrapper =
                FileChooserFactory.getInstance()
                    .createSaveFileDialog(
                        new FileSaverDescriptor("Export Selected Injections to File...", "", "xml"),
                        myProject)
                    .save(null, null);
            if (wrapper == null) return;
            final Configuration configuration = new Configuration();
            configuration.setInjections(injections);
            final Document document = new Document(configuration.getState());
            try {
              JDOMUtil.writeDocument(document, wrapper.getFile(), "\n");
            } catch (IOException ex) {
              final String msg = ex.getLocalizedMessage();
              Messages.showErrorDialog(
                  myProject,
                  msg != null && msg.length() > 0 ? msg : ex.toString(),
                  "Export Failed");
            }
          }

          @Override
          public boolean isEnabled() {
            return !getSelectedInjections().isEmpty();
          }
        });
  }