public void Complex()
        {
            Expression <Func <ControllerSample, ModelSample, ModelSample> > lambda = (test, model)
                                                                                     => test.ControllerMethod(model.Id, model.Name, QueryParameter.Is <string>(), QueryParameter.Is <int>());
            var methodCallExpression = (MethodCallExpression)lambda.Body;


            var httpControllerDescriptor = _fixture.CreateAnonymous <HttpControllerDescriptor>();

            var apiExplorerMoq = new Mock <IApiExplorer>();

            apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection <ApiDescription>()
            {
                new ApiDescription()
                {
                    ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, methodCallExpression.Method),
                    HttpMethod       = HttpMethod.Get,
                    RelativePath     = "/api"
                }
            });

            var mappingRule = new MappingRule(methodCallExpression, apiExplorerMoq.Object);

            _actionConfiguration.AddMappingRule(mappingRule);

            _actionConfiguration.Configure();
            var originalType = typeof(ModelSample);
            var strategy     = _defaultStrategyFactory.Build(_actionConfiguration, originalType);

            Assume.That(strategy.ClassKey(originalType), Is.StringContaining("_NHateoas.Tests.ModelSample_SP_SR"));

            var typeBuilder = new TypeBuilder(originalType, strategy);
            var type        = typeBuilder.BuildType();

            Assume.That(type.Name, Is.EqualTo(originalType.Name));
            Assume.That(type.FullName, Is.StringContaining("_NHateoas.Tests.ModelSample_SP_SR"));

            var props = type.GetProperties();

            Assume.That(props, Is.Not.Empty);

            var propNames = props.ToList().ConvertAll(p => p.Name);

            Assume.That(propNames, Is.EquivalentTo(new[] { "Id", "Name", "Price", "EMailAddress", "get_modelsample_by_id_name_query_skip" }));
            var propTypes = props.ToList().ConvertAll(p => p.PropertyType.Name);

            Assume.That(propTypes, Is.EquivalentTo(new[] { "Int32", "String", "Double", "String", "String" }));


            var instance = Activator.CreateInstance(type);
            var original = _fixture.CreateAnonymous <ModelSample>();

            strategy.ActivateInstance(instance, original, _actionConfiguration);

            var propValues = props.ToList().ConvertAll(p => p.GetValue(instance).ToString());

            Assume.That(propValues, Is.EquivalentTo(new[] { original.Id.ToString(), original.Name, original.Price.ToString(), original.EMailAddress, "/api" }));
        }
        public void Complex()
        {
            Expression <Func <ControllerSample, ModelSample, ModelSample> > lambda = (test, model)
                                                                                     => test.ControllerMethod(model.Id, model.Name, QueryParameter.Is <string>(), QueryParameter.Is <int>());
            var methodCallExpression = (MethodCallExpression)lambda.Body;


            var httpControllerDescriptor = _fixture.CreateAnonymous <HttpControllerDescriptor>();

            Expression <Func <ControllerSample, int> > lambda2 = (test) => test.FakeMethodWithAttribute();

            var apiExplorerMoq = new Mock <IApiExplorer>();

            apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection <ApiDescription>()
            {
                new ApiDescription()
                {
                    ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, methodCallExpression.Method),
                    HttpMethod       = HttpMethod.Get,
                    RelativePath     = "/api"
                },
                new ApiDescription()
                {
                    ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, ((MethodCallExpression)lambda2.Body).Method),
                    HttpMethod       = HttpMethod.Post,
                    RelativePath     = "/api/test"
                }
            });

            _actionConfiguration.AddMappingRule(new MappingRule(methodCallExpression, apiExplorerMoq.Object));


            var rule = new MappingRule((MethodCallExpression)lambda2.Body, apiExplorerMoq.Object)
            {
                Type = MappingRule.RuleType.ActionRule
            };

            rule.Names.Add("action-name");
            _actionConfiguration.AddMappingRule(rule);

            _actionConfiguration.UseSirenSpecification();
            _actionConfiguration.Configure();
            var originalType = typeof(ModelSample);
            var strategy     = _defaultStrategyFactory.Build(_actionConfiguration, originalType);

            Assume.That(strategy.ClassKey(originalType), Is.StringContaining("_NHateoas.Tests.ModelSample_PP"));

            var typeBuilder = new TypeBuilder(originalType, strategy);
            var type        = typeBuilder.BuildType();

            Assume.That(type.Name, Is.EqualTo(originalType.Name));
            Assume.That(type.FullName, Is.StringContaining("_NHateoas.Tests.ModelSample_PP"));

            var props = type.GetProperties();

            Assume.That(props, Is.Not.Empty);

            var propNames = new List <string>();

            props.ToList().ForEach(p =>
                                   { propNames.Add(p.Name);

                                     if (p.PropertyType == typeof(string))
                                     {
                                         return;
                                     }

                                     if (p.PropertyType.IsArray && p.PropertyType.GetElementType() == typeof(string))
                                     {
                                         return;
                                     }

                                     var pt = (p.PropertyType.BaseType != null && p.PropertyType.BaseType.IsGenericType) ?
                                              p.PropertyType.BaseType.GetGenericArguments()[0] : p.PropertyType;
                                     pt.GetProperties().ToList().ForEach(sp => propNames.Add(sp.Name)); });

            Assume.That(propNames, Is.EquivalentTo(new[] { "properties", "Id", "Name", "Price", "EMailAddress", "class", "href", "rel", "links", "RelList", "Href", "actions", "ActionName", "Class", "Title", "Method", "Href", "ContentType", "ActionFields" }));
            var propTypes = props.Where(p => !p.PropertyType.IsArray && p.PropertyType != typeof(string)).ToList().ConvertAll(p => p.PropertyType.Name);

            Assume.That(propTypes, Is.EquivalentTo(new[] { "ModelSample", "Links", "Actions" }));


            var instance = Activator.CreateInstance(type);
            var original = new ModelSample()
            {
                Id           = 1,
                Name         = "test",
                Price        = 3.0,
                EMailAddress = "aa.bb@ccc"
            };

            strategy.ActivateInstance(instance, original, _actionConfiguration);

            var result = JsonConvert.SerializeObject(instance);

            Assume.That(result, Is.EqualTo("{\"properties\":{\"Id\":1,\"Name\":\"test\",\"Price\":3.0,\"EMailAddress\":\"aa.bb@ccc\"},\"links\":[{\"rel\":[\"get_modelsample_by_id_name_query_skip\"],\"href\":\"http://localhost/api\"}],\"actions\":[{\"name\":\"rel-name\",\"method\":\"POST\",\"href\":\"http://localhost/api/test\",\"type\":\"application/x-www-form-urlencoded\"}]}"));
        }