build (Needle::InterceptorChainBuilder)

    # File lib/needle/interceptor-chain.rb, line 103
        def build( point, service, interceptors )
          return service if interceptors.nil? || interceptors.empty?

          ordered_list =
            interceptors.sort { |a,b|
              a.options[:priority] <=> b.options[:priority] }

          chain = ProxyObjectChainElement.new( service )

          ordered_list.reverse.each do |interceptor|
            factory = interceptor.action.call( point.container )
            instance = factory.new( point, interceptor.options )
            element = InterceptorChainElement.new( instance )
            element.next = chain
            chain = element
          end

          # FIXME: should inherited methods of "Object" be interceptable?
          methods_to_intercept = ( service.class.instance_methods( true ) -
                                   Object.instance_methods +
                                   service.class.instance_methods( false ) ).uniq

          service = InterceptedServiceProxy.new( chain )
          singleton = class << service; self; end

          methods_to_intercept.each do |method|
            next if method =~ /^__/

            if singleton.instance_methods(false).include? method
              singleton.send( :remove_method, method )
            end

            singleton.class_eval "def \#{method}( *args, &block )\ncontext = InvocationContext.new( :\#{method}, args, block, Hash.new )\n@chain.process_next( context )\nend\n"
          end

          # allow the interceptor to intercept methods not explicitly
          # declared on the reciever.
          if singleton.instance_methods(false).include? "method_missing"
            singleton.send( :remove_method, :method_missing )
          end

          singleton.class_eval "def method_missing( sym, *args, &block )\ncontext = InvocationContext.new( sym, args, block, Hash.new )\n@chain.process_next( context )\nend\n"

          return service
        end