/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.sdk.internal.workspace;

import java.io.PrintStream;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.scout.commons.CollectionUtility;
import org.eclipse.scout.commons.WeakEventListener;
import org.eclipse.scout.commons.holders.Holder;
import org.eclipse.scout.nls.sdk.internal.NlsCore;
import org.eclipse.scout.nls.sdk.model.workspace.project.INlsProject;
import org.eclipse.scout.sdk.Texts;
import org.eclipse.scout.sdk.extensions.runtime.bundles.RuntimeBundles;
import org.eclipse.scout.sdk.extensions.runtime.classes.IRuntimeClasses;
import org.eclipse.scout.sdk.extensions.targetpackage.DefaultTargetPackage;
import org.eclipse.scout.sdk.icon.IIconProvider;
import org.eclipse.scout.sdk.internal.ScoutSdk;
import org.eclipse.scout.sdk.util.type.TypeUtility;
import org.eclipse.scout.sdk.util.typecache.IPrimaryTypeTypeHierarchy;
import org.eclipse.scout.sdk.util.typecache.ITypeHierarchyChangedListener;
import org.eclipse.scout.sdk.workspace.IScoutBundle;
import org.eclipse.scout.sdk.workspace.IScoutBundleComparator;
import org.eclipse.scout.sdk.workspace.IScoutBundleFilter;
import org.eclipse.scout.sdk.workspace.IScoutBundleGraphVisitor;
import org.eclipse.scout.sdk.workspace.ScoutBundleComparators;

/**
 * <h3>{@link ScoutBundle}</h3>
 * 
 * @author Matthias Villiger
 * @since 3.9.0 30.01.2013
 */
public class ScoutBundle implements IScoutBundle {

  private static final Pattern REGEX_LEADING_DOTS = Pattern.compile("^\\.*");

  private final Map<String, IPluginModelBase> m_allDependencies;
  private final Set<ScoutBundle> m_parentBundles;
  private final Set<ScoutBundle> m_childBundles;
  private final Set<String> m_dependencyIssues;
  private final IScoutBundleComparator m_defaultComparator;
  private final String m_type;
  private final IJavaProject m_javaProject;
  private final IProject m_project;
  private final IPluginModelBase m_pluginModelBase;
  private final String m_symbolicName;
  private final boolean m_isFragment;
  private final boolean m_isBinary;
  private final String m_id;
  private final int m_hash;

  private ITypeHierarchyChangedListener m_textProvidersChangedListener;
  private IEclipsePreferences m_projectPreferences;
  private volatile Holder<INlsProject> m_nlsProjectHolder;
  private volatile Holder<INlsProject> m_docsNlsProjectHolder;
  private volatile IIconProvider m_iconProvider;
  private volatile IPackageFragmentRoot m_rootPackage;

  public ScoutBundle(IPluginModelBase bundle, IProgressMonitor monitor) {
    m_pluginModelBase = bundle;
    m_parentBundles = new HashSet<ScoutBundle>();
    m_childBundles = new HashSet<ScoutBundle>();
    m_dependencyIssues = new HashSet<String>();
    m_allDependencies = getAllDependenciesImpl(bundle, monitor);
    m_type = RuntimeBundles.getBundleType(this);
    m_javaProject = getJavaProject(bundle);
    m_isBinary = m_javaProject == null;
    m_project = m_isBinary ? null : getJavaProject().getProject();
    m_symbolicName = bundle.getBundleDescription().getSymbolicName();
    m_defaultComparator = ScoutBundleComparators.getSymbolicNameLevenshteinDistanceComparator(m_symbolicName);
    m_isFragment = bundle.getBundleDescription().getHost() != null;
    m_id = "{" + m_symbolicName + "@type=" + m_type + "@fragment=" + m_isFragment + "@binary=" + m_isBinary + "}";
    m_hash = m_id.hashCode();

    m_nlsProjectHolder = null;
    m_docsNlsProjectHolder = null;
    m_projectPreferences = null;
    m_iconProvider = null;
    m_rootPackage = null;
  }

