#vulnerable code 
                                public Vote lookForLeader() throws InterruptedException {
        HashMap<Long, Vote> recvset = new HashMap<Long, Vote>();

        HashMap<Long, Vote> outofelection = new HashMap<Long, Vote>();

        int notTimeout = finalizeWait;
        
        synchronized(this){
            logicalclock++;
            updateProposal(self.getId(), self.getLastLoggedZxid());
        }
        
        LOG.info("New election: " + proposedZxid);
        sendNotifications();

        /*
         * Loop in which we exchange notifications until we find a leader
         */

        while (self.getPeerState() == ServerState.LOOKING) {
            /*
             * Remove next notification from queue, times out after 2 times
             * the termination time
             */
            Notification n = recvqueue.poll(notTimeout, TimeUnit.MILLISECONDS);
            
            /*
             * Sends more notifications if haven't received enough.
             * Otherwise processes new notification.
             */
            if(n == null){
            	if(manager.haveDelivered()){
            		sendNotifications();
            	} else {
            	    manager.connectAll();
            	}
            	
            	/*
            	 * Exponential backoff
            	 */
            	int tmpTimeOut = notTimeout*2;
            	notTimeout = (tmpTimeOut < maxNotificationInterval? tmpTimeOut : maxNotificationInterval);
            	LOG.info("Notification time out: " + notTimeout);
            }
            else { 
                //notTimeout = finalizeWait;
                switch (n.state) { 
                case LOOKING:
                    // If notification > current, replace and send messages out
                    LOG.info("Notification: " + n.leader + ", " + n.zxid + ", " + 
                            n.epoch + ", " + self.getId() + ", " + self.getPeerState() + 
                            ", " + n.state + ", " + n.sid);
                    if (n.epoch > logicalclock) {
                        logicalclock = n.epoch;
                        recvset.clear();
                        if(totalOrderPredicate(n.leader, n.zxid, self.getId(), self.getLastLoggedZxid()))
                            updateProposal(n.leader, n.zxid);
                        else
                            updateProposal(self.getId(), self.getLastLoggedZxid());
                        sendNotifications();
                    } else if (n.epoch < logicalclock) {
                        LOG.info("n.epoch < logicalclock");
                        break;
                    } else if (totalOrderPredicate(n.leader, n.zxid, proposedLeader, proposedZxid)) {
                        LOG.info("Updating proposal");
                        updateProposal(n.leader, n.zxid);
                        sendNotifications();
                    }
                
                    LOG.info("Adding vote");
                    recvset.put(n.sid, new Vote(n.leader, n.zxid, n.epoch));

                    //If have received from all nodes, then terminate
                    if (self.quorumPeers.size() == recvset.size()) {
                        self.setPeerState((proposedLeader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                        leaveInstance();
                        return new Vote(proposedLeader, proposedZxid);
                        
                    } else if (termPredicate(recvset, new Vote(proposedLeader, proposedZxid, logicalclock))) {
                        //Otherwise, wait for a fixed amount of time
                        LOG.debug("Passed predicate");

                        // Verify if there is any change in the proposed leader
                        while((n = recvqueue.poll(finalizeWait, TimeUnit.MILLISECONDS)) != null){
                            if(totalOrderPredicate(n.leader, n.zxid, proposedLeader, proposedZxid)){
                                recvqueue.put(n);
                                break;
                            }
                        }
                    
                        if (n == null) {
                            self.setPeerState((proposedLeader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                            LOG.info("About to leave instance:" + proposedLeader + ", " + 
                                    proposedZxid + ", " + self.getId() + ", " + self.getPeerState());
                            leaveInstance();
                            return new Vote(proposedLeader,
                                proposedZxid);
                        }
                    }
                    break;
                case LEADING:
                    /*
                     * There is at most one leader for each epoch, so if a peer claims to
                     * be the leader for an epoch, then that peer must be the leader (no
                     * arbitrary failures assumed). Now, if there is no quorum supporting 
                     * this leader, then processes will naturally move to a new epoch.
                     */
                    if(n.epoch == logicalclock){
                        self.setPeerState((n.leader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                   
                        leaveInstance();
                        return new Vote(n.leader, n.zxid);
                    }
                case FOLLOWING:
                    LOG.info("Notification: " + n.leader + ", " + n.zxid + 
                            ", " + n.epoch + ", " + self.getId() + ", " + 
                            self.getPeerState() + ", " + n.state + ", " + n.sid);
       
                    outofelection.put(n.sid, new Vote(n.leader, n.zxid, n.epoch, n.state));

                    if (termPredicate(outofelection, new Vote(n.leader, n.zxid, n.epoch, n.state))
                            && checkLeader(outofelection, n.leader, n.epoch)) {
                        synchronized(this){
                            logicalclock = n.epoch;
                            self.setPeerState((n.leader == self.getId()) ? 
                                    ServerState.LEADING: ServerState.FOLLOWING);
                        }
                        leaveInstance();
                        return new Vote(n.leader, n.zxid);
                    }
                    break;
                default:
                    break;
                }
            }
        }

        return null;
    } 
                            #location 35 
                            #vulnerability type THREAD_SAFETY_VIOLATION
#fixed code
                                public Vote lookForLeader() throws InterruptedException {
        HashMap<Long, Vote> recvset = new HashMap<Long, Vote>();

        HashMap<Long, Vote> outofelection = new HashMap<Long, Vote>();

        int notTimeout = finalizeWait;
        
        synchronized(this){
            logicalclock++;
            updateProposal(self.getId(), self.getLastLoggedZxid());
        }
        
        LOG.info("New election: " + proposedZxid);
        sendNotifications();

        /*
         * Loop in which we exchange notifications until we find a leader
         */

        while (self.getPeerState() == ServerState.LOOKING) {
            /*
             * Remove next notification from queue, times out after 2 times
             * the termination time
             */
            Notification n = recvqueue.poll(notTimeout, TimeUnit.MILLISECONDS);
            
            /*
             * Sends more notifications if haven't received enough.
             * Otherwise processes new notification.
             */
            if(n == null){
            	if(manager.haveDelivered()){
            		sendNotifications();
            	} else {
            	    manager.connectAll();
            	}
            	
            	/*
            	 * Exponential backoff
            	 */
            	int tmpTimeOut = notTimeout*2;
            	notTimeout = (tmpTimeOut < maxNotificationInterval? tmpTimeOut : maxNotificationInterval);
            	LOG.info("Notification time out: " + notTimeout);
            }
            else { 
                //notTimeout = finalizeWait;
                switch (n.state) { 
                case LOOKING:
                    // If notification > current, replace and send messages out
                    LOG.info("Notification: " + n.leader + ", " + n.zxid + ", " + 
                            n.epoch + ", " + self.getId() + ", " + self.getPeerState() + 
                            ", " + n.state + ", " + n.sid);
                    if (n.epoch > logicalclock) {
                        LOG.debug("Increasing logical clock: " + n.epoch);
                        logicalclock = n.epoch;
                        recvset.clear();
                        if(totalOrderPredicate(n.leader, n.zxid, self.getId(), self.getLastLoggedZxid()))
                            updateProposal(n.leader, n.zxid);
                        else
                            updateProposal(self.getId(), self.getLastLoggedZxid());
                        sendNotifications();
                    } else if (n.epoch < logicalclock) {
                        LOG.info("n.epoch < logicalclock");
                        break;
                    } else if (totalOrderPredicate(n.leader, n.zxid, proposedLeader, proposedZxid)) {
                        LOG.info("Updating proposal");
                        updateProposal(n.leader, n.zxid);
                        sendNotifications();
                    }
                
                    LOG.info("Adding vote");
                    recvset.put(n.sid, new Vote(n.leader, n.zxid, n.epoch));

                    //If have received from all nodes, then terminate
                    if (self.quorumPeers.size() == recvset.size()) {
                        self.setPeerState((proposedLeader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                        leaveInstance();
                        return new Vote(proposedLeader, proposedZxid);
                        
                    } else if (termPredicate(recvset, new Vote(proposedLeader, proposedZxid, logicalclock))) {
                        //Otherwise, wait for a fixed amount of time
                        LOG.debug("Passed predicate");

                        // Verify if there is any change in the proposed leader
                        while((n = recvqueue.poll(finalizeWait, TimeUnit.MILLISECONDS)) != null){
                            if(totalOrderPredicate(n.leader, n.zxid, proposedLeader, proposedZxid)){
                                recvqueue.put(n);
                                break;
                            }
                        }
                    
                        if (n == null) {
                            self.setPeerState((proposedLeader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                            LOG.info("About to leave instance:" + proposedLeader + ", " + 
                                    proposedZxid + ", " + self.getId() + ", " + self.getPeerState());
                            leaveInstance();
                            return new Vote(proposedLeader,
                                proposedZxid);
                        }
                    }
                    break;
                case LEADING:
                    /*
                     * There is at most one leader for each epoch, so if a peer claims to
                     * be the leader for an epoch, then that peer must be the leader (no
                     * arbitrary failures assumed). Now, if there is no quorum supporting 
                     * this leader, then processes will naturally move to a new epoch.
                     */
                    if(n.epoch == logicalclock){
                        self.setPeerState((n.leader == self.getId()) ? 
                                ServerState.LEADING: ServerState.FOLLOWING);
                   
                        leaveInstance();
                        return new Vote(n.leader, n.zxid);
                    }
                case FOLLOWING:
                    LOG.info("Notification: " + n.leader + ", " + n.zxid + 
                            ", " + n.epoch + ", " + self.getId() + ", " + 
                            self.getPeerState() + ", " + n.state + ", " + n.sid);
       
                    outofelection.put(n.sid, new Vote(n.leader, n.zxid, n.epoch, n.state));

                    if (termPredicate(outofelection, new Vote(n.leader, n.zxid, n.epoch, n.state))
                            && checkLeader(outofelection, n.leader, n.epoch)) {
                        synchronized(this){
                            logicalclock = n.epoch;
                            self.setPeerState((n.leader == self.getId()) ? 
                                    ServerState.LEADING: ServerState.FOLLOWING);
                        }
                        leaveInstance();
                        return new Vote(n.leader, n.zxid);
                    }
                    break;
                default:
                    break;
                }
            }
        }

        return null;
    }