private AdvancedIncQueryEngine createEngine() {
    boolean wildcardMode =
        IncQueryGUIPlugin.getDefault()
            .getPreferenceStore()
            .getBoolean(PreferenceConstants.WILDCARD_MODE);
    boolean dynamicEMFMode =
        IncQueryGUIPlugin.getDefault()
            .getPreferenceStore()
            .getBoolean(PreferenceConstants.DYNAMIC_EMF_MODE);

    try {
      AdvancedIncQueryEngine engine =
          AdvancedIncQueryEngine.createUnmanagedEngine(
              key.getNotifier(), wildcardMode, dynamicEMFMode);
      return engine;
    } catch (IncQueryException e) {
      logger.log(
          new Status(
              IStatus.ERROR,
              IncQueryGUIPlugin.PLUGIN_ID,
              "Could not retrieve IncQueryEngine for " + key.getNotifier(),
              e));
      return null;
    }
  }
  @Override
  public void init(IViewSite site, IMemento memento) throws PartInitException {
    super.init(site, memento);
    int detailsState = IFlyoutPreferences.STATE_OPEN;
    int patternsState = IFlyoutPreferences.STATE_COLLAPSED;
    if (memento != null) {
      if (memento.getInteger(DETAILS_VIEW_FLYOUT_STATE) != null) {
        detailsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE);
      }
      if (memento.getInteger(PATTERNS_VIEWER_FLYOUT_STATE) != null) {
        patternsState = memento.getInteger(DETAILS_VIEW_FLYOUT_STATE);
      }
      if (memento.getString(PACKAGE_PRESENTATION_STATE) != null) {
        mementoPackagePresentation = memento.getString(PACKAGE_PRESENTATION_STATE);
      }
    }
    detailsViewerFlyoutPreferences =
        new FlyoutPreferences(IFlyoutPreferences.DOCK_EAST, detailsState, 300);
    patternsViewerFlyoutPreferences =
        new FlyoutPreferences(IFlyoutPreferences.DOCK_WEST, patternsState, 100);

    IncQueryGUIPlugin.getDefault()
        .getPreferenceStore()
        .setDefault(PreferenceConstants.WILDCARD_MODE, true);
  }
/**
 * A top level element in the {@link QueryExplorer}'s tree viewer, which is actually displayed.
 * Instances of this class are always associated with an instance of {@link
 * PatternMatcherRootContentKey}. The child elements of this {@link CompositeContent} will consist
 * of {@link PatternMatcherContent} instances.
 *
 * @author Tamas Szabo (itemis AG)
 */
