[Demonstration 1]

[Buggy Method]
@Override
public void visit(MemberAccess node) {
    node.getLeft().visit(this);
    assert node.getLeft().isTypeResolved();
    if (node.getLeft().getType().isVariable()) {
        reportError(node.getLeft(), "Could not infer left hand type of member access");
    }
    assert node.getLeft().getType().isClass();
    final ClassType instanceType = node.getLeft().getType().asClass();
    final TypeDeclaration raw = node.getScope().resolveType(node, instanceType);
    final Unification subst = Unification.testIf(instanceType).isA(raw.getType());
    // Resolve type of the right hand node in the scope of the left hand
    // node. This will yield the raw (declared type) of the right hand node.
    // It must therefore be run through the substitution which binds type
    // variables
    // Create a sub scope in which type variables of the LHS are defined
    final Scope memberScope = new Scope("$member" + raw.getIdentifier(), raw.getScope());
    memberScope.defineSubstitutions(subst);
    node.getRight().setScope(memberScope);
    node.getRight().visit(this);
    assert node.getRight().isTypeResolved();
    if (raw instanceof ClassDeclaration) {
        final ClassScope rawScope = (ClassScope) raw.getScope();
        final Unification typeVarBindings = rawScope.getSubstitutions();
        // We need to substitute type variables of the right with their
        // bindings from
        // the left scope
        final Type rightType = typeVarBindings.apply(node.getRight());
        node.setType(rightType);
    } else {
        node.setType(node.getRight().getType());
    }
}

[Buggy Hunk]
final Unification typeVarBindings = rawScope.getSubstitutions();

[Patch]
final Unification typeVarBindings = rawScope.getSubstitutions().merge(subst);

[Demonstration 2]

[Buggy Method]
@Override
public Pair<ASTExpression, List<ASTType>> visit(ASTOrPredicate orPredicate) {
    boolean old = rememberPredicate;
    rememberPredicate = false;
    Pair<ASTExpression, List<ASTType>> left = visit(orPredicate.left);
    Pair<ASTExpression, List<ASTType>> right = visit(orPredicate.left);
    orPredicate.left = (ASTPredicate) left.left;
    orPredicate.right = (ASTPredicate) right.left;
    rememberPredicate = old;
    return new Pair<ASTExpression, List<ASTType>>(orPredicate, left.right);
}

[Buggy Hunk]
Pair<ASTExpression, List<ASTType>> right = visit(orPredicate.left);

[Patch]
Pair<ASTExpression, List<ASTType>> right = visit(orPredicate.right);

[Demonstration 3]

[Buggy Method]
public List<JarInfo> extract() {
    Jar jar = loadJar();
    List<JarInfo> result = new ArrayList<>();
    Enumeration en = jar.entries();
    while (en.hasMoreElements()) {
        JarEntry file = (JarEntry) en.nextElement();
        result.addAll(processJarItems(jar, result, file));
    }
    for (JarInfo i : result) {
        i.setFileName(new File(jarFile).getName());
    }
    return result;
}

[Buggy Hunk]
result.addAll(processJarItems(jar, result, file));

[Patch]
result.addAll(processJarItems(jar, file));