class TileSetMetadataEnvoy extends AbstractEnvoy implements DataRegistryDataProvider {

    @Override
    public void query(DataModelCategory category, Collection<? extends Satisfaction> satisfactions,
            List<? extends PropertyMatcher<?>> parameters, List<? extends OrderSpecifier> orderSpecifiers, int limit,
            Collection<? extends PropertyDescriptor<?>> propertyDescriptors, CacheDepositReceiver queryReceiver)
                throws InterruptedException, QueryException
    {
        try
        {
            URL url = new URL(myServerUrl + Constants.TILE_SETS_URL + "/" + category.getCategory() + Constants.TILE_METADATA_URL);
            HttpServer server = getToolbox().getServerProviderRegistry().getProvider(HttpServer.class).getServer(url);
            ResponseValues responseValues = new ResponseValues();
            CancellableInputStream stream = server.sendGet(url, responseValues);
            if (responseValues.getResponseCode() == HttpURLConnection.HTTP_OK)
            {
                ObjectMapper mapper = JsonUtils.createMapper();
                TileSetMetadata tileSetMetadata = mapper.readValue(stream, TileSetMetadata.class);

                Collection<PropertyAccessor<TileSetMetadata, ?>> accessors = New.collection();
                accessors.add(SerializableAccessor.<TileSetMetadata, TileSetMetadata>getSingletonAccessor(Constants.TILESET_METADATA_PROPERTY_DESCRIPTOR,
                        tileSetMetadata));

                CacheDeposit<TileSetMetadata> deposit = new DefaultCacheDeposit<TileSetMetadata>(
                        new DataModelCategory(myServerUrl, category.getFamily(), category.getCategory()), accessors,
                        New.list(tileSetMetadata), true, DefaultCacheDeposit.SESSION_END, false);
                queryReceiver.receive(deposit);
            }
            else
            {
                StreamReader errorMessageReader = new StreamReader(stream);
                throw new QueryException(url.toString() + " returned code " + responseValues.getResponseCode() + " "
                        + responseValues.getResponseMessage() + " message "
                        + errorMessageReader.readStreamIntoString(StringUtilities.DEFAULT_CHARSET));
            }
        }
        catch (IOException | URISyntaxException | CacheException e)
        {
            throw new QueryException(e.getMessage(), e);
        }
    }

    public  TileSetMetadataEnvoy(Toolbox toolbox, String serverUrl);

}