class ClusterOverviewProcedure extends CallableProcedure.BasicProcedure {

    @Override
    public RawIterator<Object[],ProcedureException> apply(
            Context ctx, Object[] input, ResourceTracker resourceTracker )
    {
        Map<MemberId,RoleInfo> roleMap = topologyService.allCoreRoles();
        List<ReadWriteEndPoint> endpoints = new ArrayList<>();

        CoreTopology coreTopology = topologyService.allCoreServers();
        Set<MemberId> coreMembers = coreTopology.members().keySet();

        for ( MemberId memberId : coreMembers )
        {
            Optional<CoreServerInfo> coreServerInfo = coreTopology.find( memberId );
            if ( coreServerInfo.isPresent() )
            {
                CoreServerInfo info = coreServerInfo.get();
                RoleInfo role = roleMap.getOrDefault( memberId, RoleInfo.UNKNOWN );
                endpoints.add( new ReadWriteEndPoint( info.connectors(), role, memberId.getUuid(),
                        asList( info.groups() ), info.getDatabaseName() ) );
            }
            else
            {
                log.debug( "No Address found for " + memberId );
            }
        }

        for ( Map.Entry<MemberId,ReadReplicaInfo> readReplica : topologyService.allReadReplicas().members().entrySet() )
        {
            ReadReplicaInfo readReplicaInfo = readReplica.getValue();
            endpoints.add( new ReadWriteEndPoint( readReplicaInfo.connectors(), RoleInfo.READ_REPLICA,
                    readReplica.getKey().getUuid(), asList( readReplicaInfo.groups() ), readReplicaInfo.getDatabaseName() ) );
        }

        endpoints.sort( comparing( o -> o.addresses().toString() ) );

        return map( endpoint -> new Object[]
                        {
                                endpoint.memberId().toString(),
                                endpoint.addresses().uriList().stream().map( URI::toString ).collect( Collectors.toList() ),
                                endpoint.role().name(),
                                endpoint.groups(),
                                endpoint.dbName()
                        },
                asRawIterator( endpoints.iterator() ) );
    }

    public  ClusterOverviewProcedure( TopologyService topologyService, LogProvider logProvider );

}