def expose(operation=None, action='GET', is_long=False):
    """ A decorator for exposing methods as BLL operations/actions

    Keyword arguments:

    * operation
        the name of the operation that the caller should supply in
        the BLL request.  If this optional argument is not supplied,
        then the operation name will be the name of the method being
        decorated.

    * action
        the name of the action (typically ``GET``, ``PUT``, ``DELETE`` or
        ``POST``) that will be matched against the BLL request.  If this
        optional argument is not supplied, then the dispatching
        mechanism will ignore the action.

    * is_long
        indicates that the method being decorated is a long-running
        function.  Long-running methods may either be called once
        (via complete) or twice (via handle for validation and via
        for the rest) depending on their signature -- if the
        method has an argument (other than self), then it will be
        called twice, in which case the parameter will be populated
        with a boolean indicating whether it is being called via
        handle; in this case, the function should return a recommended
        polling interval.

    Note, if you override handle or complete, this decorations will be ignored!

    When a normal (short-running) method is called, its return value should
    just be the data portion of the response. The handle method will take
    care of building a full BllResponse structure and placing this return
    value in the data portion.   Otherwise, if there are any problems, the
    method should just throw an appropriate exception.  The handle method
    will catch the exception and package it up in an appropriate BllResponse
    object.

    The decorator can be applied multiple times to the same function, in
    order to permit a function to be called via multiple operations.  For
    example::

        class MySvc(SvcBase)
            @expose('add_stuff')
            @expose('update_stuff')
            def add_or_update(self):
                ...

    """

    def decorate(f):
        f.exposed = True
        if not hasattr(f, 'operation'):
            f.operation = []

        f.operation.append(operation or f.__name__)

        if action:
            f.action = action

        if is_long:
            f.is_long = is_long

        # normally a decorator returns a wrapped function, but here
        # we return f unmodified, after registering it
        return f

    return decorate