public void run()
    {
        while (running) {
            Queue<Job> jobQueue = gsNode.getJobQueue();
            // System.out.println("Scheduling... (jobs: " + jobQueue.size() + ", RMs: " + gsNode.getMatchedRMs().size() + ")");
            
            // Cache the loads, so we can update them as "guesses"
            // before the actual loads change
            loadEstimates = new HashMap<String, Integer>();
            for (String rm : gsNode.getMatchedRMs()) {
                loadEstimates.put(rm, gsNode.getLoadForRM(rm));
            }
            
            // Schedule all jobs in the current queue
            // Note that the queue may be added to in the process, so we
            // explicitly iterate up to size()
            // Need to make sure that we never remove(E) in another thread!
            int length = jobQueue.size();
            for (int i = 0; i < length; i++) {
                Job job = jobQueue.peek();
                boolean scheduled = scheduleJob(job);
                if (scheduled) {
                    jobQueue.remove();
                } else {
                    // Can't schedule right now
                    break;
                }
            }
            
            try {
                Thread.sleep(pollSleep);
            } catch (InterruptedException ex) {
                System.out.println("Scheduler " + gsNode.getId() + " was interrupted.");
            }
        }
    }