public static Collection<Properties> getConnectionProperties(URI uri) {
   ServerDescriptor serverDescriptor = SERVERS.get(createKey(uri));
   if (serverDescriptor != null) {
     return serverDescriptor.getConnections().values();
   } else {
     return Collections.emptyList();
   }
 }
  @Override
  public Connection connect(URI uri, Properties properties) throws ConnectionException {

    if (PASSTHROUGH.equals(uri.getScheme())) {
      if (STRIPES.containsKey(uri.getAuthority())) {
        String serverName = uri.getHost();
        PassthroughServer server =
            PassthroughServerRegistry.getSharedInstance().getServerForName(serverName);
        if (null != server) {
          String connectionName = properties.getProperty("connection.name");
          if (null == connectionName) {
            connectionName = "Ehcache:ACTIVE-PASSIVE";
          }

          Connection connection = server.connectNewClient(connectionName);
          STRIPES.get(uri.getAuthority()).add(connection);
          return connection;
        }
      } else {
        throw new IllegalArgumentException(
            "UnitTestConnectionService failed to find stripe" + uri.getAuthority());
      }
    }

    checkURI(uri);

    ServerDescriptor serverDescriptor = SERVERS.get(uri);
    if (serverDescriptor == null) {
      throw new IllegalArgumentException("No server available for " + uri);
    }

    String name = properties.getProperty(ConnectionPropertyNames.CONNECTION_NAME);
    if (name == null) {
      name = "Ehcache:UNKNOWN";
    }
    Connection connection = serverDescriptor.server.connectNewClient(name);
    serverDescriptor.add(connection, properties);

    LOGGER.info("Client opened {} to PassthroughServer at {}", formatConnectionId(connection), uri);

    /*
     * Uses a Proxy around Connection so closed connections can be removed from the ServerDescriptor.
     */
    return (Connection)
        Proxy.newProxyInstance(
            Connection.class.getClassLoader(),
            new Class[] {Connection.class},
            new ConnectionInvocationHandler(serverDescriptor, connection));
  }
    @Override
    @SuppressWarnings("unchecked")
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      if (method.getName().equals("close")) {
        serverDescriptor.remove(connection);
        LOGGER.info("Client closed {}", formatConnectionId(connection));
      }

      if (method.getName().equals("getEntityRef")) {
        serverDescriptor.addKnownEntity((Class<? extends Entity>) args[0], args[1], args[2]);
      }
      try {
        return method.invoke(connection, args);
      } catch (InvocationTargetException e) {
        throw e.getCause();
      }
    }
  /**
   * Removes the {@link PassthroughServer} previously associated with the {@code URI} provided. The
   * server is stopped as it is removed. In addition to stopping the server, all open {@link
   * Connection} instances created through the {@link #connect(URI, Properties)} method are closed;
   * this is done to clean up the threads started in support of each open connection.
   *
   * @param uri the {@code URI} for which the server is removed
   * @return the removed {@code PassthroughServer}
   */
  public static PassthroughServer remove(URI uri) {
    URI keyURI = createKey(uri);
    ServerDescriptor serverDescriptor = SERVERS.remove(keyURI);
    if (serverDescriptor != null) {
      for (Connection connection : serverDescriptor.getConnections().keySet()) {
        try {
          LOGGER.warn("Force close {}", formatConnectionId(connection));
          connection.close();
        } catch (AssertionError e) {
          // Ignored -- https://github.com/Terracotta-OSS/terracotta-apis/issues/102
        } catch (IOException e) {
          // Ignored
        }
      }

      // open destroy connection.  You need to make sure connection doesn't have any entities
      // associated with it.
      PassthroughConnection connection =
          serverDescriptor.server.connectNewClient("destroy-connection");

      for (Entry entry : serverDescriptor.knownEntities.entrySet()) {
        @SuppressWarnings("unchecked")
        Class<? extends Entity> type = (Class) entry.getKey();
        List args = (List) entry.getValue();
        Long version = (Long) args.get(0);
        String stringArg = (String) args.get(1);

        try {
          EntityRef entityRef = connection.getEntityRef(type, version, stringArg);
          entityRef.destroy();
        } catch (EntityNotProvidedException ex) {
          LOGGER.error("Entity destroy failed: ", ex);
        } catch (EntityNotFoundException ex) {
          LOGGER.error("Entity destroy failed: ", ex);
        } catch (PermanentEntityException ex) {
          LOGGER.error("Entity destroy failed (permanent???): ", ex);
        }
      }

      serverDescriptor.server.stop();
      LOGGER.info("Stopped PassthroughServer at {}", keyURI);
      return serverDescriptor.server;
    } else {
      return null;
    }
  }