class XYZImageProvider implements ImageProvider<ZYXImageKey> {

    @Override
    public Image getImage(ZYXImageKey key)
    {
        DataModelCategory imageCategory = new DataModelCategory(myLayer.getServerUrl(), XYZTileUtils.TILES_FAMILY,
                myLayer.getName());
        List<PropertyMatcher<?>> matchers = New.list();
        ZYXKeyPropertyMatcher keyMatcher = new ZYXKeyPropertyMatcher(XYZTileUtils.KEY_PROPERTY_DESCRIPTOR, key);
        matchers.add(keyMatcher);
        SimpleQuery<InputStream> query = new SimpleQuery<>(imageCategory, XYZTileUtils.IMAGE_PROPERTY_DESCRIPTOR, matchers);

        Image image = null;

        QueryTracker tracker = myRegistry.performQuery(query);

        if (query.getResults() != null && !query.getResults().isEmpty())
        {
            try
            {
                InputStream stream = query.getResults().get(0);

                StreamingDDSImage.setThreadByteBufferPool(ourByteBufferPool);
                try (ObjectInputStream ois = new CustomObjectInputStream(myClassProvider, stream))
                {
                    image = (Image)ois.readObject();
                }
                catch (ClassNotFoundException e)
                {
                    LOGGER.error(e, e);
                }
                finally
                {
                    StreamingDDSImage.setThreadByteBufferPool(null);
                }
            }
            catch (ClosedByInterruptException e)
            {
                if (LOGGER.isDebugEnabled())
                {
                    LOGGER.debug(e, e);
                }
            }
            catch (IOException e)
            {
                LOGGER.error(e, e);
            }
        }
        else if (tracker.getException() != null)
        {
            LOGGER.error(tracker.getException(), tracker.getException());
        }

        return image;
    }

    public  XYZImageProvider(DataRegistry registry, XYZTileLayerInfo layer);

}