def filter(workitem=nil)

      filter = lookup_filter(workitem)

      return unless filter

      unless filter.is_a?(Array)
        #
        # filter is a participant

        def filter.receive(wi); end
          # making sure the participant never replies to the engine

        hwi = workitem || h.applied_workitem

        if filter.respond_to?(:filter)
          hwi['fields'] = filter.filter(hwi['fields'], workitem ? 'out' : 'in')
        else
          hwi['fields']['__filter_direction__'] = workitem ? 'out' : 'in'
          filter.consume(Ruote::Workitem.new(hwi))
        end

        hwi['fields'].delete('__filter_direction__')

        return
      end

      #
      # filter is a not a participnat

      unless workitem # in

        h.fields_pre_filter =
          Rufus::Json.dup(h.applied_workitem['fields'])
        h.applied_workitem['fields'] =
          Ruote.filter(filter, h.applied_workitem['fields'], {})

      else # out

        workitem['fields'] =
          Ruote.filter(
            filter,
            workitem['fields'],
            :double_tilde =>
              h.fields_pre_filter || h.applied_workitem['fields'])

        workitem['fields'].delete('params')
          # take and discard tend to copy it over, so let's remove it
      end
    end
def filter(workitem=nil)

      filter = lookup_filter(workitem)

      return unless filter

      unless filter.is_a?(Array)
        #
        # filter is a participant

        def filter.receive(wi); end
          # making sure the participant never replies to the engine

        hwi = workitem || h.applied_workitem

        if filter.respond_to?(:filter)
          hwi['fields'] = filter.filter(hwi['fields'], workitem ? 'out' : 'in')
        else
          hwi['fields']['__filter_direction__'] = workitem ? 'out' : 'in'
          filter.consume(Ruote::Workitem.new(hwi))
        end

        hwi['fields'].delete('__filter_direction__')

        return
      end

      #
      # filter is a not a participnat

      unless workitem # in

        h.fields_pre_filter =
          Rufus::Json.dup(h.applied_workitem['fields'])
        h.applied_workitem['fields'] =
          Ruote.filter(filter, h.applied_workitem['fields'], {})

      else # out

        workitem['fields'] =
          Ruote.filter(
            filter,
            workitem['fields'],
            :double_tilde =>
              h.fields_pre_filter || h.applied_workitem['fields'])

        workitem['fields'].delete('params')
          # take and discard tend to copy it over, so let's remove it
      end
    end
The :filter attribute work is done here, at apply (in) and at reply (out).