During the development and review process of the disk health indicator we noticed that it was hard to understand. Since we learnt a lot from the first round of development we want to go through the code one more time and restructure it.
server/src/main/java/org/elasticsearch/cluster/routing/RoutingNode.java
sb.append("routingNode ([");
        if (node != null) {
            sb.append(node.getName());
            sb.append("][");
            sb.append(node.getId());
            sb.append("][");
            sb.append(node.getHostName());
            sb.append("][");
            sb.append(node.getHostAddress());
        } else {
            sb.append("null");
        }
        sb.append("], [");
        sb.append(shards.size());
        sb.append(" assigned shards])");
        return sb.toString();
    }
    public ShardRouting[] copyShards() {
        return shards.values().toArray(EMPTY_SHARD_ROUTING_ARRAY);
    }
    public boolean isEmpty() {
        return shards.isEmpty();
    }
    boolean invariant() {
        var shardRoutingsInitializing = new ArrayList<ShardRouting>(shards.size());
        var shardRoutingsRelocating = new ArrayList<ShardRouting>(shards.size());
        var shardRoutingsStarted = new ArrayList<ShardRouting>(shards.size());
        
        var shardRoutingsByIndex = Maps.<Index, Set<ShardRouting>>newHashMapWithExpectedSize(shards.size());
        for (var shard : shards.values()) {