public void EntitiesChangeInterceptor(DSPResourceWithCollectionProperty resource, UpdateOperations operations)
 {
     if (InterceptorServiceDefinition.Current.EnableChangeInterceptors)
     {
         Assert.IsFalse(InterceptorServiceDefinition.Current.ChangeInterceptorCalledOnEntityId.HasValue, "Change interceptor called more than once.");
         if (operations == UpdateOperations.Add)
         {
             // The new resource has no properties set on it yet, so assume the "new" one - 42
             InterceptorServiceDefinition.Current.ChangeInterceptorCalledOnEntityId = 42;
         }
         else
         {
             InterceptorServiceDefinition.Current.ChangeInterceptorCalledOnEntityId = (int)resource.GetValue("ID");
         }
     }
 }
            public void Collection_ProcessingPipeline()
            {
                var metadata = CreateMetadataForXFeatureEntity();

                Func<int, DSPResource> CreateNewXFeatureEntityResource = (id) =>
                {
                    DSPResourceWithCollectionProperty newResource = new DSPResourceWithCollectionProperty(metadata.GetResourceType("XFeatureTestsEntity"));
                    newResource.SetRawValue("ID", id);
                    newResource.SetRawValue("Description", "Second");
                    newResource.SetRawValue("Strings", new List<string>() { "One", "Two" });
                    newResource.SetRawValue("Structs", new List<DSPResource>());
                    return newResource;
                };

                var actualCallCount = new ProcessingPipelineCallCount();

                DSPServiceDefinition service = new DSPServiceDefinition()
                {
                    Metadata = metadata,
                    CreateDataSource = (m) =>
                    {
                        DSPContext context = new DSPContext();
                        context.GetResourceSetEntities("Entities").Add(CreateNewXFeatureEntityResource(0));
                        return context;
                    },
                    Writable = true,
                };
                service.ProcessingPipeline.ProcessingRequest = (sender, args) => { actualCallCount.ProcessingRequestCallCount++; };
                service.ProcessingPipeline.ProcessedRequest = (sender, args) => { actualCallCount.ProcessedRequestCallCount++; };
                service.ProcessingPipeline.ProcessingChangeset = (sender, args) => { actualCallCount.ProcessingChangesetCallCount++; };
                service.ProcessingPipeline.ProcessedChangeset = (sender, args) => { actualCallCount.ProcessedChangesetCallCount++; };

                var testCases = new ProcessingPipelineTestCase[]
                {
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities"; r.Accept = format; },
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities(0)/Strings"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; },
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => { r.HttpMethod = "GET"; r.RequestUriString = "/Entities(0)/Structs"; r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format; },
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "POST";
                            r.RequestUriString = "/Entities";
                            r.Accept = format;
                            r.RequestContentType = format;
                            r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity(
                                CreateNewXFeatureEntityResource(1), 
                                DSPResourceSerializer.SerializerFormatFromMimeType(format)));
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "PUT";
                            r.RequestUriString = "/Entities(0)";
                            r.Accept = format;
                            r.RequestContentType = format;
                            r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity(
                                CreateNewXFeatureEntityResource(0), 
                                DSPResourceSerializer.SerializerFormatFromMimeType(format)));
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "PATCH";
                            r.RequestUriString = "/Entities(0)";
                            r.Accept = format;
                            r.RequestContentType = format;
                            r.SetRequestStreamAsText(DSPResourceSerializer.WriteEntity(
                                CreateNewXFeatureEntityResource(0), 
                                DSPResourceSerializer.SerializerFormatFromMimeType(format)));
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "DELETE";
                            r.RequestUriString = "/Entities(0)";
                            r.Accept = format;
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "PUT";
                            r.RequestUriString = "/Entities(0)/Strings";
                            r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format;
                            r.RequestContentType = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format;
                            r.SetRequestStreamAsText(DSPResourceSerializer.WriteProperty(
                                metadata.GetResourceType("XFeatureTestsEntity").Properties.First(p => p.Name == "Strings"),
                                new List<string> { "Foo", "Bar" },
                                DSPResourceSerializer.SerializerFormatFromMimeType(format)));
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                    new ProcessingPipelineTestCase() {
                        SetupRequest = (r, format) => {
                            r.HttpMethod = "PUT";
                            r.RequestUriString = "/Entities(0)/Structs";
                            r.Accept = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format;
                            r.RequestContentType = format == UnitTestsUtil.AtomFormat ? UnitTestsUtil.MimeApplicationXml : format;
                            r.SetRequestStreamAsText(DSPResourceSerializer.WriteProperty(
                                metadata.GetResourceType("XFeatureTestsEntity").Properties.First(p => p.Name == "Structs"),
                                new List<DSPResource>(),
                                DSPResourceSerializer.SerializerFormatFromMimeType(format)));
                        },
                        ExpectedCallCount = new ProcessingPipelineCallCount() {
                            ProcessingChangesetCallCount = 1,
                            ProcessedChangesetCallCount = 1
                        }
                    },
                };

                using (DSPResourceWithCollectionProperty.CollectionPropertiesResettable.Restore())
                using (TestWebRequest request = service.CreateForInProcess())
                {
                    DSPResourceWithCollectionProperty.CollectionPropertiesResettable.Value = true;

                    TestUtil.RunCombinations(testCases, UnitTestsUtil.BooleanValues, UnitTestsUtil.ResponseFormats, (testCase, batch, format) =>
                    {
                        service.ClearChanges();
                        actualCallCount.Clear();
                        var expectedCallCount = new ProcessingPipelineCallCount(testCase.ExpectedCallCount);
                        // Each request must fire at least one ProcessingRequest and ProcessedRequest
                        expectedCallCount.ProcessingRequestCallCount++;
                        expectedCallCount.ProcessedRequestCallCount++;

                        if (batch)
                        {
                            InMemoryWebRequest batchPart = new InMemoryWebRequest();
                            testCase.SetupRequest(batchPart, format);
                            BatchWebRequest batchRequest = new BatchWebRequest();
                            if (batchPart.HttpMethod == "GET")
                            {
                                batchRequest.Parts.Add(batchPart);
                            }
                            else
                            {
                                var changeset = new BatchWebRequest.Changeset();
                                changeset.Parts.Add(batchPart);
                                batchRequest.Changesets.Add(changeset);
                            }
                            batchRequest.SendRequest(request);
                        }
                        else
                        {
                            request.RequestContentType = null;
                            request.RequestStream = null;
                            testCase.SetupRequest(request, format);
                            request.SendRequest();
                        }

                        actualCallCount.AssertEquals(expectedCallCount);
                    });
                }
            }