Example #1
0
 //--- Constructors ---
 /// <summary>
 /// Creates a new stage instance.
 /// </summary>
 /// <param name="name">Stage name.</param>
 /// <param name="handler">Stage handler.</param>
 /// <param name="access">Stage access level.</param>
 public DreamFeatureStage(string name, CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>> handler, DreamAccess access)
 {
     if(handler == null) {
         throw new ArgumentNullException("handler");
     }
     this.Name = name ?? UNNAMED;
     this.Access = access;
     _handler = handler;
 }
Example #2
0
        //--- Constructors ---

        /// <summary>
        /// Creates a new stage instance.
        /// </summary>
        /// <param name="name">Stage name.</param>
        /// <param name="handler">Stage handler.</param>
        /// <param name="access">Stage access level.</param>
        public DreamFeatureStage(string name, CoroutineHandler <DreamContext, DreamMessage, Result <DreamMessage> > handler, DreamAccess access)
        {
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            this.Name   = name ?? UNNAMED;
            this.Access = access;
            _handler    = handler;
        }
 //--- Constructors ---
 public DekiScriptInvocationTargetDescriptor(DreamAccess access, bool isProperty, bool isIdempotent, string name, DekiScriptParameter[] parameters, DekiScriptType returnType, string description, string transform, IDekiScriptInvocationTarget target) {
     this.Access = access;
     this.IsProperty = isProperty;
     this.IsIdempotent = isIdempotent;
     this.Name = name;
     this.Parameters = parameters;
     this.ReturnType = returnType;
     this.Description = description;
     this.Transform = transform;
     this.Target = target;
 }
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr, DekiScriptEnv env) {
     if(parameters == null) {
         throw new ArgumentNullException("parameters");
     }
     if(expr == null) {
         throw new ArgumentNullException("expr");
     }
     this.Access = access;
     this.Parameters = parameters;
     this.Expression = expr;
     _env = env;
 }
 //--- Constructors ---
 public DekiScriptInvocationTargetDescriptor(DreamAccess access, bool isProperty, bool isIdempotent, string name, DekiScriptParameter[] parameters, DekiScriptType returnType, string description, string transform, IDekiScriptInvocationTarget target)
 {
     this.Access       = access;
     this.IsProperty   = isProperty;
     this.IsIdempotent = isIdempotent;
     this.Name         = name;
     this.Parameters   = parameters;
     this.ReturnType   = returnType;
     this.Description  = description;
     this.Transform    = transform;
     this.Target       = target;
 }
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr, DekiScriptEnv env)
 {
     if (parameters == null)
     {
         throw new ArgumentNullException("parameters");
     }
     if (expr == null)
     {
         throw new ArgumentNullException("expr");
     }
     this.Access     = access;
     this.Parameters = parameters;
     this.Expression = expr;
     _env            = env;
 }
Example #7
0
        /// <summary>
        /// Creates a new stage instance.
        /// </summary>
        /// <param name="service">Service instance to which the stage belongs to.</param>
        /// <param name="method">Method definintion for stage handler.</param>
        /// <param name="access">Stage access level.</param>
        public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }
            this.Name   = service.GetType().FullName + "!" + method.Name;
            this.Access = access;
            _method     = method;
            _service    = service;

            // determine what kind of method we were given
            var parameters = method.GetParameters();

            if ((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result <DreamMessage>)))
            {
                // classical coroutine feature handler
                _handler = (CoroutineHandler <DreamContext, DreamMessage, Result <DreamMessage> >)Delegate.CreateDelegate(typeof(CoroutineHandler <DreamContext, DreamMessage, Result <DreamMessage> >), service, method);
            }
            else
            {
                // validate method return type
                if (method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc))
                {
                    throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType));
                }

                // create an execution plan for fetching the necessary parameters to invoke the method
                _plan = new List <DreamFeatureAdapter>();
                foreach (var param in parameters)
                {
                    // check name-based parameters
                    if (param.Name.EqualsInvariant("verb"))
                    {
                        Assert(method, param, typeof(string));
                        _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb));
                    }
                    else if (param.Name.EqualsInvariant("path"))
                    {
                        Assert(method, param, typeof(string[]), typeof(string));
                        if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath));
                        }
                        else
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments));
                        }
                    }
                    else if (param.Name.EqualsInvariant("uri"))
                    {
                        Assert(method, param, typeof(XUri));
                        _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri));
                    }
                    else if (param.Name.EqualsInvariant("body"))
                    {
                        Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[]));

                        // check which body type is requested
                        if (param.ParameterType == typeof(XDoc))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument));
                        }
                        else if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText));
                        }
                        else if (param.ParameterType == typeof(Stream))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream));
                        }
                        else if (param.ParameterType == typeof(byte[]))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes));
                        }
                        else
                        {
                            throw new ShouldNeverHappenException();
                        }
                    }
                    else
                    {
                        // check type-based parameters
                        if (param.ParameterType == typeof(DreamContext))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContext));
                        }
                        else if (param.ParameterType == typeof(DreamMessage))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest));
                        }
                        else if (param.ParameterType == typeof(Result <DreamMessage>))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse));
                        }
                        else if (param.ParameterType == typeof(Result <XDoc>))
                        {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse));
                        }
                        else if (param.ParameterType == typeof(DreamCookie))
                        {
                            _plan.Add(MakeRequestCookieGetter(param.Name));
                        }
                        else if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(MakeContextParamGetter(param.Name));
                        }
                        else if (param.ParameterType == typeof(string[]))
                        {
                            _plan.Add(MakeContextParamListGetter(param.Name));
                        }
                        else
                        {
                            _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType));
                        }
                    }
                }
            }
        }
