class CloudnameService implements AutoCloseable {

    public void addServiceListener(
            final ServiceCoordinate coordinate, final ServiceListener listener) {
        if (coordinate == null) {
            throw new IllegalArgumentException("Coordinate can not be null");
        }
        if (listener == null) {
            throw new IllegalArgumentException("Listener can not be null");
        }
        // Just create the corresponding listener on the backend and translate the parameters
        // from the listener.
        final LeaseListener leaseListener = new LeaseListener() {
            @Override
            public void leaseCreated(final CloudnamePath path, final String data) {
                final InstanceCoordinate instanceCoordinate = new InstanceCoordinate(path);
                final ServiceData serviceData = ServiceData.fromJsonString(data);
                listener.onServiceCreated(instanceCoordinate, serviceData);
            }

            @Override
            public void leaseRemoved(final CloudnamePath path) {
                final InstanceCoordinate instanceCoordinate = new InstanceCoordinate(path);
                listener.onServiceRemoved(instanceCoordinate);
            }

            @Override
            public void dataChanged(final CloudnamePath path, final String data) {
                final InstanceCoordinate instanceCoordinate = new InstanceCoordinate(path);
                final ServiceData serviceData = ServiceData.fromJsonString(data);
                listener.onServiceDataChanged(instanceCoordinate, serviceData);
            }
        };
        synchronized (syncObject) {
            temporaryListeners.add(leaseListener);
        }
        backend.addLeaseCollectionListener(coordinate.toCloudnamePath(), leaseListener);
    }

    public  CloudnameService(final CloudnameBackend backend);

}