anchor.diff:              one_level(NewGD, NewWeights, NewModularity)
       end.
   
  +% Remove 2*CommWeight when edge is copmletely in the community
  +% self edges are not doubled
   remove_node(NodeComm, NodeDegree, CommWeight, Weights = #louvain_weights{}) ->
       Weights#louvain_weights{weights = dict:update(
           NodeComm,
  
positive.code:     dict:fold(
          fun(_, {AW, CW}, Modularity) ->
              Modularity + CW/M -
              math:pow(AW/(M * 2.0), 2)
          end, 0, WeightsD).
  
  
negative.code: one_level(GD0 = #louvain_graphd{}, Weights0 = #louvain_weights{}, Modularity) ->
      % XXX make sure the graph is valid
      validate_graph(GD0),
      EdgesD = GD0#louvain_graphd.edgesd,
      {Modified, NewWeights, NewCommunitiesD} = dict:fold(
          fun(Node, NodeNeighbors, {Mods, Weights, CommunitiesD}) ->
              NodeComm = dict_lookup(Node, CommunitiesD),
              {NodeDegree, NeighborCommWeightsD} =
                          neighboring_community_weights(Node,
                                                        NodeNeighbors,
                                                        EdgesD,
                                                        CommunitiesD),
              LookupCommWeight = fun(Comm) ->
                                     dict_lookup(Comm, NeighborCommWeightsD, 0.0)
                                 end,
              % 2k(i)sum(tot)/2m
              %  k(i) === NodeDegree
              %  sum(tot) === CommunityAllDegree
              DegCTotW = NodeDegree / (Weights#louvain_weights.m * 2.0),
              Weights1 = remove_node(NodeComm,
                                     NodeDegree,
                                     LookupCommWeight(NodeComm),
                                     Weights),
              % test node in each neighboring community and find the
              % community that gives the best modularity gain
              {BestComm, _} = dict:fold(
                  fun(Community,
                          CommunityWeight,
                          {TopCommunity, TopModularityGain}) ->
                      {CommunityDegree, _} =
                          dict_lookup(Community,
                                      Weights1#louvain_weights.weights,
                                      {0,0}),
                      % XXX modualarity gain needs another 2m in the denominator
                      ModularityGain =
                                  CommunityWeight - CommunityDegree * DegCTotW,
                      case ModularityGain > TopModularityGain of
                          true -> {Community, ModularityGain};
                          false -> {TopCommunity, TopModularityGain}
                      end
                  end, {NodeComm, 0.0}, NeighborCommWeightsD),
              Weights2 = add_node(BestComm,
                                  NodeDegree,
                                  LookupCommWeight(BestComm),
                                  Weights1),
  % XXX check weights
  
              {(BestComm /= NodeComm) or Mods,
               Weights2,
               dict:store(Node, BestComm, CommunitiesD)}
          end,
          {false, Weights0, GD0#louvain_graphd.communitiesd},
          GD0#louvain_graphd.neighborsd),
          NewGD = GD0#louvain_graphd{communitiesd = NewCommunitiesD},
  
      % XXX recompute weights and see if they match the new weights
      compare_weights(NewWeights, weights(NewGD)),
  
      NewModularity = modularity(NewWeights),
      ?DEBUG("OneLevel Modularity: ~p -> ~p", [Modularity, NewModularity]),
      % stop if the communities didn't change, or the modularity did not
      % increase by very much, or (due to a buggy implementation) the
      % modularity is more than 1.0.
  