Example #8
0
        /// <summary>
        /// Creates a new stage instance.
        /// </summary>
        /// <param name="service">Service instance to which the stage belongs to.</param>
        /// <param name="method">Method definintion for stage handler.</param>
        /// <param name="access">Stage access level.</param>
        public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access)
        {
            if(service == null) {
                throw new ArgumentNullException("service");
            }
            if(method == null) {
                throw new ArgumentNullException("method");
            }
            this.Name = service.GetType().FullName + "!" + method.Name;
            this.Access = access;
            _method = method;
            _service = service;

            // determine what kind of method we were given
            var parameters = method.GetParameters();
            if((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result<DreamMessage>))) {

                // classical coroutine feature handler
                _handler = (CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>)Delegate.CreateDelegate(typeof(CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>), service, method);
            } else {

                // TODO (arnec): Eventually DreamMessage should have a DreamMessage<T> with custom serializers allowing arbitrary return types

                // validate method return type
                if(method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc)) {
                    throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType));
                }

                // create an execution plan for fetching the necessary parameters to invoke the method
                _plan = new List<DreamFeatureAdapter>();
                foreach(var param in method.GetParameters()) {
                    var attributes = param.GetCustomAttributes(false);
                    QueryAttribute queryParam = (QueryAttribute)attributes.FirstOrDefault(i => i is QueryAttribute);
                    PathAttribute pathParam = (PathAttribute)attributes.FirstOrDefault(i => i is PathAttribute);
                    HeaderAttribute header = (HeaderAttribute)attributes.FirstOrDefault(i => i is HeaderAttribute);
                    CookieAttribute cookie = (CookieAttribute)attributes.FirstOrDefault(i => i is CookieAttribute);

                    // check attribute-based parameters
                    if(queryParam != null) {

                        // check if a single or a list of query parameters are requested
                        if(param.ParameterType == typeof(string)) {
                            _plan.Add(MakeContextParamGetter(queryParam.Name ?? param.Name));
                        } else if(param.ParameterType == typeof(string[])) {
                            _plan.Add(MakeContextParamListGetter(queryParam.Name ?? param.Name));
                        } else {
                            _plan.Add(MakeConvertingContextParamGetter(queryParam.Name ?? param.Name, param.ParameterType));
                        }
                    } else if(pathParam != null) {
                        if(param.ParameterType == typeof(string)) {
                            _plan.Add(MakeContextParamGetter(pathParam.Name ?? param.Name));
                        } else {
                            _plan.Add(MakeConvertingContextParamGetter(pathParam.Name ?? param.Name, param.ParameterType));
                        }
                    } else if(cookie != null) {
                        Assert(method, param, typeof(string), typeof(DreamCookie));

                        // check which cookie type is requested
                        if(param.ParameterType == typeof(string)) {
                            _plan.Add(MakeRequestCookieValueGetter(cookie.Name ?? param.Name));
                        } else if(param.ParameterType == typeof(DreamCookie)) {
                            _plan.Add(MakeRequestCookieGetter(cookie.Name ?? param.Name));
                        } else {
                            throw new ShouldNeverHappenException();
                        }
                    } else if(header != null) {
                        Assert(method, param, typeof(string));
                        _plan.Add(MakeRequestHeaderGetter(header.Name ?? param.Name));
                    } else {

                        // check name-based parameters
                        if(param.Name.EqualsInvariant("verb")) {
                            Assert(method, param, typeof(string));
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb));
                        } else if(param.Name.EqualsInvariant("path")) {

                            Assert(method, param, typeof(string[]), typeof(string));
                            if(param.ParameterType == typeof(string)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath));
                            } else {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments));
                            }
                        } else if(param.Name.EqualsInvariant("uri")) {
                            Assert(method, param, typeof(XUri));
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri));
                        } else if(param.Name.EqualsInvariant("body")) {
                            Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[]));

                            // check which body type is requested
                            if(param.ParameterType == typeof(XDoc)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument));
                            } else if(param.ParameterType == typeof(string)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText));
                            } else if(param.ParameterType == typeof(Stream)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream));
                            } else if(param.ParameterType == typeof(byte[])) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes));
                            } else {
                                throw new ShouldNeverHappenException();
                            }
                        } else {

                            // check type-based parameters
                            if(param.ParameterType == typeof(DreamContext)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContext));
                            } else if(param.ParameterType == typeof(DreamMessage)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest));
                            } else if(param.ParameterType == typeof(Result<DreamMessage>)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse));
                            } else if(param.ParameterType == typeof(Result<XDoc>)) {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse));
                            } else if(param.ParameterType == typeof(DreamCookie)) {
                                _plan.Add(MakeRequestCookieGetter(param.Name));
                            } else if(param.ParameterType == typeof(string)) {
                                _plan.Add(MakeContextParamGetter(param.Name));
                            } else if(param.ParameterType == typeof(string[])) {
                                _plan.Add(MakeContextParamListGetter(param.Name));
                            } else {
                                _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType));
                            }
                        }
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Creates a new stage instance.
        /// </summary>
        /// <param name="service">Service instance to which the stage belongs to.</param>
        /// <param name="method">Method definintion for stage handler.</param>
        /// <param name="access">Stage access level.</param>
        public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access)
        {
            if(service == null) {
                throw new ArgumentNullException("service");
            }
            if(method == null) {
                throw new ArgumentNullException("method");
            }
            this.Name = service.GetType().FullName + "!" + method.Name;
            this.Access = access;
            _method = method;
            _service = service;

            // determine what kind of method we were given
            var parameters = method.GetParameters();
            if((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result<DreamMessage>))) {

                // classical coroutine feature handler
                _handler = (CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>)Delegate.CreateDelegate(typeof(CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>), service, method);
            } else {

                // validate method return type
                if(method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc)) {
                    throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType));
                }

                // create an execution plan for fetching the necessary parameters to invoke the method
                _plan = new List<DreamFeatureAdapter>();
                foreach(var param in parameters) {

                    // check name-based parameters
                    if(param.Name.EqualsInvariant("verb")) {
                        Assert(method, param, typeof(string));
                        _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb));
                    } else if(param.Name.EqualsInvariant("path")) {
                        Assert(method, param, typeof(string[]), typeof(string));
                        if(param.ParameterType == typeof(string)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath));
                        } else {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments));
                        }
                    } else if(param.Name.EqualsInvariant("uri")) {
                        Assert(method, param, typeof(XUri));
                        _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri));
                    } else if(param.Name.EqualsInvariant("body")) {
                        Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[]));

                        // check which body type is requested
                        if(param.ParameterType == typeof(XDoc)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument));
                        } else if(param.ParameterType == typeof(string)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText));
                        } else if(param.ParameterType == typeof(Stream)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream));
                        } else if(param.ParameterType == typeof(byte[])) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes));
                        } else {
                            throw new ShouldNeverHappenException();
                        }
                    } else {

                        // check type-based parameters
                        if(param.ParameterType == typeof(DreamContext)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContext));
                        } else if(param.ParameterType == typeof(DreamMessage)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest));
                        } else if(param.ParameterType == typeof(Result<DreamMessage>)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse));
                        } else if(param.ParameterType == typeof(Result<XDoc>)) {
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse));
                        } else if(param.ParameterType == typeof(DreamCookie)) {
                            _plan.Add(MakeRequestCookieGetter(param.Name));
                        } else if(param.ParameterType == typeof(string)) {
                            _plan.Add(MakeContextParamGetter(param.Name));
                        } else if(param.ParameterType == typeof(string[])) {
                            _plan.Add(MakeContextParamListGetter(param.Name));
                        } else {
                            _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType));
                        }
                    }
                }
            }
        }
 //--- Constructors ---
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr) : this(access, parameters, expr, null) { }
 //--- Constructors ---
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr) : this(access, parameters, expr, null)
 {
 }
        /// <summary>
        /// Creates a new stage instance.
        /// </summary>
        /// <param name="service">Service instance to which the stage belongs to.</param>
        /// <param name="method">Method definintion for stage handler.</param>
        /// <param name="access">Stage access level.</param>
        public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }
            this.Name   = service.GetType().FullName + "!" + method.Name;
            this.Access = access;
            _method     = method;
            _service    = service;

            // determine what kind of method we were given
            var parameters = method.GetParameters();

            if ((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result <DreamMessage>)))
            {
                // classical coroutine feature handler
                _handler = (CoroutineHandler <DreamContext, DreamMessage, Result <DreamMessage> >)Delegate.CreateDelegate(typeof(CoroutineHandler <DreamContext, DreamMessage, Result <DreamMessage> >), service, method);
            }
            else
            {
                // TODO (arnec): Eventually DreamMessage should have a DreamMessage<T> with custom serializers allowing arbitrary return types

                // validate method return type
                if (method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc))
                {
                    throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType));
                }

                // create an execution plan for fetching the necessary parameters to invoke the method
                _plan = new List <DreamFeatureAdapter>();
                foreach (var param in method.GetParameters())
                {
                    var             attributes = param.GetCustomAttributes(false);
                    QueryAttribute  queryParam = (QueryAttribute)attributes.FirstOrDefault(i => i is QueryAttribute);
                    PathAttribute   pathParam  = (PathAttribute)attributes.FirstOrDefault(i => i is PathAttribute);
                    HeaderAttribute header     = (HeaderAttribute)attributes.FirstOrDefault(i => i is HeaderAttribute);
                    CookieAttribute cookie     = (CookieAttribute)attributes.FirstOrDefault(i => i is CookieAttribute);

                    // check attribute-based parameters
                    if (queryParam != null)
                    {
                        // check if a single or a list of query parameters are requested
                        if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(MakeContextParamGetter(queryParam.Name ?? param.Name));
                        }
                        else if (param.ParameterType == typeof(string[]))
                        {
                            _plan.Add(MakeContextParamListGetter(queryParam.Name ?? param.Name));
                        }
                        else
                        {
                            _plan.Add(MakeConvertingContextParamGetter(queryParam.Name ?? param.Name, param.ParameterType));
                        }
                    }
                    else if (pathParam != null)
                    {
                        if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(MakeContextParamGetter(pathParam.Name ?? param.Name));
                        }
                        else
                        {
                            _plan.Add(MakeConvertingContextParamGetter(pathParam.Name ?? param.Name, param.ParameterType));
                        }
                    }
                    else if (cookie != null)
                    {
                        Assert(method, param, typeof(string), typeof(DreamCookie));

                        // check which cookie type is requested
                        if (param.ParameterType == typeof(string))
                        {
                            _plan.Add(MakeRequestCookieValueGetter(cookie.Name ?? param.Name));
                        }
                        else if (param.ParameterType == typeof(DreamCookie))
                        {
                            _plan.Add(MakeRequestCookieGetter(cookie.Name ?? param.Name));
                        }
                        else
                        {
                            throw new ShouldNeverHappenException();
                        }
                    }
                    else if (header != null)
                    {
                        Assert(method, param, typeof(string));
                        _plan.Add(MakeRequestHeaderGetter(header.Name ?? param.Name));
                    }
                    else
                    {
                        // check name-based parameters
                        if (param.Name.EqualsInvariant("verb"))
                        {
                            Assert(method, param, typeof(string));
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb));
                        }
                        else if (param.Name.EqualsInvariant("path"))
                        {
                            Assert(method, param, typeof(string[]), typeof(string));
                            if (param.ParameterType == typeof(string))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath));
                            }
                            else
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments));
                            }
                        }
                        else if (param.Name.EqualsInvariant("uri"))
                        {
                            Assert(method, param, typeof(XUri));
                            _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri));
                        }
                        else if (param.Name.EqualsInvariant("body"))
                        {
                            Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[]));

                            // check which body type is requested
                            if (param.ParameterType == typeof(XDoc))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument));
                            }
                            else if (param.ParameterType == typeof(string))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText));
                            }
                            else if (param.ParameterType == typeof(Stream))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream));
                            }
                            else if (param.ParameterType == typeof(byte[]))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes));
                            }
                            else
                            {
                                throw new ShouldNeverHappenException();
                            }
                        }
                        else
                        {
                            // check type-based parameters
                            if (param.ParameterType == typeof(DreamContext))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetContext));
                            }
                            else if (param.ParameterType == typeof(DreamMessage))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest));
                            }
                            else if (param.ParameterType == typeof(Result <DreamMessage>))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse));
                            }
                            else if (param.ParameterType == typeof(Result <XDoc>))
                            {
                                _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse));
                            }
                            else if (param.ParameterType == typeof(DreamCookie))
                            {
                                _plan.Add(MakeRequestCookieGetter(param.Name));
                            }
                            else if (param.ParameterType == typeof(string))
                            {
                                _plan.Add(MakeContextParamGetter(param.Name));
                            }
                            else if (param.ParameterType == typeof(string[]))
                            {
                                _plan.Add(MakeContextParamListGetter(param.Name));
                            }
                            else
                            {
                                _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType));
                            }
                        }
                    }
                }
            }
        }