@Subscribe
 public void onEvent(ModelArchiveDownloadedEvent e) throws IOException {
   if (!isRunning()) {
     log(INFO_SERVICE_NOT_RUNNING);
     return;
   }
   if (isIndex(e.model)) {
     File location = repository.getLocation(e.model, false).orNull();
     String remoteUri = e.model.getHint(HINT_REPOSITORY_URL).orNull();
     if (remoteUri != null) {
       Pair<File, IModelIndex> pair = openDelegates.get(remoteUri);
       if (pair == null) {
         File folder = createIndexLocation(remoteUri);
         folder.mkdir();
         Zips.unzip(location, folder);
         openDelegate(remoteUri, folder);
       } else {
         File folder = Files.createTempDir();
         Zips.unzip(location, folder);
         IModelIndex modelIndex = pair.getSecond();
         modelIndex.updateIndex(folder);
         bus.post(new ModelIndexOpenedEvent());
         FileUtils.deleteDirectory(folder);
       }
     }
   }
 }
 @Override
 protected void shutDown() throws Exception {
   cache.invalidateAll();
   for (Pair<File, IModelIndex> delegate : openDelegates.values()) {
     removeDelegate(delegate);
     delegate.getSecond().close();
   }
 }
  @Override
  public Optional<ProjectCoordinate> suggestProjectCoordinateByArtifactId(String artifactId) {
    if (!isRunning()) {
      log(INFO_SERVICE_NOT_RUNNING);
      return absent();
    }
    for (Pair<File, IModelIndex> delegate : openDelegates.values()) {
      IModelIndex index = delegate.getSecond();
      Optional<ProjectCoordinate> suggest = index.suggestProjectCoordinateByArtifactId(artifactId);
      if (suggest.isPresent()) {
        return suggest;
      }
    }

    return absent();
  }
  /** This implementation caches the previous results */
  @Override
  public Optional<ModelCoordinate> suggest(final ProjectCoordinate pc, final String modelType) {
    if (!isRunning()) {
      log(INFO_SERVICE_NOT_RUNNING);
      return absent();
    }
    Pair<ProjectCoordinate, String> key = Pair.newPair(pc, modelType);
    try {
      return cache.get(
          key,
          new Callable<Optional<ModelCoordinate>>() {

            @Override
            public Optional<ModelCoordinate> call() {
              for (String remote : prefs.remotes) {
                Pair<File, IModelIndex> pair = openDelegates.get(remote);
                if (pair == null) {
                  continue; // Index not (yet) available; try next remote repository
                }
                IModelIndex index = pair.getSecond();
                Optional<ModelCoordinate> suggest = index.suggest(pc, modelType);
                if (suggest.isPresent()) {
                  return of(createCopyWithRepositoryUrlHint(suggest.get(), remote));
                }
              }
              return absent();
            }
          });
    } catch (ExecutionException e) {
      Logs.log(LogMessages.ERROR_FAILED_TO_ACCESS_MODEL_COORDINATES_CACHE, e);
      return absent();
    }
  }
 private void openDelegate(String remoteUrl, File indexLocation) throws IOException {
   IModelIndex modelIndex = createModelIndex(indexLocation);
   modelIndex.open();
   storeDelegate(remoteUrl, Pair.newPair(indexLocation, modelIndex));
   bus.post(new ModelIndexOpenedEvent());
 }