def METHOD_NAME (sync_function) :
    def wrap_function (self, *args, **kwargs) :
        if 'ttype' in kwargs and kwargs['ttype']:
            if not kwargs['ttype'] in (T_SYNC, T_ASYNC, T_TASK) :
                # cannot handle that ttype value, do not call async methods
                ttype = kwargs['ttype']
                msg   = " %s: async %s() called with invalid tasktype (%s)" \
                      % (self.__class__.__name__, sync_function.__name__,
                         str(ttype))
                raise rse.BadParameter (msg)
            # call async method flavor
            try :
                async_function_name = "%s_async"  %  sync_function.__name__
                async_function      = getattr (self, async_function_name)
            except AttributeError as e:
                msg = " %s: async %s() not implemented" \
                    % (self.__class__.__name__, sync_function.__name__)
                raise rse.NotImplemented (msg) from e
            else :
                # 'self' not needed, getattr() returns member function
                return async_function (*args, **kwargs)
        # no ttype, or ttype==None -- make sure it's gone, and call default sync
        # function
        if 'ttype' in kwargs :
            del kwargs['ttype']
        # only some functions will provide metrics, and thus need the _from_task
        # parameter -- strip that as well if its not needed
        if '_from_task' in kwargs:
            if '_from_task' not in inspect.getargspec (sync_function).args:
                del(kwargs['_from_task'])
        return sync_function (self, *args, **kwargs)
    return wrap_function