public VoteResultFinder(VotingRound votingRound)
    {    	
        List<Vote> votes     = votingRound.getVotes();
        int        voteCount = votes.size();
        
        this.voterGraph  = new DirectedGraph(2 + voteCount, null); // one node per voter + source & sink nodes
        this.sourceNode  = this.voterGraph.nodeCount() - 1;
        this.sinkNode    = this.voterGraph.nodeCount() - 2;
        this.votingRound = votingRound;
        
        // Populate voter adjacency graph
        for (int i = 0; i < voteCount; i++)
        {
            Vote v1 = votes.get(i);
            for (int j = 0; j < voteCount; j++)
            {
                Vote v2 = votes.get(j);
                if (v1.getVoteType() != v2.getVoteType() && v1.getVoteToKick() == v2.getVoteToKeep() && i != j)
                {
                    DirectedEdge newEdge;
                    if (v1.getVoteType() == VoteType.forCat)
                        newEdge = new DirectedEdge(i, j); 
                    else // v1.getVoteType() == VoteType.forDog)
                        newEdge = new DirectedEdge(j, i);    
                    
                    // conditional addresses the case where two voters have opposing votes
                    if (!this.voterGraph.getAdjacentNodes(newEdge.getStart()).contains(newEdge.getEnd()))
                        this.voterGraph.addEdge(newEdge);
                }
            }
        }
        
        // connect source and sink nodes for maximum matching alorithm
        for (int i = 0; i < voteCount; i++)
        {
            if (votes.get(i).getVoteType() == VoteType.forCat)
                this.voterGraph.addEdge(new DirectedEdge(sourceNode, i));
            else // votes.get(i).getVoteType() == VoteType.forDog)
                this.voterGraph.addEdge(new DirectedEdge(i, sinkNode));
        }        
    }