public void computeSALSA(int nIterations) {
        for(int iter=0; iter < nIterations; iter++) {
            // Hubs: sum of authority-neighbors values divided by their degree
            for(SalsaVertex hub: hubs.values()) {
                double nbSum = 0.0;
                // Update the degree because not all authorities were selected
                int degree = 0;
                for(int authId : hub.neighbors) {
                    SalsaVertex auth = authorities.get(authId);
                    if (auth != null) {
                        nbSum += auth.value / auth.degree;
                        degree++;
                    }
                }
                hub.value = nbSum;
                hub.degree = degree;
            }

            // Authorities: push from authority side.
            // First: set values to zero
            for(SalsaVertex auth: authorities.values()) {
                auth.value = 0;
            }

            // Then, push hubs values to their auths
            for(SalsaVertex hub: hubs.values()) {
                double myContribution = hub.value / hub.degree;
                for(int authId : hub.neighbors) {
                    SalsaVertex auth = authorities.get(authId);
                    if (auth != null) {
                        auth.value += myContribution;
                    }
                }
            }
        }
    }