class Combine implements Runnable {

    private final OpenOrdLayout layout;
    private final Object lock = new Object();
    private final Control control;

    public Combine(OpenOrdLayout layout) {
        this.layout = layout;
        this.control = layout.getControl();
    }

    @Override
    public void run() {<FILL_FUNCTION_BODY>}

    private void printPositions(Node[] nodes) {
        NumberFormat formatter = DecimalFormat.getInstance();
        formatter.setMaximumFractionDigits(2);
        for (Node node : nodes) {
            String xStr = formatter.format(node.x);
            String yStr = formatter.format(node.y);
        }
    }

    public float getTotEnergy() {
        float totEnergy = 0;
        for (Worker w : layout.getWorkers()) {
            totEnergy += w.getTotEnergy();
        }
        return totEnergy;
    }

    public void waitForIteration() {
        try {
            synchronized (lock) {
                lock.wait();
            }
        } catch (InterruptedException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
}

        //System.out.println("Combine results");

        Worker[] workers = layout.getWorkers();

        //Gather positions
        Node[] positions = null;
        for (Worker w : workers) {
            if (positions == null) {
                positions = w.getPositions();
            } else {
                Node[] workerPositions = w.getPositions();
                for (int i = w.getId(); i < positions.length; i += workers.length) {
                    positions[i] = workerPositions[i];
                }
            }
        }

        //Unfix positions if necessary
        if (!control.isRealFixed()) {
            for (Node n : positions) {
                n.fixed = false;
            }
        }

        //Combine density
        for (Worker w : workers) {
            DensityGrid densityGrid = w.getDensityGrid();
            boolean fineDensity = w.isFineDensity();
            boolean firstAdd = w.isFirstAdd();
            boolean fineFirstAdd = w.isFineFirstAdd();
            Node[] wNodes = w.getPositions();
            for (Worker z : workers) {
                if (w != z) {
                    Node[] zNodes = w.getPositions();
                    for (int i = z.getId(); i < wNodes.length; i += workers.length) {
                        densityGrid.substract(wNodes[i], firstAdd, fineFirstAdd, fineDensity);
                        densityGrid.add(zNodes[i], fineDensity);
                    }
                }
            }
        }

        //Redistribute positions to workers
        if (workers.length > 1) {
            for (Worker w : workers) {
                Node[] positionsCopy = new Node[positions.length];
                for (int i = 0; i < positions.length; i++) {
                    positionsCopy[i] = positions[i].clone();
                }
                w.setPositions(positionsCopy);
            }
        }

        float totEnergy = getTotEnergy();
        boolean done = !control.udpateStage(totEnergy);

        //Params
        for (Worker w : layout.getWorkers()) {
            control.initWorker(w);
        }

        //Write positions to nodes
        Graph graph = layout.getGraph();
        for (org.gephi.graph.api.Node n : graph.getNodes()) {
            if (n.getLayoutData() != null && n.getLayoutData() instanceof OpenOrdLayoutData) {
                OpenOrdLayoutData layoutData = n.getLayoutData();
                Node node = positions[layoutData.nodeId];
                n.setX(node.x * 10f);
                n.setY(node.y * 10f);
            }
        }

        //Finish
        if (!layout.canAlgo() || done) {
            for (Worker w : layout.getWorkers()) {
                w.setDone(true);
            }
            layout.setRunning(false);
        }

        //Synchronize with layout goAlgo()
        synchronized (lock) {
            lock.notify();
        }
    
<no_super_class>