@Override
  public final void merge(MergeOperation<ASTNodeArtifact> operation, MergeContext context)
      throws IOException, InterruptedException {
    Objects.requireNonNull(operation, "operation must not be null!");
    Objects.requireNonNull(context, "context must not be null!");

    MergeStrategy<ASTNodeArtifact> astNodeStrategy = new ASTNodeStrategy();

    if (LOG.isDebugEnabled()) {
      LOG.debug("Using strategy: " + astNodeStrategy);
    }

    MergeTriple<ASTNodeArtifact> triple = operation.getMergeTriple();
    ASTNodeArtifact left = triple.getLeft();
    ASTNodeArtifact right = triple.getRight();
    ASTNodeArtifact target = operation.getTarget();

    boolean safeMerge = true;

    int numChildNoTransform;
    try {
      numChildNoTransform = target.astnode.getClass().newInstance().getNumChildNoTransform();
    } catch (InstantiationException | IllegalAccessException e) {
      throw new RuntimeException();
    }

    if (!isRoot() && numChildNoTransform > 0) {

      // this language element has a fixed number of children, we need to be careful with this one
      boolean leftChanges = left.hasChanges(false);
      boolean rightChanges = right.hasChanges(false);

      if (leftChanges && rightChanges) {

        if (LOG.isTraceEnabled()) {
          LOG.trace("Target " + target.getId() + " expects a fixed amount of children.");
          LOG.trace("Both " + left.getId() + " and " + right.getId() + " contain changes.");
          LOG.trace("We will report a conflict instead of performing the merge.");
        }
        safeMerge = false;

        // to be safe, we will report a conflict instead of merging
        ASTNodeArtifact targetParent = target.getParent();
        targetParent.removeChild(target);

        Operation<ASTNodeArtifact> conflictOp =
            new ConflictOperation<>(left, left, right, targetParent);
        conflictOp.apply(context);
      }
    }

    if (safeMerge) {
      astNodeStrategy.merge(operation, context);
    }

    if (!context.isQuiet() && context.hasOutput()) {
      System.out.print(context.getStdIn());
    }
  }