public class PatternMatcherRootContent
    extends CompositeContent<RootContent, PatternMatcherContent> {

  private final Map<String, PatternMatcherContent> mapping;
  private ContentChildren<PatternMatcherContent> children;
  private final PatternMatcherRootContentKey key;
  private IncQueryEngineLifecycleListener taintListener;
  private final ILog logger = IncQueryGUIPlugin.getDefault().getLog();
  private IStatus contentStatus;

  public PatternMatcherRootContent(RootContent parent, PatternMatcherRootContentKey key) {
    super(parent);
    this.children = new ContentChildren<PatternMatcherContent>();
    this.taintListener = new ContentEngineTaintListener();
    this.mapping = Maps.newHashMap();
    this.key = key;

    AdvancedIncQueryEngine engine = key.getEngine();
    if (engine == null) {
      key.setEngine(createEngine());
    }
    if (engine != null) {
      engine.addLifecycleListener(taintListener);
    }
  }

  private AdvancedIncQueryEngine createEngine() {
    boolean wildcardMode =
        IncQueryGUIPlugin.getDefault()
            .getPreferenceStore()
            .getBoolean(PreferenceConstants.WILDCARD_MODE);
    boolean dynamicEMFMode =
        IncQueryGUIPlugin.getDefault()
            .getPreferenceStore()
            .getBoolean(PreferenceConstants.DYNAMIC_EMF_MODE);

    try {
      AdvancedIncQueryEngine engine =
          AdvancedIncQueryEngine.createUnmanagedEngine(
              key.getNotifier(), wildcardMode, dynamicEMFMode);
      return engine;
    } catch (IncQueryException e) {
      logger.log(
          new Status(
              IStatus.ERROR,
              IncQueryGUIPlugin.PLUGIN_ID,
              "Could not retrieve IncQueryEngine for " + key.getNotifier(),
              e));
      return null;
    }
  }

  public void addMatcher(
      IncQueryEngine engine, IQuerySpecification<?> specification, boolean generated) {
    String fqn = specification.getFullyQualifiedName();

    PatternMatcherContent pm = new PatternMatcherContent(this, engine, specification, generated);
    this.mapping.put(fqn, pm);

    if (generated) {
      // generated matchers are inserted in front of the list
      this.children.addChild(0, pm);
    } else {
      // generic matchers are inserted in the list according to the order in the eiq file
      this.children.addChild(pm);
    }
  }

  public void removeMatcher(String patternFqn) {
    // if the pattern is first deactivated then removed, than the matcher corresponding matcher is
    // disposed
    PatternMatcherContent matcher = this.mapping.get(patternFqn);
    if (matcher != null) {
      matcher.dispose();
      this.children.removeChild(matcher);
      this.mapping.remove(patternFqn);
    }
  }

  @Override
  public void dispose() {
    super.dispose();
    AdvancedIncQueryEngine engine = key.getEngine();
    if (engine != null) {
      engine.removeLifecycleListener(taintListener);
    }
  }

  public boolean isTainted() {
    AdvancedIncQueryEngine engine = key.getEngine();
    return (engine == null) ? true : engine.isTainted();
  }

  public PatternMatcherRootContentKey getKey() {
    return key;
  }

  public IEditorPart getEditorPart() {
    return this.key.getEditorPart();
  }

  public Notifier getNotifier() {
    return this.key.getNotifier();
  }

  public void registerPattern(final IQuerySpecification<?>... patterns) {
    IncQueryEngine engine = null;
    try {
      engine = key.getEngine();

      if (engine.getBaseIndex().isInWildcardMode()) {
        addMatchersForPatterns(patterns);
      } else {
        engine
            .getBaseIndex()
            .coalesceTraversals(
                new Callable<Void>() {
                  @Override
                  public Void call() {
                    addMatchersForPatterns(patterns);
                    return null;
                  }
                });
      }
      contentStatus = Status.OK_STATUS;
    } catch (IncQueryException ex) {
      reportMatcherError("Cannot initialize pattern matcher engine.", ex);
    } catch (InvocationTargetException e) {
      reportMatcherError(
          "Error during pattern matcher construction: " + e.getCause().getMessage(), e.getCause());
    }
  }

  private void reportMatcherError(String message, Throwable t) {
    if (t != null) {
      contentStatus = new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, message, t);
    } else {
      contentStatus = new Status(IStatus.ERROR, IncQueryGUIPlugin.PLUGIN_ID, message);
    }
    logger.log(contentStatus);
    getParent().getViewer().refresh(this);
  }

  private void addMatchersForPatterns(IQuerySpecification<?>... queries) {
    for (IQuerySpecification<?> query : queries) {
      boolean isGenerated = QueryExplorerPatternRegistry.getInstance().isGenerated(query);
      addMatcher(key.getEngine(), query, isGenerated);
    }
  }

  public void unregisterPattern(IQuerySpecification<?> specification) {
    removeMatcher(specification.getFullyQualifiedName());
  }

  private class ContentEngineTaintListener implements IncQueryEngineLifecycleListener {

    @Override
    public void engineBecameTainted(String description, Throwable t) {
      reportMatcherError(description, t);
    }

    @Override
    public void matcherInstantiated(IncQueryMatcher<? extends IPatternMatch> matcher) {}

    @Override
    public void engineWiped() {}

    @Override
    public void engineDisposed() {}
  }

  @Override
  public String getText() {
    return this.key.toString();
  }

  @Override
  public IObservableList getChildren() {
    return children;
  }

  @Override
  public Iterator<PatternMatcherContent> getChildrenIterator() {
    return children.getElements().iterator();
  }

  public IStatus getStatus() {
    return contentStatus;
  }
}