public void removeNetworkingBlocks(Collection<T> networkNodes) {
    if (networkNodes.size() == 0) {
      return;
    }
    // This performance improvement is needed until the split detection (above) is improved, after
    // that it can be
    // removed
    validateNotMutating();
    mutating = true;
    try {
      Set<SimpleNetwork<T>> affectedNetworks = Sets.newHashSet();
      for (T networkNode : networkNodes) {
        final SimpleNetwork<T> networkWithBlock = findNetworkWithNetworkingBlock(networkNode);
        if (networkWithBlock == null) {
          throw new IllegalStateException(
              "Trying to remove a networking block that doesn't belong to any network");
        }

        affectedNetworks.add(networkWithBlock);
        networkingNodes.remove(networkNode.location, networkNode);
      }

      List<Set<T>> listOfNodesFromModifiedNetworks = Lists.newLinkedList();
      for (SimpleNetwork<T> networkWithBlock : affectedNetworks) {
        Set<T> leafNodesToNotify = Sets.newHashSet(networkWithBlock.getLeafNodes());
        Set<T> networkingNodesToNotify = Sets.newHashSet(networkWithBlock.getNetworkingNodes());

        networkWithBlock.removeAllLeafNodes();
        notifyLeafNodesAdded(networkWithBlock, leafNodesToNotify);
        networkWithBlock.removeAllNetworkingNodes();
        notifyNetworkingNodesRemoved(
            networkWithBlock, Collections.unmodifiableSet(networkingNodesToNotify));

        networks.remove(networkWithBlock);
        notifyNetworkRemoved(networkWithBlock);
      }

      for (Set<T> networkingNodesInModifiedNetwork : listOfNodesFromModifiedNetworks) {
        for (T networkingNode : networkingNodesInModifiedNetwork) {
          if (!networkNodes.contains(networkingNode)) {
            addNetworkingBlockInternal(networkingNode);
          }
        }
      }
    } finally {
      mutating = false;
    }
  }
  public void removeNetworkingBlock(T networkNode) {
    validateNotMutating();
    mutating = true;
    try {
      SimpleNetwork<T> networkWithBlock = findNetworkWithNetworkingBlock(networkNode);

      if (networkWithBlock == null) {
        throw new IllegalStateException(
            "Trying to remove a networking block that doesn't belong to any network");
      }

      networkingNodes.remove(networkNode.location, networkNode);

      // Naive implementation, just remove everything and start over
      // TODO: Improve to actually detects the branches of splits and build separate network for
      // each disjunctioned
      // TODO: network
      Set<T> networkingNodesToNotify = Sets.newHashSet(networkWithBlock.getNetworkingNodes());
      Set<T> leafNodesToNotify = Sets.newHashSet(networkWithBlock.getLeafNodes());

      networkWithBlock.removeAllLeafNodes();
      notifyLeafNodesRemoved(networkWithBlock, leafNodesToNotify);
      networkWithBlock.removeAllNetworkingNodes();
      notifyNetworkingNodesRemoved(
          networkWithBlock, Collections.unmodifiableSet(networkingNodesToNotify));

      networks.remove(networkWithBlock);
      notifyNetworkRemoved(networkWithBlock);

      for (T networkingNode : networkingNodesToNotify) {
        if (!networkingNode.equals(networkNode)) {
          addNetworkingBlockInternal(networkingNode);
        }
      }
    } finally {
      mutating = false;
    }
  }
  private void addNetworkingBlockInternal(T networkNode) {
    SimpleNetwork<T> addToNetwork = null;

    Set<T> networkingNodesToAdd = Sets.newHashSet();
    networkingNodesToAdd.add(networkNode);

    Set<T> newLeafNodes = Sets.newHashSet();

    // Try adding to existing networks
    final Iterator<SimpleNetwork<T>> networkIterator = networks.iterator();
    while (networkIterator.hasNext()) {
      final SimpleNetwork<T> network = networkIterator.next();
      if (network.canAddNetworkingNode(networkNode)) {
        if (addToNetwork == null) {
          addToNetwork = network;
        } else {
          Set<T> networkingNodesToNotify = Sets.newHashSet(network.getNetworkingNodes());
          Set<T> leafNodesToNotify = Sets.newHashSet(network.getLeafNodes());

          networkingNodesToAdd.addAll(networkingNodesToNotify);
          newLeafNodes.addAll(leafNodesToNotify);

          network.removeAllLeafNodes();
          notifyLeafNodesRemoved(network, leafNodesToNotify);
          network.removeAllNetworkingNodes();
          notifyNetworkingNodesRemoved(network, networkingNodesToNotify);

          networkIterator.remove();
          notifyNetworkRemoved(network);
        }
      }
    }

    // If it's not in any networks, create a new one
    if (addToNetwork == null) {
      SimpleNetwork<T> newNetwork = new SimpleNetwork<>();
      networks.add(newNetwork);
      notifyNetworkAdded(newNetwork);
      addToNetwork = newNetwork;
    }

    for (T networkingNode : networkingNodesToAdd) {
      addToNetwork.addNetworkingNode(networkingNode);
    }
    notifyNetworkingNodesAdded(addToNetwork, networkingNodesToAdd);

    for (T leafNode : newLeafNodes) {
      addToNetwork.addLeafNode(leafNode);
    }

    // Find all leaf nodes that it joins to its network
    for (T leafNode : leafNodes.values()) {
      if (addToNetwork.canAddLeafNode(leafNode)) {
        addToNetwork.addLeafNode(leafNode);
        newLeafNodes.add(leafNode);
      }
    }

    if (newLeafNodes.size() > 0) {
      notifyLeafNodesAdded(addToNetwork, newLeafNodes);
    }
  }