  /**
   * returns a valid java project that can be edited or null if no editable java project can be found.<br>
   * An editable java project is a java project that exists, is not read-only and has at least one writable package
   * fragment root.
   * 
   * @param bundle
   * @return
   */
  private IJavaProject getJavaProject(IPluginModelBase bundle) {
    if (bundle.getUnderlyingResource() != null) {
      IProject project = bundle.getUnderlyingResource().getProject();
      if (project != null) {
        IJavaProject jp = JavaCore.create(project);
        if (jp != null && jp.exists() && !jp.isReadOnly()) {
          try {
            IPackageFragmentRoot[] packageFragmentRoots = jp.getPackageFragmentRoots();
            if (packageFragmentRoots != null) {
              for (IPackageFragmentRoot root : packageFragmentRoots) {
                if (root != null && !root.isArchive() && !root.isReadOnly() && !root.isExternal()) {
                  return jp;
                }
              }
            }
          }
          catch (JavaModelException e) {
            BundleDescription bundleDescription = bundle.getBundleDescription();
            if (bundleDescription != null) {
              ScoutSdk.logError("Unable to evaluate package fragment roots of bundle '" + bundleDescription.getSymbolicName() + "'. The bundle will be handled as binary.", e);
            }
            else {
              ScoutSdk.logError("Unable to evaluate package fragment roots. The bundle will be handled as binary.", e);
            }
          }
        }
      }
    }
    return null;
  }

  @Override
  public String toString() {
    return m_id;
  }

  @Override
  public String getType() {
    return m_type;
  }

  @Override
  public String getSymbolicName() {
    return m_symbolicName;
  }

