protected HashMap<String, Double> computeModularity(Graph graph, CommunityStructure theStructure,
                                                        int[] comStructure,
                                                        double currentResolution, boolean randomized,
                                                        boolean weighted) {
        isCanceled = false;
        Progress.start(progress);
        Random rand = new Random();

        double totalWeight = theStructure.graphWeightSum;
        double[] nodeDegrees = theStructure.weights.clone();

        HashMap<String, Double> results = new HashMap<>();

        if (isCanceled) {
            return results;
        }
        boolean someChange = true;
        while (someChange) {
            someChange = false;
            boolean localChange = true;
            while (localChange) {
                localChange = false;
                int start = 0;
                if (randomized) {
                    start = Math.abs(rand.nextInt()) % theStructure.N;
                }
                int step = 0;
                for (int i = start; step < theStructure.N; i = (i + 1) % theStructure.N) {
                    step++;
                    Community bestCommunity = updateBestCommunity(theStructure, i, currentResolution);
                    if ((theStructure.nodeCommunities[i] != bestCommunity) && (bestCommunity != null)) {
                        theStructure.moveNodeTo(i, bestCommunity);
                        localChange = true;
                    }
                    if (isCanceled) {
                        return results;
                    }
                }
                someChange = localChange || someChange;
                if (isCanceled) {
                    return results;
                }
            }

            if (someChange) {
                theStructure.zoomOut();
            }
        }

        fillComStructure(graph, theStructure, comStructure);
        double[] degreeCount = fillDegreeCount(graph, theStructure, comStructure, nodeDegrees, weighted);

        double computedModularity = finalQ(comStructure, degreeCount, graph, theStructure, totalWeight, 1., weighted);
        double computedModularityResolution =
            finalQ(comStructure, degreeCount, graph, theStructure, totalWeight, currentResolution, weighted);

        results.put("modularity", computedModularity);
        results.put("modularityResolution", computedModularityResolution);

        return results;
    }
@Test
    public void testCyclicWithWeightsGraphModularity() {
        GraphModel graphModel = GraphModel.Factory.newInstance();
        UndirectedGraph undirectedGraph = graphModel.getUndirectedGraph();

        Node node1 = graphModel.factory().newNode("0");
        Node node2 = graphModel.factory().newNode("1");
        Node node3 = graphModel.factory().newNode("2");
        Node node4 = graphModel.factory().newNode("3");
        Node node5 = graphModel.factory().newNode("4");
        Node node6 = graphModel.factory().newNode("5");
        Node node7 = graphModel.factory().newNode("6");
        Node node8 = graphModel.factory().newNode("7");

        undirectedGraph.addNode(node1);
        undirectedGraph.addNode(node2);
        undirectedGraph.addNode(node3);
        undirectedGraph.addNode(node4);
        undirectedGraph.addNode(node5);
        undirectedGraph.addNode(node6);
        undirectedGraph.addNode(node7);
        undirectedGraph.addNode(node8);

        //Test 3 parallel edges summing weight = 10
        //Related issues ==> #1419 Getting null pointer error when trying to calculate modularity; #1526 NullPointerException on Modularity Statistics with gexf with kind / parallel nodes
        Edge edge12_1 = graphModel.factory().newEdge(node1, node2, 1, 2.f, false);
        Edge edge12_2 = graphModel.factory().newEdge(node1, node2, 2, 5.f, false);
        Edge edge12_3 = graphModel.factory().newEdge(node1, node2, 2, 3.f, false);

        Edge edge23 = graphModel.factory().newEdge(node2, node3, false);
        Edge edge34 = graphModel.factory().newEdge(node3, node4, 0, 10.f, false);
        Edge edge45 = graphModel.factory().newEdge(node4, node5, false);
        Edge edge56 = graphModel.factory().newEdge(node5, node6, 0, 10.f, false);
        Edge edge67 = graphModel.factory().newEdge(node6, node7, false);

        //Test 2 parallel edges summing weight = 10
        Edge edge78_1 = graphModel.factory().newEdge(node7, node8, 0, 5.f, false);
        Edge edge78_2 = graphModel.factory().newEdge(node7, node8, 0, 5.f, false);
        Edge edge81 = graphModel.factory().newEdge(node8, node1, false);

        undirectedGraph.addEdge(edge12_1);
        undirectedGraph.addEdge(edge12_2);
        undirectedGraph.addEdge(edge12_3);
        undirectedGraph.addEdge(edge23);
        undirectedGraph.addEdge(edge34);
        undirectedGraph.addEdge(edge45);
        undirectedGraph.addEdge(edge56);
        undirectedGraph.addEdge(edge67);
        undirectedGraph.addEdge(edge78_1);
        undirectedGraph.addEdge(edge78_2);
        undirectedGraph.addEdge(edge81);

        UndirectedGraph graph = graphModel.getUndirectedGraph();
        Modularity mod = new Modularity();

        Modularity.CommunityStructure theStructure = mod.new CommunityStructure(graph);
        int[] comStructure = new int[graph.getNodeCount()];

        HashMap<String, Double> modularityValues = mod.computeModularity(graph, theStructure, comStructure,
            1., true, true);

        int class1 = comStructure[0];
        int class2 = comStructure[1];
        int class4 = comStructure[3];
        int class5 = comStructure[4];
        int class7 = comStructure[6];
        int class8 = comStructure[7];

        assertEquals(class1, class2);
        assertEquals(class7, class8);
        Assert.assertNotEquals(class4, class5);
    }