[Demonstration 1]

[Buggy Method]
@Override
public synchronized void createTable(Table table, PrincipalPrivileges principalPrivileges) {
    TableType tableType = TableType.valueOf(table.getTableType());
    checkArgument(EnumSet.of(MANAGED_TABLE, EXTERNAL_TABLE, VIRTUAL_VIEW).contains(tableType), "Invalid table type: %s", tableType);
    SchemaTableName schemaTableName = new SchemaTableName(table.getDatabaseName(), table.getTableName());
    if (tableType == VIRTUAL_VIEW) {
        checkArgument(table.getStorage().getLocation() == null, "Storage location for view must be null");
    } else {
        File directory = new File(URI.create(table.getStorage().getLocation()));
        if (!directory.exists()) {
            throw new PrestoException(HIVE_METASTORE_ERROR, "Table directory does not exist");
        }
        if (tableType == MANAGED_TABLE && !isParentDir(directory, baseDirectory)) {
            throw new PrestoException(HIVE_METASTORE_ERROR, "Table directory must be inside of the metastore base directory");
        }
    }
    if (relations.putIfAbsent(schemaTableName, table) != null) {
        throw new TableAlreadyExistsException(schemaTableName);
    }
    for (Entry<String, Collection<HivePrivilegeInfo>> entry : principalPrivileges.getUserPrivileges().asMap().entrySet()) {
        setTablePrivileges(entry.getKey(), USER, table.getDatabaseName(), table.getTableName(), entry.getValue());
    }
    for (Entry<String, Collection<HivePrivilegeInfo>> entry : principalPrivileges.getRolePrivileges().asMap().entrySet()) {
        setTablePrivileges(entry.getKey(), ROLE, table.getDatabaseName(), table.getTableName(), entry.getValue());
    }
}

[Buggy Hunk]
checkArgument(table.getStorage().getLocation() == null, "Storage location for view must be null");

[Patch]
checkArgument(table.getStorage().getLocation().isEmpty(), "Storage location for view must be empty");

[Demonstration 2]

[Buggy Method]
private void resetTimer() {
    context.checkThread();
    // Because of asynchronous execution, the candidate state could have already been closed. In that case,
    // simply skip the election.
    if (isClosed())
        return;
    // Cancel the current timer task and purge the election timer of cancelled tasks.
    if (currentTimer != null) {
        currentTimer.cancel(false);
    }
    // When the election timer is reset, increment the current term and
    // restart the election.
    context.setTerm(context.getTerm() + 1);
    long delay = context.getElectionTimeout() + (random.nextInt((int) context.getElectionTimeout()) % context.getElectionTimeout());
    currentTimer = context.executor().schedule(() -> {
        // When the election times out, clear the previous majority vote
        // check and restart the election.
        LOGGER.info("{} - Election timed out", context.getLocalMember());
        if (quorum != null) {
            quorum.cancel();
            quorum = null;
        }
        resetTimer();
        LOGGER.info("{} - Restarted election", context.getLocalMember());
    }, delay, TimeUnit.MILLISECONDS);
    final AtomicBoolean complete = new AtomicBoolean();
    // Send vote requests to all nodes. The vote request that is sent
    // to this node will be automatically successful.
    // First check if the quorum is null. If the quorum isn't null then that
    // indicates that another vote is already going on.
    final Quorum quorum = new Quorum((int) Math.floor(context.getActiveMembers().size() / 2) + 1, (elected) -> {
        complete.set(true);
        if (elected) {
            transition(CopycatState.LEADER);
        }
    });
    // First, load the last log entry to get its term. We load the entry
    // by its index since the index is required by the protocol.
    final Long lastIndex = context.log().lastIndex();
    ByteBuffer lastEntry = lastIndex != null ? context.log().getEntry(lastIndex) : null;
    // Once we got the last log term, iterate through each current member
    // of the cluster and poll each member for a vote.
    LOGGER.info("{} - Polling members {}", context.getLocalMember(), context.getActiveMembers());
    final Long lastTerm = lastEntry != null ? lastEntry.getLong() : null;
    for (String member : context.getActiveMembers()) {
        LOGGER.debug("{} - Polling {} for term {}", context.getLocalMember(), member, context.getTerm());
        PollRequest request = PollRequest.builder().withUri(member).withTerm(context.getTerm()).withCandidate(context.getLocalMember()).withLogIndex(lastIndex).withLogTerm(lastTerm).build();
        pollHandler.apply(request).whenCompleteAsync((response, error) -> {
            context.checkThread();
            if (isOpen() && !complete.get()) {
                if (error != null) {
                    LOGGER.trace(context.getLocalMember(), error);
                    quorum.fail();
                } else if (!response.voted()) {
                    LOGGER.info("{} - Received rejected vote from {}", context.getLocalMember(), member);
                    quorum.fail();
                } else if (response.term() != context.getTerm()) {
                    LOGGER.info("{} - Received successful vote for a different term from {}", context.getLocalMember(), member);
                    quorum.fail();
                } else {
                    LOGGER.info("{} - Received successful vote from {}", context.getLocalMember(), member);
                    quorum.succeed();
                }
            }
        }, context.executor());
    }
}

[Buggy Hunk]
final Quorum quorum = new Quorum((int) Math.floor(context.getActiveMembers().size() / 2) + 1, (elected) -> {

[Patch]
final Quorum quorum = new Quorum(context.getActiveMembers().size(), (int) Math.floor(context.getActiveMembers().size() / 2) + 1, (elected) -> {

[Demonstration 3]

[Buggy Method]
@RequestMapping(value = "/group/member", method = RequestMethod.GET)
public MomiaHttpResponse listGroupMembers(@RequestParam String utoken, @RequestParam long id) {
    if (StringUtils.isBlank(utoken))
        return MomiaHttpResponse.TOKEN_EXPIRED;
    if (id <= 0)
        return MomiaHttpResponse.BAD_REQUEST;
    List<ImUser> teachers = new ArrayList<ImUser>();
    List<ImUser> customers = new ArrayList<ImUser>();
    List<ImUser> members = imServiceApi.listGroupMembers(utoken, id);
    for (ImUser member : members) {
        member.setAvatar(ImageFile.smallUrl(member.getAvatar()));
        if (member.isTeacher())
            teachers.add(member);
        else
            customers.add(member);
    }
    JSONObject resultJson = new JSONObject();
    resultJson.put("teachers", teachers);
    resultJson.put("customers", customers);
    return MomiaHttpResponse.SUCCESS(resultJson);
}

[Buggy Hunk]
if (member.isTeacher()) teachers.add(member);

[Patch]
if (member.getRole() == User.Role.TEACHER) teachers.add(member);