  @Override
  public int hashCode() {
    return m_hash;
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof ScoutBundle)) {
      return false;
    }
    return toString().equals(obj.toString());
  }

  @Override
  public Set<? extends IScoutBundle> getDirectParentBundles() {
    return CollectionUtility.hashSet(m_parentBundles);
  }

  @Override
  public Set<ScoutBundle> getDirectChildBundles() {
    return CollectionUtility.hashSet(m_childBundles);
  }

  @Override
  public IScoutBundle[] getChildBundles(IScoutBundleFilter filter, boolean includeThis) {
    P_BundleCollector bundleCollector = new P_BundleCollector(filter);
    visit(bundleCollector, includeThis, false);
    return bundleCollector.getElements();
  }

  @Override
  public IScoutBundle getChildBundle(IScoutBundleFilter filter, boolean includeThis) {
    return getChildBundle(filter, m_defaultComparator, includeThis);
  }

  @Override
  public IScoutBundle getChildBundle(IScoutBundleFilter filter, IScoutBundle reference, boolean includeThis) {
    IScoutBundleComparator c = ScoutBundleComparators.getSymbolicNameLevenshteinDistanceComparator(reference.getSymbolicName());
    return getChildBundle(filter, c, includeThis);
  }

  @Override
  public IScoutBundle getChildBundle(IScoutBundleFilter filter, IScoutBundleComparator comparator, boolean includeThis) {
    P_SingleBundleByLevelCollector bundleCollector = new P_SingleBundleByLevelCollector(filter, comparator);
    visit(bundleCollector, includeThis, false);
    return bundleCollector.getElement();
  }

  @Override
  public IScoutBundle[] getParentBundles(IScoutBundleFilter filter, boolean includeThis) {
    P_BundleCollector bundleCollector = new P_BundleCollector(filter);
    visit(bundleCollector, includeThis, true);
    return bundleCollector.getElements();
  }

  @Override
  public IScoutBundle getParentBundle(IScoutBundleFilter filter, boolean includeThis) {
    return getParentBundle(filter, m_defaultComparator, includeThis);
  }

  @Override
  public IScoutBundle getParentBundle(IScoutBundleFilter filter, IScoutBundle reference, boolean includeThis) {
    IScoutBundleComparator c = ScoutBundleComparators.getSymbolicNameLevenshteinDistanceComparator(reference.getSymbolicName());
    return getParentBundle(filter, c, includeThis);
  }

  @Override
  public IScoutBundle getParentBundle(IScoutBundleFilter filter, IScoutBundleComparator comparator, boolean includeThis) {
    P_SingleBundleByLevelCollector bundleCollector = new P_SingleBundleByLevelCollector(filter, comparator);
    visit(bundleCollector, includeThis, true);
    return bundleCollector.getElement();
  }

  @Override
  public IJavaProject getJavaProject() {
    return m_javaProject;
  }

  @Override
  public IProject getProject() {
    return m_project;
  }

  @Override
  public synchronized IEclipsePreferences getPreferences() {
    if (m_projectPreferences == null && getProject() != null) {
      IScopeContext prefScope = new ProjectScope(getProject());
      m_projectPreferences = prefScope.getNode(ScoutSdk.getDefault().getBundle().getSymbolicName());
    }
    return m_projectPreferences;
  }

  @Override
  public boolean contains(IJavaElement e) {
    if (!TypeUtility.exists(e)) {
      return false;
    }
    String contributingBundle = ScoutWorkspace.getInstance().getBundleGraphInternal().getContributingBundleSymbolicName(e);
    return m_symbolicName.equals(contributingBundle);
  }

  @Override
  public INlsProject getNlsProject() {
    Holder<INlsProject> result = m_nlsProjectHolder;
    if (result == null) {
      synchronized (this) {
        result = m_nlsProjectHolder;
        if (result == null) {
          try {
            registerNlsServiceListener();
            result = new Holder<INlsProject>(INlsProject.class, null);
            INlsProject nlsProject = NlsCore.getNlsWorkspace().getNlsProject(new Object[]{TypeUtility.getType(IRuntimeClasses.TEXTS), this});
            result.setValue(nlsProject);
            m_nlsProjectHolder = result;
          }
          catch (CoreException e) {
            ScoutSdk.logError("error loading NLS project for: '" + getSymbolicName() + "'.", e);
          }
        }
      }
    }
    return result.getValue();
  }

  @Override
  public INlsProject getDocsNlsProject() {
    Holder<INlsProject> result = m_docsNlsProjectHolder;
    if (result == null) {
      synchronized (this) {
        result = m_docsNlsProjectHolder;
        if (result == null) {
          try {
            registerNlsServiceListener();
            result = new Holder<INlsProject>(INlsProject.class, null);
            INlsProject nlsProject = NlsCore.getNlsWorkspace().getNlsProject(new Object[]{TypeUtility.getType(IRuntimeClasses.IDocumentationTextProviderService), this});
            result.setValue(nlsProject);
            m_docsNlsProjectHolder = result;
          }
          catch (CoreException e) {
            ScoutSdk.logError("error loading NLS project for: '" + getSymbolicName() + "'.", e);
          }
        }
      }
    }
    return result.getValue();
  }

  @Override
  public String getPackageName(String appendix) {
    if (appendix == null) {
      return getSymbolicName();
    }

    appendix = REGEX_LEADING_DOTS.matcher(appendix).replaceAll("").trim();
    if (appendix.length() > 0) {
      appendix = "." + appendix;
    }
    return getSymbolicName() + appendix;
  }

  @Override
  public IPackageFragment getPackageFragment(String packageFqn) throws JavaModelException {
    IPackageFragmentRoot result = m_rootPackage;
    if (result == null) {
      synchronized (this) {
        result = m_rootPackage;
        if (result == null) {
          Path src = new Path(IPath.SEPARATOR + getSymbolicName() + IPath.SEPARATOR + TypeUtility.DEFAULT_SOURCE_FOLDER_NAME);
          result = getJavaProject().findPackageFragmentRoot(src);
          m_rootPackage = result;
        }
      }
    }
    return result.getPackageFragment(packageFqn);
  }

  @Override
  public String getDefaultPackage(String packageId) {
    String pck = DefaultTargetPackage.get(this, packageId);
    if (pck == null) {
      throw new IllegalArgumentException("invalid package id");
    }
    return getPackageName(pck);
  }

  @Override
  public IIconProvider getIconProvider() {
    IIconProvider result = m_iconProvider;
    if (result == null) {
      synchronized (this) {
        result = m_iconProvider;
        if (result == null) {
          m_iconProvider = result = new ScoutProjectIcons(this);
        }
      }
    }
    return result;
  }

  @Override
  public boolean isBinary() {
    return m_isBinary;
  }

  @Override
  public boolean isFragment() {
    return m_isFragment;
  }

  @Override
  public Object getAdapter(Class adapter) {
    if (IScoutBundle.class == adapter || IAdaptable.class == adapter || ScoutBundle.class == adapter) {
      return this;
    }
    if (!isBinary()) {
      if (IResource.class == adapter || ISchedulingRule.class == adapter) {
        return getProject();
      }
      if (IJavaProject.class == adapter || IParent.class == adapter || IJavaElement.class == adapter || IOpenable.class == adapter) {
        return getJavaProject();
      }
    }
    if (IPluginModelBase.class == adapter) {
      return getPluginModelBase();
    }

    return Platform.getAdapterManager().getAdapter(this, adapter);
  }

  public IPluginModelBase getPluginModelBase() {
    return m_pluginModelBase;
  }

  @Override
  public void visit(IScoutBundleGraphVisitor visitor, boolean includeThis, boolean up) {
    if (includeThis) {
      breadthFirstTraverseFromThis(visitor, up);
    }
    else {
      breadthFirstTraverseNeighbors(visitor, up, up ? m_parentBundles : m_childBundles);
    }
  }

  private void registerNlsServiceListener() {
    if (m_textProvidersChangedListener == null) {
      IType abstractDynamicNlsTextProviderService = TypeUtility.getType(IRuntimeClasses.AbstractDynamicNlsTextProviderService);
      if (TypeUtility.exists(abstractDynamicNlsTextProviderService)) {
        IPrimaryTypeTypeHierarchy pth = TypeUtility.getPrimaryTypeHierarchy(abstractDynamicNlsTextProviderService);
        m_textProvidersChangedListener = new P_TextProviderServiceHierarchyChangedListener(this);
        pth.addHierarchyListener(m_textProvidersChangedListener);
      }
    }
  }

  private void breadthFirstTraverseNeighbors(IScoutBundleGraphVisitor visitor, boolean up, Set<ScoutBundle> directNeighbors) {
    Deque<P_TraverseComposite> deck = new LinkedList<P_TraverseComposite>();
    for (ScoutBundle start : directNeighbors) {
      deck.addLast(new P_TraverseComposite(start, 1));
    }
    breadthFirstTraverse(visitor, up, deck);
  }

  private void breadthFirstTraverseFromThis(IScoutBundleGraphVisitor visitor, boolean up) {
    Deque<P_TraverseComposite> deck = new LinkedList<P_TraverseComposite>();
    deck.addLast(new P_TraverseComposite(this, 0));
    breadthFirstTraverse(visitor, up, deck);
  }

  /**
   * level order traversal
   * 
   * @param start
   * @param visitor
   * @param up
   */
  private static void breadthFirstTraverse(IScoutBundleGraphVisitor visitor, boolean up, Deque<P_TraverseComposite> deck) {
    while (!deck.isEmpty()) {
      P_TraverseComposite el = deck.removeFirst();
      Set<ScoutBundle> nextLevelBundles;
      if (up) {
        nextLevelBundles = el.m_bundle.m_parentBundles;
      }
      else {
        nextLevelBundles = el.m_bundle.m_childBundles;
      }

      int nextLevel = el.m_level + 1;
      for (ScoutBundle child : nextLevelBundles) {
        deck.addLast(new P_TraverseComposite(child, nextLevel));
      }

      if (!visitor.visit(el.m_bundle, el.m_level)) {
        return;
      }
    }
  }

  void print(PrintStream out) {
    print(out, this, "");
  }

  void addChildProject(ScoutBundle child) {
    m_childBundles.add(child);
    child.m_parentBundles.add(this);
  }

  public void removeChildProject(ScoutBundle child) {
    m_childBundles.remove(child);
    child.m_parentBundles.remove(this);
  }

  public Map<String, IPluginModelBase> getAllDependencies() {
    return m_allDependencies;
  }

  void removeImplicitChildren() {
    Iterator<ScoutBundle> bundleIt = m_childBundles.iterator();
    while (bundleIt.hasNext()) {
      ScoutBundle bundle = bundleIt.next();
      bundle.removeImplicitChildren();

      ScoutBundle[] otherChildren = m_childBundles.toArray(new ScoutBundle[m_childBundles.size()]);
      for (ScoutBundle otherChild : otherChildren) {
        if (otherChild != bundle && otherChild.containsBundleRec(bundle)) {
          bundleIt.remove(); // remove bundle from my children
          bundle.m_parentBundles.remove(this); //remove me from bundle's parents
          break;
        }
      }
    }
  }

  boolean containsBundleRec(ScoutBundle search) {
    for (ScoutBundle b : m_childBundles) {
      if (b == search) {
        return true;
      }
      if (b.containsBundleRec(search)) {
        return true;
      }
    }
    return false;
  }

  Set<String> getDependencyIssues() {
    return m_dependencyIssues;
  }

  private Map<String, IPluginModelBase> getAllDependenciesImpl(IPluginModelBase bundle, IProgressMonitor monitor) {
    Map<String, IPluginModelBase> collector = new HashMap<String, IPluginModelBase>();
    Stack<IPluginModelBase> dependencyStack = new Stack<IPluginModelBase>();
    Set<String> messageCollector = new HashSet<String>();
    collectDependencies(bundle, collector, dependencyStack, messageCollector, true, monitor);
    getDependencyIssues().addAll(messageCollector);
    return collector;
  }

  private synchronized void clearNlsCache() {
    m_nlsProjectHolder = null;
    m_docsNlsProjectHolder = null;
    if (m_textProvidersChangedListener != null) {
      IType abstractDynamicNlsTextProviderService = TypeUtility.getType(IRuntimeClasses.AbstractDynamicNlsTextProviderService);
      if (TypeUtility.exists(abstractDynamicNlsTextProviderService)) {
        IPrimaryTypeTypeHierarchy pth = TypeUtility.getPrimaryTypeHierarchy(abstractDynamicNlsTextProviderService);
        pth.removeHierarchyListener(m_textProvidersChangedListener);
      }
      m_textProvidersChangedListener = null; // weak listener. will be collected when this instance holds no reference anymore.
    }
  }

  private static void collectDependencies(IPluginModelBase bundle, Map<String, IPluginModelBase> collector, Stack<IPluginModelBase> dependencyStack, Set<String> messageCollector, boolean rec, IProgressMonitor monitor) {
    if (bundle != null && bundle.getBundleDescription() != null) {
      for (BundleSpecification dependency : bundle.getBundleDescription().getRequiredBundles()) {
        if (monitor != null && monitor.isCanceled()) {
          return;
        }

        if (!bundle.getBundleDescription().getSymbolicName().equals(dependency.getName())) { // ignore dependencies on the bundle itself
          IPluginModelBase model = PluginRegistry.findModel(dependency.getName());
          if (model != null) {
            addDependency(model, collector, dependencyStack, messageCollector, rec, monitor);
          }
        }
      }

      if (bundle.getBundleDescription().getHost() != null) {
        for (BundleDescription host : bundle.getBundleDescription().getHost().getHosts()) {
          // it is a fragment: the dependencies of the host are also present.
          IPluginModelBase model = PluginRegistry.findModel(host.getSymbolicName());
          if (model != null) {
            addDependency(model, collector, dependencyStack, messageCollector, rec, monitor);
          }
        }
      }
    }
  }

  private static boolean handleDependencyCycle(IPluginModelBase bundle, Map<String, IPluginModelBase> collector, Stack<IPluginModelBase> dependencyStack, Set<String> messageCollector) {
    if (dependencyStack.contains(bundle)) {
      // a dependency loop was detected: log the loop
      StringBuilder loopMsg = new StringBuilder(Texts.get("DependencyLoopDetected"));
      loopMsg.append(":\n");
      boolean loopBeginFound = false;
      for (IPluginModelBase s : dependencyStack) {
        if (!loopBeginFound && s.equals(bundle)) {
          loopBeginFound = true;
        }
        if (loopBeginFound) {
          String symbolicName = s.getBundleDescription().getSymbolicName();
          loopMsg.append(symbolicName);
          loopMsg.append('\n');
          collector.remove(symbolicName); // correction: remove all dependencies that build up the cycle
        }
      }
      loopMsg.append(bundle.getBundleDescription().getSymbolicName());
      messageCollector.add(loopMsg.toString());
      return true; // cycle found
    }
    return false; // no cycle found
  }

  private static void addDependency(IPluginModelBase bundle, Map<String, IPluginModelBase> collector, Stack<IPluginModelBase> dependencyStack, Set<String> messageCollector, boolean rec, IProgressMonitor monitor) {
    // dependency loop detection & prevention
    if (handleDependencyCycle(bundle, collector, dependencyStack, messageCollector)) {
      // cycle found and corrected: stop processing of this part of the dependency graph
      return;
    }

    IPluginModelBase existingBundle = collector.put(bundle.getBundleDescription().getSymbolicName(), bundle);
    if (existingBundle != null) {
      // we have already processed this bundle and its children. cancel here.
      return;
    }

    try {
      dependencyStack.push(bundle);
      if (rec && !RuntimeBundles.containsTypeDefiningBundle(bundle.getBundleDescription())) {
        collectDependencies(bundle, collector, dependencyStack, messageCollector, rec, monitor);
      }
    }
    finally {
      dependencyStack.pop();
    }
  }

  private static void print(PrintStream out, ScoutBundle b, String prefix) {
    out.println(prefix + b);
    for (ScoutBundle child : b.getDirectChildBundles()) {
      print(out, child, prefix + "  | ");
    }
  }

  private static final class P_BundleCollector implements IScoutBundleGraphVisitor {
    private final LinkedHashSet<IScoutBundle> m_collector;
    private final IScoutBundleFilter m_filter;

    private P_BundleCollector(IScoutBundleFilter filter) {
      m_collector = new LinkedHashSet<IScoutBundle>();
      m_filter = filter;
    }

    @Override
    public boolean visit(IScoutBundle bundle, int traversalLevel) {
      if (m_filter == null || m_filter.accept(bundle)) {
        m_collector.add(bundle);
      }
      return true;
    }

    public IScoutBundle[] getElements() {
      return m_collector.toArray(new IScoutBundle[m_collector.size()]);
    }
  }

  private static final class P_SingleBundleByLevelCollector implements IScoutBundleGraphVisitor {
    private final IScoutBundleFilter m_filter;
    private final TreeSet<IScoutBundle> m_collector;
    private int m_lastLevel;

    private P_SingleBundleByLevelCollector(IScoutBundleFilter filter, IScoutBundleComparator comparator) {
      m_filter = filter;
      if (comparator == null) {
        // if no comparator is given, the client does not care about which bundle inside a traversal level is chosen.
        // but to ensure there is no random behavior we assign one
        comparator = ScoutBundleComparators.getSymbolicNameAscComparator();
      }
      m_collector = new TreeSet<IScoutBundle>(comparator);
      m_lastLevel = 0; // first traversal level is 0
    }

    @Override
    public boolean visit(IScoutBundle bundle, int traversalLevel) {
      if (traversalLevel > m_lastLevel) {
        // the next level is coming: check if we have a candidate
        IScoutBundle candidate = getElement();
        if (candidate != null) {
          // we have found an item: cancel the traversal
          return false;
        }
        m_lastLevel = traversalLevel;
      }

      if (m_filter == null || m_filter.accept(bundle)) {
        m_collector.add(bundle);
      }

      return true; // continue
    }

    public IScoutBundle getElement() {
      if (m_collector.isEmpty()) {
        return null;
      }
      return m_collector.first();
    }
  }

  private static final class P_TextProviderServiceHierarchyChangedListener implements ITypeHierarchyChangedListener, WeakEventListener {
    private ScoutBundle m_observer;

    private P_TextProviderServiceHierarchyChangedListener(ScoutBundle observer) {
      m_observer = observer;
    }

    @Override
    public void hierarchyInvalidated() {
      m_observer.clearNlsCache();
    }
  }

  private static final class P_TraverseComposite {
    private final int m_level;
    private final ScoutBundle m_bundle;

    private P_TraverseComposite(ScoutBundle bundle, int level) {
      m_level = level;
      m_bundle = bundle;
    }
  }
}
