diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/Module.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/Module.java
index 9f53bee..9bdc0c4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/Module.java
@@ -40,7 +40,7 @@
 import com.googlesource.gerrit.plugins.eventseiffel.mapping.EiffelEventMapper;
 import com.googlesource.gerrit.plugins.eventseiffel.mq.RabbitMqPublisher;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser;
-import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf;
+import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserImpl;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParsingExecutor;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParsingQueue;
 import com.googlesource.gerrit.plugins.eventseiffel.rest.RestModule;
@@ -100,7 +100,7 @@
         .in(Scopes.SINGLETON);
     bind(EiffelEventParsingExecutor.Scheduled.class).in(Scopes.SINGLETON);
     bind(EiffelEventParsingExecutor.class).to(EiffelEventParsingExecutor.Scheduled.class);
-    bind(EiffelEventParserIf.class).to(EiffelEventParser.class);
+    bind(EiffelEventParser.class).to(EiffelEventParserImpl.class);
     bind(EiffelEventParsingQueue.class).in(Scopes.SINGLETON);
     bind(EiffelEventHubImpl.class).in(Scopes.SINGLETON);
     bind(EiffelEventHub.class).to(EiffelEventHubImpl.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParser.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParser.java
index df82291..6c0ad07 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParser.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Android Open Source Project
+// Copyright (C) 2022 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -11,419 +11,64 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-
 package com.googlesource.gerrit.plugins.eventseiffel.parsing;
 
-import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType.SCC;
-
-import com.github.rholder.retry.RetryException;
-import com.github.rholder.retry.Retryer;
-import com.github.rholder.retry.RetryerBuilder;
-import com.github.rholder.retry.StopStrategies;
-import com.github.rholder.retry.WaitStrategies;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.entities.RefNames;
-import com.google.gerrit.exceptions.NoSuchEntityException;
 import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.common.CommitInfo;
 import com.google.gerrit.extensions.events.RevisionCreatedListener.Event;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.eventseiffel.EiffelEventHub;
-import com.googlesource.gerrit.plugins.eventseiffel.cache.EiffelEventIdLookupException;
-import com.googlesource.gerrit.plugins.eventseiffel.eiffel.CompositionDefinedEventKey;
-import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
-import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEvent;
-import com.googlesource.gerrit.plugins.eventseiffel.mapping.EiffelEventMapper;
-import com.googlesource.gerrit.plugins.eventseiffel.parsing.UnprocessedCommitsWalker.EventCreate;
-import com.googlesource.gerrit.plugins.eventseiffel.parsing.UnprocessedCommitsWalker.ScsWalker;
-import java.io.IOException;
-import java.util.List;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
 
-/** Creates and pushes missing Eiffel events to the Eiffel event queue. */
-public class EiffelEventParser implements EiffelEventParserIf {
-  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+public interface EiffelEventParser {
 
-  private static final int NBR_RETRIES = 3;
+  void createAndScheduleSccFromEvent(Event event);
 
-  private final EiffelEventHub eventHub;
-  private final GitRepositoryManager repoManager;
-  private final UnprocessedCommitsWalker.Factory walkerFactory;
-  private final EiffelEventMapper mapper;
-
-  @Inject
-  public EiffelEventParser(
-      EiffelEventHub eventQueue,
-      GitRepositoryManager repoManager,
-      EiffelEventMapper mapper,
-      UnprocessedCommitsWalker.Factory walkerFactory) {
-    this.eventHub = eventQueue;
-    this.repoManager = repoManager;
-    this.walkerFactory = walkerFactory;
-    this.mapper = mapper;
-  }
-
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleSccFromEvent(com.google.gerrit.extensions.events.RevisionCreatedListener.Event)
+  /**
+   * Creates SCC events for all commits reachable from branchRef. I.e. create SCCs for already
+   * merged commit that are missing SCCs.
+   *
+   * @param repoName
+   * @param branchRef
    */
-  @Override
-  public void createAndScheduleSccFromEvent(Event event) {
-    CommitInfo commit = event.getRevision().commit;
-    SourceChangeEventKey scc =
-        SourceChangeEventKey.sccKey(
-            event.getChange().project, event.getChange().branch, commit.commit);
-    try {
-      if (eventHub.getExistingId(scc).isPresent()) {
-        logger.atWarning().log(
-            "Event %s already pushed for %d/%d",
-            scc, event.getChange()._number, event.getRevision()._number);
-        return;
-      }
-      List<UUID> parentUuids = Lists.newArrayList();
-      for (CommitInfo parent : commit.parents) {
-        Optional<UUID> parentUuid = eventHub.getExistingId(scc.copy(parent.commit));
-        if (parentUuid.isPresent()) {
-          parentUuids.add(parentUuid.get());
-        }
-      }
+  void createAndScheduleSccFromBranch(String repoName, String branchRef);
 
-      /* Eiffel events have been scheduled or published for all parents. */
-      if (parentUuids.size() == commit.parents.size()) {
-        pushToHub(mapper.toScc(event, parentUuids));
-      } else {
-        createAndScheduleMissingSccs(scc);
-      }
-    } catch (IOException
-        | ConfigInvalidException
-        | NoSuchEntityException
-        | EiffelEventIdLookupException
-        | InterruptedException e) {
-      logger.atSevere().withCause(e).log(
-          "Event creation failed for: %s, %s, %s to SCC.",
-          event.getChange().project, event.getChange().branch, event.getRevision().commit.commit);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleSccFromBranch(java.lang.String, java.lang.String)
+  /**
+   * Creates SCC events for all commits reachable from commit.
+   *
+   * @param repoName
+   * @param targetBranch
+   * @param commit
    */
-  @Override
-  public void createAndScheduleSccFromBranch(String repoName, String branchRef) {
-    ObjectId tip = getTipOf(repoName, branchRef);
-    if (tip == null) {
-      return;
-    }
-    createAndScheduleSccFromCommit(repoName, branchRef, tip.getName());
-  }
+  void createAndScheduleSccFromCommit(String repoName, String targetBranch, String commit);
 
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleSccFromCommit(java.lang.String, java.lang.String, java.lang.String)
+  /**
+   * Creates missing SCS events for repoName, branch.
+   *
+   * @param repoName
+   * @param branch
    */
-  @Override
-  public void createAndScheduleSccFromCommit(String repoName, String branchRef, String commit) {
+  void createAndScheduleMissingScssFromBranch(String repoName, String branch);
 
-    SourceChangeEventKey scc = SourceChangeEventKey.sccKey(repoName, branchRef, commit);
-    try {
-      createAndScheduleMissingSccs(scc);
-    } catch (IOException
-        | EiffelEventIdLookupException
-        | NoSuchEntityException
-        | ConfigInvalidException
-        | InterruptedException e) {
-      logger.atSevere().withCause(e).log("Event creation failed for: %s", scc);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleMissingScssFromBranch(java.lang.String, java.lang.String)
+  /**
+   * Creates missing SCS events for a submit transaction. submitter and submittedAt is set for all
+   * events created within the submit transaction, i.e. not reachable from commitSha1TransactionEnd.
+   *
+   * @param scs
+   * @param commitSha1TransactionEnd
+   * @param submitter
+   * @param submittedAt
    */
-  @Override
-  public void createAndScheduleMissingScssFromBranch(String repoName, String branchRef) {
-    ObjectId tip = getTipOf(repoName, branchRef);
-    if (tip == null) {
-      return;
-    }
-    SourceChangeEventKey scs = SourceChangeEventKey.scsKey(repoName, branchRef, tip.getName());
-    createAndScheduleMissingScss(scs, null, null, null);
-  }
-
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleMissingScss(com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey, java.lang.String, com.google.gerrit.extensions.common.AccountInfo, java.lang.Long)
-   */
-  @Override
-  public void createAndScheduleMissingScss(
+  void createAndScheduleMissingScss(
       SourceChangeEventKey scs,
       String commitSha1TransactionEnd,
       AccountInfo submitter,
-      Long submittedAt) {
-    SourceChangeEventKey currentScs = scs;
-    SourceChangeEventKey scc = scs.copy(SCC);
-    try {
-      try (ScsWalker scsFinder =
-          walkerFactory.scsWalker(scs, commitSha1TransactionEnd, submitter, submittedAt)) {
+      Long submittedAt);
 
-        if (eventHub.getExistingId(scc).isEmpty()) {
-          /* One or several SCC events are missing, create them first */
-          try (UnprocessedCommitsWalker sccFinder = scsFinder.sccWalker()) {
-            createAndScheduleMissingSccs(scc, sccFinder);
-          }
-        }
-
-        if (!scsFinder.hasNext()) {
-          logger.atInfo().log("All events were already published for %s", scs);
-        } else {
-          logger.atFine().log("Start publishing events for: %s", scs);
-        }
-        while (scsFinder.hasNext()) {
-          EventCreate create = scsFinder.next();
-          currentScs = create.key;
-          Optional<UUID> sccId = eventHub.getExistingId(create.key.copy(SCC));
-          if (sccId.isEmpty()) {
-            throw new EiffelEventIdLookupException(
-                "Unable to find SCC event id: %s", create.key.copy(SCC));
-          }
-          List<UUID> scsParentEventIds = Lists.newArrayList();
-          for (RevCommit parent : create.commit.getParents()) {
-            Optional<UUID> parentUuid = eventHub.getExistingId(create.key.copy(parent.getName()));
-            if (parentUuid.isPresent()) {
-              scsParentEventIds.add(parentUuid.get());
-            } else {
-              exceptionForMissingParent(create, parent);
-            }
-          }
-          pushToHub(
-              mapper.toScs(
-                  create.commit,
-                  create.key.repo(),
-                  create.key.branch(),
-                  create.submitter,
-                  create.submittedAt,
-                  scsParentEventIds,
-                  sccId.get()));
-        }
-      }
-      logger.atFine().log("Done publishing events for: %s", scs);
-    } catch (IOException
-        | EiffelEventIdLookupException
-        | InterruptedException
-        | ConfigInvalidException
-        | NoSuchEntityException e) {
-      logger.atSevere().withCause(e).log("Failed to create Eiffel event(s) for %s.", currentScs);
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf#createAndScheduleArtc(java.lang.String, java.lang.String, java.lang.Long, boolean)
+  /**
+   * Creates missing ARTC for a tag, together with CD and (if missing) SCS for referenced commit.7
+   *
+   * @param projectName
+   * @param tagName
+   * @param creationTime
+   * @param force
    */
-  @Override
-  public void createAndScheduleArtc(
-      String repoName, String tagName, Long creationTime, boolean force) {
-    try {
-      CompositionDefinedEventKey cd =
-          CompositionDefinedEventKey.create(mapper.tagCompositionName(repoName), tagName);
-      Optional<UUID> oldCdId = eventHub.getExistingId(cd);
-      if (oldCdId.isEmpty() || force) {
-        createAndScheduleCd(repoName, tagName, creationTime, force);
-        Optional<UUID> cdId = eventHub.getExistingId(cd);
-        if (cdId.isPresent() && !cdId.equals(oldCdId)) {
-          pushToHub(mapper.toArtc(repoName, tagName, creationTime, cdId.get()), force);
-          if (oldCdId.isPresent()) {
-            logger.atInfo().log(
-                "Event Artc has been forcibly created for: %s, %s", repoName, tagName);
-          } else {
-            logger.atFine().log("Event Artc has been created for: %s, %s", repoName, tagName);
-          }
-        }
-      } else {
-        /* Artc event has already been created */
-        logger.atWarning().log(
-            "Event Artc has already been created for: %s, %s", repoName, tagName);
-      }
-    } catch (EiffelEventIdLookupException | InterruptedException e) {
-      logger.atSevere().withCause(e).log(
-          "Event creation failed for: %s, %s to Artc", repoName, tagName);
-    }
-  }
-
-  private void createAndScheduleCd(
-      String projectName, String tagName, Long creationTime, boolean force) {
-    SourceChangeEventKey scs = null;
-    Optional<UUID> scsId = Optional.empty();
-
-    try {
-      String commitId = peelTag(projectName, tagName);
-      if (commitId == null) {
-        return;
-      }
-      scs = SourceChangeEventKey.scsKey(projectName, RefNames.REFS_HEADS + "master", commitId);
-      scsId = eventHub.getExistingId(scs);
-
-      if (scsId.isEmpty()) {
-        Retryer<Optional<UUID>> retryer =
-            RetryerBuilder.<Optional<UUID>>newBuilder()
-                .retryIfResult(Optional::isEmpty)
-                .withWaitStrategy(WaitStrategies.fixedWait(10, TimeUnit.SECONDS))
-                .withStopStrategy(StopStrategies.stopAfterAttempt(2))
-                .build();
-        try {
-          scsId = retryer.call(() -> findSourceChangeEventKey(projectName, commitId));
-        } catch (RetryException | ExecutionException e) {
-          logger.atSevere().withCause(e).log(
-              "Failed to find SCS for %s in %s", commitId, projectName);
-          return;
-        }
-      }
-      if (scsId.isEmpty()) {
-        logger.atSevere().log("Could not find SCS for: %s in %s", commitId, projectName);
-        return;
-      }
-      pushToHub(mapper.toCd(projectName, tagName, creationTime, scsId.get()), force);
-    } catch (EiffelEventIdLookupException | InterruptedException e) {
-      logger.atSevere().withCause(e).log(
-          "Event creation failed for: %s",
-          CompositionDefinedEventKey.create(mapper.tagCompositionName(projectName), tagName));
-    }
-  }
-
-  private String peelTag(String projectName, String tagName) {
-    try (Repository repo = repoManager.openRepository(Project.nameKey(projectName))) {
-      Ref tagRef = repo.getRefDatabase().exactRef(Constants.R_TAGS + tagName);
-      if (tagRef != null) {
-        ObjectId peeled = repo.getRefDatabase().peel(tagRef).getPeeledObjectId();
-        return peeled != null ? peeled.getName() : tagRef.getObjectId().getName();
-      }
-      logger.atSevere().log("Cannot find tag: %s:%s", projectName, tagName);
-    } catch (IOException e) {
-      logger.atSevere().withCause(e).log("Unable to peel tag: %s:%s", projectName, tagName);
-    }
-    return null;
-  }
-
-  private Optional<UUID> findSourceChangeEventKey(String projectName, String commitId)
-      throws EiffelEventIdLookupException {
-    List<String> branches;
-    try (Repository repo = repoManager.openRepository(Project.nameKey(projectName))) {
-      branches =
-          repo.getRefDatabase().getRefsByPrefix(RefNames.REFS_HEADS).stream()
-              .map(Ref::getName)
-              .collect(Collectors.toList());
-    } catch (IOException ioe) {
-      logger.atSevere().withCause(ioe).log("Unable to find branches of %s.", projectName);
-      return Optional.empty();
-    }
-    return eventHub.getScsForCommit(projectName, commitId, branches);
-  }
-
-  private void pushToHub(EiffelEvent toPush) throws InterruptedException {
-    pushToHub(toPush, false);
-  }
-
-  private void pushToHub(EiffelEvent toPush, boolean force) throws InterruptedException {
-    int failureCount = 0;
-    EventKey key = EventKey.fromEvent(toPush);
-    while (true) {
-      try {
-        eventHub.push(toPush, force);
-        logger.atFine().log("Successfully pushed %s to EventHub", key);
-        return;
-      } catch (InterruptedException e) {
-        if (!eventHub.isOpen()) {
-          logger.atInfo().log("EventHub is closed, aborting.");
-          throw e;
-        }
-        failureCount++;
-        if (failureCount < NBR_RETRIES) {
-          logger.atWarning().withCause(e).log(
-              "Interrupted while pushing %s to EventHub, attempt %d/%d",
-              key, failureCount, NBR_RETRIES);
-        } else {
-          throw e;
-        }
-      }
-    }
-  }
-
-  @VisibleForTesting
-  void createAndScheduleMissingSccs(SourceChangeEventKey scc)
-      throws MissingObjectException, IncorrectObjectTypeException, IOException,
-          EiffelEventIdLookupException, RepositoryNotFoundException, NoSuchEntityException,
-          ConfigInvalidException, InterruptedException {
-    logger.atFine().log("Start publishing events for: %s", scc);
-    try (UnprocessedCommitsWalker commitFinder = walkerFactory.sccWalker(scc)) {
-      createAndScheduleMissingSccs(scc, commitFinder);
-    }
-    logger.atFine().log("Done publishing events for: %s", scc);
-  }
-
-  /* Callers are responsible for closing commitFinder. */
-  private void createAndScheduleMissingSccs(
-      SourceChangeEventKey scc, UnprocessedCommitsWalker commitFinder)
-      throws MissingObjectException, EiffelEventIdLookupException, IOException,
-          NoSuchEntityException, ConfigInvalidException, InterruptedException {
-    if (!commitFinder.hasNext()) {
-      logger.atInfo().log("All events were already published for %s", scc);
-    } else {
-      logger.atFine().log("Start publishing events for: %s", scc);
-    }
-    while (commitFinder.hasNext()) {
-      EventCreate job = commitFinder.next();
-      logger.atFine().log("Processing event-creation for: %s", job.key);
-      List<UUID> parentIds = Lists.newArrayList();
-      for (RevCommit parent : job.commit.getParents()) {
-        SourceChangeEventKey parentKey = scc.copy(parent.getName());
-        Optional<UUID> parentId = eventHub.getExistingId(parentKey);
-        if (parentId.isPresent()) {
-          parentIds.add(parentId.get());
-        } else {
-          exceptionForMissingParent(job, parent);
-        }
-      }
-      try {
-        pushToHub(mapper.toScc(job.commit, job.key.repo(), job.key.branch(), parentIds));
-      } catch (InterruptedException e) {
-        logger.atSevere().log("Interrupted while pushing %s to EventHub.", job.key);
-        throw e;
-      }
-    }
-  }
-
-  private ObjectId getTipOf(String repoName, String branch) {
-    try (Repository repo = repoManager.openRepository(Project.nameKey(repoName))) {
-      Ref branchRef = repo.exactRef(branch);
-      if (branchRef == null) {
-        logger.atWarning().log("Could not find ref: %s in project: %s", branch, repoName);
-        return null;
-      }
-      return branchRef.getTarget().getObjectId();
-    } catch (IOException ioe) {
-      logger.atSevere().withCause(ioe).log("Unable to identify tip of (%s:%s).", repoName, branch);
-      return null;
-    }
-  }
-
-  private void exceptionForMissingParent(EventCreate create, RevCommit parent)
-      throws NoSuchEntityException {
-    throw new NoSuchEntityException(
-        String.format(
-            "Unable to lookup parent (%s) event UUID for %s even though it should exist.",
-            parent.abbreviate(7).name(), create.key));
-  }
+  void createAndScheduleArtc(String projectName, String tagName, Long creationTime, boolean force);
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIf.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIf.java
deleted file mode 100644
index 94aa921..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIf.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.googlesource.gerrit.plugins.eventseiffel.parsing;
-
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.events.RevisionCreatedListener.Event;
-import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
-
-public interface EiffelEventParserIf {
-
-  void createAndScheduleSccFromEvent(Event event);
-
-  /**
-   * Creates SCC events for all commits reachable from branchRef. I.e. create SCCs for already
-   * merged commit that are missing SCCs.
-   *
-   * @param repoName - Name of the repository where the branch exists.
-   * @param branchRef - Creates missing events for all commits reachable from branch.
-   */
-  void createAndScheduleSccFromBranch(String repoName, String branchRef);
-
-  /**
-   * Creates SCC events for all commits reachable from commit.
-   *
-   * @param repoName - Name of the repository were the commits exists.
-   * @param branchRef - Ref of the branch to create events for.
-   * @param commit - Creates missing events for all commits reachable from commit.
-   */
-  void createAndScheduleSccFromCommit(String repoName, String branchRef, String commit);
-
-  /**
-   * Creates missing SCS events for repoName, branch.
-   *
-   * @param repoName - Name of the repository where the branch exists.
-   * @param branchRef - Creates missing events for all commits reachable from branchRef.
-   */
-  void createAndScheduleMissingScssFromBranch(String repoName, String branchRef);
-
-  /**
-   * Creates missing SCS events for a submit transaction. submitter and submittedAt is set for all
-   * events created within the submit transaction, i.e. not reachable from commitSha1TransactionEnd.
-   *
-   * @param scs - key for the event that shuold be created, together with parents.
-   * @param commitSha1TransactionEnd - tip before submit transaction.
-   * @param submitter - The submitter
-   * @param submittedAt - When the commit was submitted.
-   */
-  void createAndScheduleMissingScss(
-      SourceChangeEventKey scs,
-      String commitSha1TransactionEnd,
-      AccountInfo submitter,
-      Long submittedAt);
-
-  /**
-   * Creates missing ARTC for a tag, together with CD and (if missing) SCS for referenced commit.
-   *
-   * @param repoName - Name of the repository were the tag exists.
-   * @param tagName - The name of the tag.
-   * @param creationTime - The time at which the tag was created.
-   * @param force - Whether existing events should be replaced or not.
-   */
-  void createAndScheduleArtc(String repoName, String tagName, Long creationTime, boolean force);
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserImpl.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserImpl.java
new file mode 100644
index 0000000..5d54053
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserImpl.java
@@ -0,0 +1,429 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.eventseiffel.parsing;
+
+import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEventType.SCC;
+
+import com.github.rholder.retry.RetryException;
+import com.github.rholder.retry.Retryer;
+import com.github.rholder.retry.RetryerBuilder;
+import com.github.rholder.retry.StopStrategies;
+import com.github.rholder.retry.WaitStrategies;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.exceptions.NoSuchEntityException;
+import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.common.CommitInfo;
+import com.google.gerrit.extensions.events.RevisionCreatedListener.Event;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.eventseiffel.EiffelEventHub;
+import com.googlesource.gerrit.plugins.eventseiffel.cache.EiffelEventIdLookupException;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.CompositionDefinedEventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEvent;
+import com.googlesource.gerrit.plugins.eventseiffel.mapping.EiffelEventMapper;
+import com.googlesource.gerrit.plugins.eventseiffel.parsing.UnprocessedCommitsWalker.EventCreate;
+import com.googlesource.gerrit.plugins.eventseiffel.parsing.UnprocessedCommitsWalker.ScsWalker;
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+/** Creates and pushes missing Eiffel events to the Eiffel event queue. */
+public class EiffelEventParserImpl implements EiffelEventParser {
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+  private static final int NBR_RETRIES = 3;
+
+  private final EiffelEventHub eventHub;
+  private final GitRepositoryManager repoManager;
+  private final UnprocessedCommitsWalker.Factory walkerFactory;
+  private final EiffelEventMapper mapper;
+
+  @Inject
+  public EiffelEventParserImpl(
+      EiffelEventHub eventQueue,
+      GitRepositoryManager repoManager,
+      EiffelEventMapper mapper,
+      UnprocessedCommitsWalker.Factory walkerFactory) {
+    this.eventHub = eventQueue;
+    this.repoManager = repoManager;
+    this.walkerFactory = walkerFactory;
+    this.mapper = mapper;
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleSccFromEvent(com.google.gerrit.extensions.events.RevisionCreatedListener.Event)
+   */
+  @Override
+  public void createAndScheduleSccFromEvent(Event event) {
+    CommitInfo commit = event.getRevision().commit;
+    SourceChangeEventKey scc =
+        SourceChangeEventKey.sccKey(
+            event.getChange().project, event.getChange().branch, commit.commit);
+    try {
+      if (eventHub.getExistingId(scc).isPresent()) {
+        logger.atWarning().log(
+            "Event %s already pushed for %d/%d",
+            scc, event.getChange()._number, event.getRevision()._number);
+        return;
+      }
+      List<UUID> parentUuids = Lists.newArrayList();
+      for (CommitInfo parent : commit.parents) {
+        Optional<UUID> parentUuid = eventHub.getExistingId(scc.copy(parent.commit));
+        if (parentUuid.isPresent()) {
+          parentUuids.add(parentUuid.get());
+        }
+      }
+
+      /* Eiffel events have been scheduled or published for all parents. */
+      if (parentUuids.size() == commit.parents.size()) {
+        pushToHub(mapper.toScc(event, parentUuids));
+      } else {
+        createAndScheduleMissingSccs(scc);
+      }
+    } catch (IOException
+        | ConfigInvalidException
+        | NoSuchEntityException
+        | EiffelEventIdLookupException
+        | InterruptedException e) {
+      logger.atSevere().withCause(e).log(
+          "Event creation failed for: %s, %s, %s to SCC.",
+          event.getChange().project, event.getChange().branch, event.getRevision().commit.commit);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleSccFromBranch(java.lang.String, java.lang.String)
+   */
+  @Override
+  public void createAndScheduleSccFromBranch(String repoName, String targetBranch) {
+    ObjectId tip = getTipOf(repoName, targetBranch);
+    if (tip == null) {
+      return;
+    }
+    createAndScheduleSccFromCommit(repoName, targetBranch, tip.getName());
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleSccFromCommit(java.lang.String, java.lang.String, java.lang.String)
+   */
+  @Override
+  public void createAndScheduleSccFromCommit(String repoName, String targetBranch, String commit) {
+
+    SourceChangeEventKey scc = SourceChangeEventKey.sccKey(repoName, targetBranch, commit);
+    try {
+      createAndScheduleMissingSccs(scc);
+    } catch (IOException
+        | EiffelEventIdLookupException
+        | NoSuchEntityException
+        | ConfigInvalidException
+        | InterruptedException e) {
+      logger.atSevere().withCause(e).log("Event creation failed for: %s", scc);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleMissingScssFromBranch(java.lang.String, java.lang.String)
+   */
+  @Override
+  public void createAndScheduleMissingScssFromBranch(String repoName, String branch) {
+    ObjectId tip = getTipOf(repoName, branch);
+    if (tip == null) {
+      return;
+    }
+    SourceChangeEventKey scs = SourceChangeEventKey.scsKey(repoName, branch, tip.getName());
+    createAndScheduleMissingScss(scs, null, null, null);
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleMissingScss(com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey, java.lang.String, com.google.gerrit.extensions.common.AccountInfo, java.lang.Long)
+   */
+  @Override
+  public void createAndScheduleMissingScss(
+      SourceChangeEventKey scs,
+      String commitSha1TransactionEnd,
+      AccountInfo submitter,
+      Long submittedAt) {
+    SourceChangeEventKey currentScs = scs;
+    SourceChangeEventKey scc = scs.copy(SCC);
+    try {
+      try (ScsWalker scsFinder =
+          walkerFactory.scsWalker(scs, commitSha1TransactionEnd, submitter, submittedAt)) {
+
+        if (eventHub.getExistingId(scc).isEmpty()) {
+          /* One or several SCC events are missing, create them first */
+          try (UnprocessedCommitsWalker sccFinder = scsFinder.sccWalker()) {
+            createAndScheduleMissingSccs(scc, sccFinder);
+          }
+        }
+
+        if (!scsFinder.hasNext()) {
+          logger.atInfo().log("All events were already published for %s", scs);
+        } else {
+          logger.atFine().log("Start publishing events for: %s", scs);
+        }
+        while (scsFinder.hasNext()) {
+          EventCreate create = scsFinder.next();
+          currentScs = create.key;
+          Optional<UUID> sccId = eventHub.getExistingId(create.key.copy(SCC));
+          if (sccId.isEmpty()) {
+            throw new EiffelEventIdLookupException(
+                "Unable to find SCC event id: %s", create.key.copy(SCC));
+          }
+          List<UUID> scsParentEventIds = Lists.newArrayList();
+          for (RevCommit parent : create.commit.getParents()) {
+            Optional<UUID> parentUuid = eventHub.getExistingId(create.key.copy(parent.getName()));
+            if (parentUuid.isPresent()) {
+              scsParentEventIds.add(parentUuid.get());
+            } else {
+              exceptionForMissingParent(create, parent);
+            }
+          }
+          pushToHub(
+              mapper.toScs(
+                  create.commit,
+                  create.key.repo(),
+                  create.key.branch(),
+                  create.submitter,
+                  create.submittedAt,
+                  scsParentEventIds,
+                  sccId.get()));
+        }
+      }
+      logger.atFine().log("Done publishing events for: %s", scs);
+    } catch (IOException
+        | EiffelEventIdLookupException
+        | InterruptedException
+        | ConfigInvalidException
+        | NoSuchEntityException e) {
+      logger.atSevere().withCause(e).log("Failed to create Eiffel event(s) for %s.", currentScs);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser#createAndScheduleArtc(java.lang.String, java.lang.String, java.lang.Long, boolean)
+   */
+  @Override
+  public void createAndScheduleArtc(
+      String projectName, String tagName, Long creationTime, boolean force) {
+    try {
+      CompositionDefinedEventKey cd =
+          CompositionDefinedEventKey.create(mapper.tagCompositionName(projectName), tagName);
+      Optional<UUID> oldCdId = eventHub.getExistingId(cd);
+      if (oldCdId.isEmpty() || force) {
+        createAndScheduleCd(projectName, tagName, creationTime, force);
+        Optional<UUID> cdId = eventHub.getExistingId(cd);
+        if (cdId.isPresent() && !cdId.equals(oldCdId)) {
+          pushToHub(mapper.toArtc(projectName, tagName, creationTime, cdId.get()), force);
+          if (oldCdId.isPresent()) {
+            logger.atInfo().log(
+                "Event Artc has been forcibly created for: %s, %s", projectName, tagName);
+          } else {
+            logger.atFine().log("Event Artc has been created for: %s, %s", projectName, tagName);
+          }
+        }
+      } else {
+        /* Artc event has already been created */
+        logger.atWarning().log(
+            "Event Artc has already been created for: %s, %s", projectName, tagName);
+      }
+    } catch (EiffelEventIdLookupException | InterruptedException e) {
+      logger.atSevere().withCause(e).log(
+          "Event creation failed for: %s, %s to Artc", projectName, tagName);
+    }
+  }
+
+  private void createAndScheduleCd(
+      String projectName, String tagName, Long creationTime, boolean force) {
+    SourceChangeEventKey scs = null;
+    Optional<UUID> scsId = Optional.empty();
+
+    try {
+      String commitId = peelTag(projectName, tagName);
+      if (commitId == null) {
+        return;
+      }
+      scs = SourceChangeEventKey.scsKey(projectName, RefNames.REFS_HEADS + "master", commitId);
+      scsId = eventHub.getExistingId(scs);
+
+      if (scsId.isEmpty()) {
+        Retryer<Optional<UUID>> retryer =
+            RetryerBuilder.<Optional<UUID>>newBuilder()
+                .retryIfResult(Optional::isEmpty)
+                .withWaitStrategy(WaitStrategies.fixedWait(10, TimeUnit.SECONDS))
+                .withStopStrategy(StopStrategies.stopAfterAttempt(2))
+                .build();
+        try {
+          scsId = retryer.call(() -> findSourceChangeEventKey(projectName, commitId));
+        } catch (RetryException | ExecutionException e) {
+          logger.atSevere().withCause(e).log(
+              "Failed to find SCS for %s in %s", commitId, projectName);
+          return;
+        }
+      }
+      if (scsId.isEmpty()) {
+        logger.atSevere().log("Could not find SCS for: %s in %s", commitId, projectName);
+        return;
+      }
+      pushToHub(mapper.toCd(projectName, tagName, creationTime, scsId.get()), force);
+    } catch (EiffelEventIdLookupException | InterruptedException e) {
+      logger.atSevere().withCause(e).log(
+          "Event creation failed for: %s",
+          CompositionDefinedEventKey.create(mapper.tagCompositionName(projectName), tagName));
+    }
+  }
+
+  private String peelTag(String projectName, String tagName) {
+    try (Repository repo = repoManager.openRepository(Project.nameKey(projectName))) {
+      Ref tagRef = repo.getRefDatabase().exactRef(Constants.R_TAGS + tagName);
+      if (tagRef != null) {
+        ObjectId peeled = repo.getRefDatabase().peel(tagRef).getPeeledObjectId();
+        return peeled != null ? peeled.getName() : tagRef.getObjectId().getName();
+      }
+      logger.atSevere().log("Cannot find tag: %s:%s", projectName, tagName);
+    } catch (IOException e) {
+      logger.atSevere().withCause(e).log("Unable to peel tag: %s:%s", projectName, tagName);
+    }
+    return null;
+  }
+
+  private Optional<UUID> findSourceChangeEventKey(String projectName, String commitId)
+      throws EiffelEventIdLookupException {
+    List<String> branches;
+    try (Repository repo = repoManager.openRepository(Project.nameKey(projectName))) {
+      branches =
+          repo.getRefDatabase().getRefsByPrefix(RefNames.REFS_HEADS).stream()
+              .map(Ref::getName)
+              .collect(Collectors.toList());
+    } catch (IOException ioe) {
+      logger.atSevere().withCause(ioe).log("Unable to find branches of %s.", projectName);
+      return Optional.empty();
+    }
+    return eventHub.getScsForCommit(projectName, commitId, branches);
+  }
+
+  private void pushToHub(EiffelEvent toPush) throws InterruptedException {
+    pushToHub(toPush, false);
+  }
+
+  private void pushToHub(EiffelEvent toPush, boolean force) throws InterruptedException {
+    int failureCount = 0;
+    EventKey key = EventKey.fromEvent(toPush);
+    while (true) {
+      try {
+        eventHub.push(toPush, force);
+        logger.atFine().log("Successfully pushed %s to EventHub", key);
+        return;
+      } catch (InterruptedException e) {
+        if (!eventHub.isOpen()) {
+          logger.atInfo().log("EventHub is closed, aborting.");
+          throw e;
+        }
+        failureCount++;
+        if (failureCount < NBR_RETRIES) {
+          logger.atWarning().withCause(e).log(
+              "Interrupted while pushing %s to EventHub, attempt %d/%d",
+              key, failureCount, NBR_RETRIES);
+        } else {
+          throw e;
+        }
+      }
+    }
+  }
+
+  @VisibleForTesting
+  void createAndScheduleMissingSccs(SourceChangeEventKey scc)
+      throws MissingObjectException, IncorrectObjectTypeException, IOException,
+          EiffelEventIdLookupException, RepositoryNotFoundException, NoSuchEntityException,
+          ConfigInvalidException, InterruptedException {
+    logger.atFine().log("Start publishing events for: %s", scc);
+    try (UnprocessedCommitsWalker commitFinder = walkerFactory.sccWalker(scc)) {
+      createAndScheduleMissingSccs(scc, commitFinder);
+    }
+    logger.atFine().log("Done publishing events for: %s", scc);
+  }
+
+  /* Callers are responsible for closing commitFinder. */
+  private void createAndScheduleMissingSccs(
+      SourceChangeEventKey scc, UnprocessedCommitsWalker commitFinder)
+      throws MissingObjectException, EiffelEventIdLookupException, IOException,
+          NoSuchEntityException, ConfigInvalidException, InterruptedException {
+    if (!commitFinder.hasNext()) {
+      logger.atInfo().log("All events were already published for %s", scc);
+    } else {
+      logger.atFine().log("Start publishing events for: %s", scc);
+    }
+    while (commitFinder.hasNext()) {
+      EventCreate job = commitFinder.next();
+      logger.atFine().log("Processing event-creation for: %s", job.key);
+      List<UUID> parentIds = Lists.newArrayList();
+      for (RevCommit parent : job.commit.getParents()) {
+        SourceChangeEventKey parentKey = scc.copy(parent.getName());
+        Optional<UUID> parentId = eventHub.getExistingId(parentKey);
+        if (parentId.isPresent()) {
+          parentIds.add(parentId.get());
+        } else {
+          exceptionForMissingParent(job, parent);
+        }
+      }
+      try {
+        pushToHub(mapper.toScc(job.commit, job.key.repo(), job.key.branch(), parentIds));
+      } catch (InterruptedException e) {
+        logger.atSevere().log("Interrupted while pushing %s to EventHub.", job.key);
+        throw e;
+      }
+    }
+  }
+
+  private ObjectId getTipOf(String repoName, String branch) {
+    try (Repository repo = repoManager.openRepository(Project.nameKey(repoName))) {
+      Ref branchRef = repo.exactRef(branch);
+      if (branchRef == null) {
+        logger.atWarning().log("Could not find ref: %s in project: %s", branch, repoName);
+        return null;
+      }
+      return branchRef.getTarget().getObjectId();
+    } catch (IOException ioe) {
+      logger.atSevere().withCause(ioe).log("Unable to identify tip of (%s:%s).", repoName, branch);
+      return null;
+    }
+  }
+
+  private void exceptionForMissingParent(EventCreate create, RevCommit parent)
+      throws NoSuchEntityException {
+    throw new NoSuchEntityException(
+        String.format(
+            "Unable to lookup parent (%s) event UUID for %s even though it should exist.",
+            parent.abbreviate(7).name(), create.key));
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
index b457b6f..c5d10b8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParsingQueue.java
@@ -36,12 +36,12 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   private volatile EiffelEventParsingExecutor pool;
-  private final EiffelEventParserIf eventParser;
+  private final EiffelEventParser eventParser;
   private final ConcurrentHashMap<EventParsingWorker, ScheduledFuture<?>> pending =
       new ConcurrentHashMap<>();
 
   @Inject
-  public EiffelEventParsingQueue(EiffelEventParsingExecutor pool, EiffelEventParserIf eventParser) {
+  public EiffelEventParsingQueue(EiffelEventParsingExecutor pool, EiffelEventParser eventParser) {
     this.pool = pool;
     this.eventParser = eventParser;
   }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventsTestModule.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventsTestModule.java
index 579f3b6..17b5acd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventsTestModule.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventsTestModule.java
@@ -26,7 +26,7 @@
 import com.googlesource.gerrit.plugins.eventseiffel.eiffel.api.EventStorage;
 import com.googlesource.gerrit.plugins.eventseiffel.mapping.EiffelEventFactory;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParser;
-import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserIf;
+import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParserImpl;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParsingExecutor;
 import com.googlesource.gerrit.plugins.eventseiffel.parsing.EiffelEventParsingQueue;
 import org.junit.Ignore;
@@ -44,7 +44,7 @@
     bind(EiffelEventParsingExecutor.class).to(EiffelEventParsingExecutor.Direct.class);
     bind(TestEventPublisher.class).in(Scopes.SINGLETON);
     bind(EiffelEventHub.Consumer.class).to(TestEventPublisher.class);
-    bind(EiffelEventParserIf.class).to(EiffelEventParser.class);
+    bind(EiffelEventParser.class).to(EiffelEventParserImpl.class);
     bind(EiffelEventParsingQueue.class);
     bind(EiffelEventFactory.class).toProvider(TestEventFactoryProvider.class);
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIT.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIT.java
index d2d87eb..d20034b 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/parsing/EiffelEventParserIT.java
@@ -57,11 +57,11 @@
 public class EiffelEventParserIT extends EiffelEventsTest {
   private static final Long EPOCH_MILLIS = 978307261000l;
 
-  private EiffelEventParser eventParser;
+  private EiffelEventParserImpl eventParser;
 
   @Before
   public void setUp() {
-    eventParser = plugin.getSysInjector().getInstance(EiffelEventParser.class);
+    eventParser = plugin.getSysInjector().getInstance(EiffelEventParserImpl.class);
     TestEventHub.EVENTS.clear();
   }
 
@@ -342,7 +342,7 @@
       bind(EiffelEventHub.class).to(TestEventHub.class);
       bind(EventMappingConfig.class).toProvider(EventMappingConfig.Provider.class);
       bind(EiffelEventMapper.class);
-      bind(EiffelEventParserIf.class).to(EiffelEventParser.class);
+      bind(EiffelEventParser.class).to(EiffelEventParserImpl.class);
       bind(EiffelConfig.class).toProvider(EiffelConfig.Provider.class).in(Scopes.SINGLETON);
       bind(EiffelEventFactory.class)
           .toProvider(EiffelEventFactory.Provider.class)
