Пример #1
0
        /// <summary>
        /// Read the normal resource.
        /// </summary>
        /// <param name="reader">The OData reader.</param>
        /// <param name="itemsStack">The item stack.</param>
        /// <param name="topLevelItem">the top level item.</param>
        private static void ReadResource(ODataReader reader, Stack <ODataItemWrapper> itemsStack, ref ODataItemWrapper topLevelItem)
        {
            Contract.Assert(reader != null);
            Contract.Assert(itemsStack != null);
            Contract.Assert(ODataReaderState.ResourceStart == reader.State);

            ODataResource        resource        = (ODataResource)reader.Item;
            ODataResourceWrapper resourceWrapper = null;

            if (resource != null)
            {
                resourceWrapper = new ODataResourceWrapper(resource);
            }

            if (itemsStack.Count == 0)
            {
                Contract.Assert(resource != null, "The top-level resource can never be null.");
                topLevelItem = resourceWrapper;
            }
            else
            {
                ODataItemWrapper             parentItem              = itemsStack.Peek();
                ODataResourceSetWrapper      parentResourceSet       = parentItem as ODataResourceSetWrapper;
                ODataDeltaResourceSetWrapper parentDeletaResourceSet = parentItem as ODataDeltaResourceSetWrapper;
                if (parentResourceSet != null)
                {
                    parentResourceSet.Resources.Add(resourceWrapper);
                }
                else if (parentDeletaResourceSet != null)
                {
                    // Delta resource set could have the normal resource
                    parentDeletaResourceSet.DeltaItems.Add(resourceWrapper);
                }
                else
                {
                    ODataNestedResourceInfoWrapper parentNestedResource = (ODataNestedResourceInfoWrapper)parentItem;
                    Contract.Assert(parentNestedResource.NestedResourceInfo.IsCollection == false, "Only singleton nested properties can contain resource as their child.");
                    Contract.Assert(parentNestedResource.NestedItems.Count == 0, "Each nested property can contain only one resource as its direct child.");
                    parentNestedResource.NestedItems.Add(resourceWrapper);
                }
            }

            itemsStack.Push(resourceWrapper);
        }
Пример #2
0
        /// <summary>
        /// Reads a <see cref="ODataResource"/> or <see cref="ODataResourceSet"/> object.
        /// </summary>
        /// <param name="reader">The OData reader to read from.</param>
        /// <returns>The read resource or resource set.</returns>
        public static async Task <ODataItemWrapper> ReadResourceOrResourceSetAsync(this ODataReader reader)
        {
            if (reader == null)
            {
                throw Error.ArgumentNull(nameof(reader));
            }

            ODataItemWrapper         topLevelItem = null;
            Stack <ODataItemWrapper> itemsStack   = new Stack <ODataItemWrapper>();

            while (await reader.ReadAsync().ConfigureAwait(false))
            {
                ReadODataItem(reader, itemsStack, ref topLevelItem);
            }

            Contract.Assert(reader.State == ODataReaderState.Completed, "We should have consumed all of the input by now.");
            Contract.Assert(topLevelItem != null, "A top level resource or resource set should have been read by now.");
            return(topLevelItem);
        }
        public async Task ReadSingleEntityReferenceLinkWorksAsExpected(ODataVersion version, string referenceLink)
        {
            // Arrange
            string payload = "{" + // -> ResourceStart
                             "\"@odata.context\":\"http://localhost/$metadata#Customers/$entity\"," +
                             "\"CustomerID\": 7," +
                             referenceLink +
                             "}";

            IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(customers); // Guard

            // Act
            Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataResourceReaderAsync(customers, customers.EntityType());
            ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, version);

            // Assert
            Assert.NotNull(item);
            ODataResourceWrapper           resource           = Assert.IsType <ODataResourceWrapper>(item);
            ODataNestedResourceInfoWrapper nestedResourceInfo = Assert.Single(resource.NestedResourceInfos);

            Assert.Equal("Order", nestedResourceInfo.NestedResourceInfo.Name);
            if (version == ODataVersion.V401)
            {
                // --- Resource
                //     |--- NestedResourceInfo (Order)
                //          |--- Resource
                ODataResourceWrapper order = Assert.IsType <ODataResourceWrapper>(nestedResourceInfo.NestedResource);
                Assert.Equal("http://svc/Orders(8)", order.Resource.Id.OriginalString);
                Assert.Empty(order.Resource.Properties);
            }
            else
            {
                // --- Resource
                //     |--- NestedResourceInfo (Order)
                //          |--- EntityReferenceLink
                ODataEntityReferenceLinkWrapper orderLink = Assert.IsType <ODataEntityReferenceLinkWrapper>(Assert.Single(nestedResourceInfo.NestedLinks));
                Assert.Equal("http://svc/Orders(7)", orderLink.EntityReferenceLink.Url.OriginalString);
            }
        }
Пример #4
0
        /// <summary>
        /// Read OData item.
        /// </summary>
        /// <param name="reader">The odata reader.</param>
        /// <param name="itemsStack">The item stack.</param>
        /// <param name="topLevelItem">The top level item.</param>
        private static void ReadODataItem(ODataReader reader, Stack <ODataItemWrapper> itemsStack, ref ODataItemWrapper topLevelItem)
        {
            Contract.Assert(reader != null);
            Contract.Assert(itemsStack != null);

            switch (reader.State)
            {
            case ODataReaderState.ResourceStart:
                ReadResource(reader, itemsStack, ref topLevelItem);
                break;

            case ODataReaderState.DeletedResourceStart:
                ReadDeletedResource(reader, itemsStack);
                break;

            case ODataReaderState.ResourceEnd:
                Contract.Assert(itemsStack.Count > 0, "The resource which is ending should be on the top of the items stack.");
                ODataResourceWrapper resourceWrapper = itemsStack.Peek() as ODataResourceWrapper;
                if (resourceWrapper != null)
                {
                    // Resource could be null
                    Contract.Assert(resourceWrapper.Resource == reader.Item, "The resource should be the same item in the reader.");
                }

                itemsStack.Pop();
                break;

            case ODataReaderState.DeletedResourceEnd:
                Contract.Assert(itemsStack.Count > 0, "The deleted resource which is ending should be on the top of the items stack.");
                ODataResourceWrapper deletedResourceWrapper = itemsStack.Peek() as ODataResourceWrapper;
                Contract.Assert(deletedResourceWrapper != null, "The top object in the stack should be delete resource wrapper.");
                Contract.Assert(deletedResourceWrapper.Resource == reader.Item, "The deleted resource should be the same item in the reader.");
                itemsStack.Pop();
                break;

            case ODataReaderState.NestedResourceInfoStart:
                ODataNestedResourceInfo nestedResourceInfo = (ODataNestedResourceInfo)reader.Item;
                Contract.Assert(nestedResourceInfo != null, "nested resource info should never be null.");

                ODataNestedResourceInfoWrapper nestedResourceInfoWrapper = new ODataNestedResourceInfoWrapper(nestedResourceInfo);
                Contract.Assert(itemsStack.Count > 0, "nested resource info can't appear as top-level item.");
                {
                    ODataResourceWrapper parentResource = (ODataResourceWrapper)itemsStack.Peek();
                    parentResource.NestedResourceInfos.Add(nestedResourceInfoWrapper);
                }

                itemsStack.Push(nestedResourceInfoWrapper);
                break;

            case ODataReaderState.NestedResourceInfoEnd:
                Contract.Assert(itemsStack.Count > 0, "The nested resource info which is ending should be on the top of the items stack.");
                ODataNestedResourceInfoWrapper nestedInfoWrapper = itemsStack.Peek() as ODataNestedResourceInfoWrapper;
                Contract.Assert(nestedInfoWrapper != null, "The top object in the stack should be nested resource info wrapper.");
                Contract.Assert(nestedInfoWrapper.NestedResourceInfo == reader.Item, "The nested resource info should be the same item in the reader.");
                itemsStack.Pop();
                break;

            case ODataReaderState.ResourceSetStart:     // resource set
                ReadResourceSet(reader, itemsStack, ref topLevelItem);
                break;

            case ODataReaderState.DeltaResourceSetStart:     // delta resource set
                ReadDeltaResourceSet(reader, itemsStack, ref topLevelItem);
                break;

            case ODataReaderState.ResourceSetEnd:
                Contract.Assert(itemsStack.Count > 0, "The resource set which is ending should be on the top of the items stack.");
                ODataResourceSetWrapper resourceSetWrapper = itemsStack.Peek() as ODataResourceSetWrapper;
                Contract.Assert(resourceSetWrapper != null, "The top object in the stack should be resource set wrapper.");
                Contract.Assert(resourceSetWrapper.ResourceSet == reader.Item, "The resource set should be the same item in the reader.");
                itemsStack.Pop();
                break;

            case ODataReaderState.DeltaResourceSetEnd:
                Contract.Assert(itemsStack.Count > 0, "The delta resource set which is ending should be on the top of the items stack.");
                ODataDeltaResourceSetWrapper deltaResourceSetWrapper = itemsStack.Peek() as ODataDeltaResourceSetWrapper;
                Contract.Assert(deltaResourceSetWrapper != null, "The top object in the stack should be delta resource set wrapper.");
                Contract.Assert(deltaResourceSetWrapper.DeltaResourceSet == reader.Item, "The delta resource set should be the same item in the reader.");
                itemsStack.Pop();
                break;

            case ODataReaderState.EntityReferenceLink:
                ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item;
                Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null.");
                ODataEntityReferenceLinkWrapper entityReferenceLinkWrapper = new ODataEntityReferenceLinkWrapper(entityReferenceLink);

                Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item.");
                {
                    ODataNestedResourceInfoWrapper parentNestedResource = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    parentNestedResource.NestedItems.Add(entityReferenceLinkWrapper);
                }

                break;

            case ODataReaderState.DeltaLink:        // added link
            case ODataReaderState.DeltaDeletedLink: // deleted link
                ODataDeltaLinkBaseWrapper linkBaseWrapper;
                if (ODataReaderState.DeltaLink == reader.State)
                {
                    ODataDeltaLink deltaLink = (ODataDeltaLink)reader.Item;
                    Contract.Assert(deltaLink != null, "Delta link should never be null.");
                    linkBaseWrapper = new ODataDeltaLinkWrapper(deltaLink);
                }
                else
                {
                    ODataDeltaDeletedLink deltaDeletedLink = (ODataDeltaDeletedLink)reader.Item;
                    Contract.Assert(deltaDeletedLink != null, "Delta deleted link should never be null.");
                    linkBaseWrapper = new ODataDeltaDeletedLinkWrapper(deltaDeletedLink);
                }

                Contract.Assert(itemsStack.Count > 0, "Delta link should never be reported as top-level item.");
                // Should never add a delta link to a non-delta resource set.
                ODataDeltaResourceSetWrapper linkResourceSetWrapper = (ODataDeltaResourceSetWrapper)itemsStack.Peek();
                Contract.Assert(linkResourceSetWrapper != null, "ODataDeltaResourceSetWrapper for delta link should not be null.");
                linkResourceSetWrapper.DeltaItems.Add(linkBaseWrapper);
                break;

            default:
                Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
                break;
            }
        }
Пример #5
0
        /// <summary>
        /// Read the delta resource set.
        /// </summary>
        /// <param name="reader">The OData reader.</param>
        /// <param name="itemsStack">The item stack.</param>
        /// <param name="topLevelItem">The top level item.</param>
        private static void ReadDeltaResourceSet(ODataReader reader, Stack <ODataItemWrapper> itemsStack, ref ODataItemWrapper topLevelItem)
        {
            Contract.Assert(reader != null);
            Contract.Assert(itemsStack != null);
            Contract.Assert(ODataReaderState.DeltaResourceSetStart == reader.State);

            ODataDeltaResourceSet deltaResourceSet = (ODataDeltaResourceSet)reader.Item;

            Contract.Assert(deltaResourceSet != null, "Delta ResourceSet should never be null.");

            ODataDeltaResourceSetWrapper deltaResourceSetWrapper = new ODataDeltaResourceSetWrapper(deltaResourceSet);

            if (itemsStack.Count > 0)
            {
                ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner delta resource set. inner delta resource sets always have a nested resource info.");
                Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain delta resource set as their child.");
                Contract.Assert(parentNestedResourceInfo.NestedItems.Count == 0, "Each nested property can contain only one delta resource set as its direct child.");
                parentNestedResourceInfo.NestedItems.Add(deltaResourceSetWrapper);
            }
            else
            {
                topLevelItem = deltaResourceSetWrapper;
            }

            itemsStack.Push(deltaResourceSetWrapper);
        }
        public async Task ReadDeletedLinkInDeltaResourceSetWorksAsExpected()
        {
            // Arrange
            string payload = "{" +
                             "\"@odata.context\":\"http://localhost/$metadata#Customers/$delta\"," +
                             "\"@odata.count\":5," +
                             "\"value\":[" +
                             "{" +
                             "\"@odata.id\":\"Customers(42)\"," +
                             "\"Name\":\"Sammy\"" +
                             "}," +
                             "{" +
                             "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedLink\"," +
                             "\"source\":\"Customers(39)\"," +
                             "\"relationship\":\"Orders\"," +
                             "\"target\":\"Orders(10643)\"" +
                             "}," +
                             "{" +
                             "\"@odata.context\":\"http://localhost/$metadata#Customers/$link\"," +
                             "\"source\":\"Customers(32)\"," +
                             "\"relationship\":\"Orders\"," +
                             "\"target\":\"Orders(10645)\"" +
                             "}," +
                             "{" +
                             "\"@odata.context\":\"http://localhost/$metadata#Orders/$entity\"," +
                             "\"@odata.id\":\"Orders(10643)\"," +
                             "\"Price\": 82" +
                             "}," +
                             "{" +
                             "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedEntity\"," +
                             "\"id\":\"Customers(21)\"," +
                             "\"reason\":\"deleted\"" +
                             "}" +
                             "]," +
                             "\"@odata.deltaLink\":\"Customers?$expand=Orders&$deltatoken=8015\"" +
                             "}";

            IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(customers); // Guard

            // Act
            Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType());
            ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func);

            // Assert
            Assert.NotNull(item);

            // --- DeltaResourceSet
            //      |--- Resource (1)
            //      |--- Resource (2)
            //      |--- DeletedResource (1)
            //      |
            //      |--- DeltaDeletedLink
            //      |--- DeltaLink
            ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item);

            // Resources
            Assert.Equal(3, deltaResourceSet.ResourceBases.Count);
            Assert.Collection(deltaResourceSet.ResourceBases,
                              e =>
            {
                ODataResourceWrapper resource1 = Assert.IsType <ODataResourceWrapper>(e);
                Assert.Equal("Customers(42)", resource1.Resource.Id.OriginalString);
                Assert.Equal("Sammy", resource1.Resource.Properties.First(p => p.Name == "Name").Value);
            },
                              e =>
            {
                ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(e);
                Assert.Equal("Orders(10643)", resource2.Resource.Id.OriginalString);
                Assert.Equal(82, resource2.Resource.Properties.First(p => p.Name == "Price").Value);
            },
                              e =>
            {
                ODataDeletedResourceWrapper deletedResource = Assert.IsType <ODataDeletedResourceWrapper>(e);
                Assert.Equal("Customers(21)", deletedResource.DeletedResource.Id.OriginalString);
                Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource.DeletedResource.Reason);
            });

            // DeltaLinks
            Assert.Equal(2, deltaResourceSet.DeltaLinks.Count);
            Assert.Collection(deltaResourceSet.DeltaLinks,
                              e =>
            {
                ODataDeltaDeletedLinkWrapper deletedLinkWrapper = Assert.IsType <ODataDeltaDeletedLinkWrapper>(e);
                Assert.Equal("Customers(39)", deletedLinkWrapper.DeltaDeletedLink.Source.OriginalString);
                Assert.Equal("Orders(10643)", deletedLinkWrapper.DeltaDeletedLink.Target.OriginalString);
                Assert.Equal("Orders", deletedLinkWrapper.DeltaDeletedLink.Relationship);
            },
                              e =>
            {
                ODataDeltaLinkWrapper linkWrapper = Assert.IsType <ODataDeltaLinkWrapper>(e);
                Assert.Equal("Customers(32)", linkWrapper.DeltaLink.Source.OriginalString);
                Assert.Equal("Orders(10645)", linkWrapper.DeltaLink.Target.OriginalString);
                Assert.Equal("Orders", linkWrapper.DeltaLink.Relationship);
            });
        }
        public async Task ReadDeltaResourceSetWorksAsExpected()
        {
            // Arrange
            string payload = "{\"@context\":\"http://example.com/$metadata#Customers/$delta\"," +
                             "\"value\":[" +
                             "{" +
                             "\"@removed\":{\"reason\":\"changed\"}," +
                             "\"CustomerID\":1," +
                             "\"Orders@delta\":[" +
                             "{" +
                             "\"@removed\":{\"reason\":\"deleted\"}," +
                             "\"OrderId\":10" +
                             "}," +
                             "{" +
                             "\"@type\":\"#NS.VipOrder\"," +
                             "\"OrderId\":9," +
                             "\"Email\":\"[email protected]\"" +
                             "}" +
                             "]" +
                             "}" +
                             "]" +
                             "}";

            IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(customers); // Guard

            // Act
            Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType());
            ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V401);

            // Assert
            Assert.NotNull(item);

            // --- DeltaResourceSet
            //      |--- DeleteResource (1)
            //          |--- NestedResourceInfo (1-1)
            //               |--- DeltaResourceSet
            //                     |--- DelteResource
            //                     |--- Normal Resource
            ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item);
            ODataResourceBaseWrapper     resourceBase     = Assert.Single(deltaResourceSet.ResourceBases);
            ODataDeletedResourceWrapper  deletedResource  = Assert.IsType <ODataDeletedResourceWrapper>(resourceBase);

            Assert.Equal(DeltaDeletedEntryReason.Changed, deletedResource.DeletedResource.Reason);

            ODataNestedResourceInfoWrapper nestedResourceInfo = Assert.Single(deletedResource.NestedResourceInfos);

            Assert.Equal("Orders", nestedResourceInfo.NestedResourceInfo.Name);
            Assert.True(nestedResourceInfo.NestedResourceInfo.IsCollection);

            ODataDeltaResourceSetWrapper ordersDeltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(nestedResourceInfo.NestedResourceSet);

            Assert.Equal(2, ordersDeltaResourceSet.ResourceBases.Count);
            ODataDeletedResourceWrapper deletedResource1 = Assert.IsType <ODataDeletedResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(0));

            Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource1.DeletedResource.Reason);

            ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(1));

            Assert.Equal("NS.VipOrder", resource2.Resource.TypeName);
            Assert.Collection(resource2.Resource.Properties,
                              p =>
            {
                Assert.Equal("OrderId", p.Name);
                Assert.Equal(9, p.Value);
            },
                              p =>
            {
                Assert.Equal("Email", p.Name);
                Assert.Equal("*****@*****.**", p.Value);
            });
        }
Пример #8
0
        /// <summary>
        /// Tries to convert the given value into an instance of <see cref="ODataItemWrapper"/>.
        /// </summary>
        /// <param name="property">The property being converted.</param>
        /// <param name="propertyValue">The property value to convert..</param>
        /// <param name="serverTypeName">The server type name of the entity whose properties are being populated.</param>
        /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param>
        /// <param name="odataItem">The odata resource or resource set if one was created.</param>
        /// <returns>Whether or not the value was converted.</returns>
        private bool TryConvertPropertyToResourceOrResourceSet(ClientPropertyAnnotation property, object propertyValue, string serverTypeName, HashSet <object> visitedComplexTypeObjects, out ODataItemWrapper odataItem)
        {
            if (property.IsComplexCollection)
            {
                odataItem = this.CreateODataComplexCollectionPropertyResourceSet(property, propertyValue, serverTypeName, visitedComplexTypeObjects);
                return(true);
            }

            if (property.IsComplex)
            {
                odataItem = this.CreateODataComplexPropertyResource(property, propertyValue, visitedComplexTypeObjects);
                return(true);
            }

            odataItem = null;
            return(false);
        }
Пример #9
0
        public static void TestReadResource()
        {
            string requestData = @"{
  ""@odata.type"": ""#NS.Customer"",
  ""*****@*****.**"": ""Cloud"",
  ""DisplayName"": ""Group Display Name"",
  ""*****@*****.**"": ""Cloud"",
  ""AssignedLabels"": [
    {
      ""City"": ""City1"",
      ""Street"": ""Street1""
    }
  ]
}";
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("Content-Type", "application/json;odata.metadata=minima;odata.streaming=true");
            headers.Add("Accept", "application/json");

            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings
            {
                BaseUri = new Uri("http://localhost"),
                ShouldIncludeAnnotation = s => true
            };

            //ODataResourceWrapper topLevelResource = null;

            ODataItemWrapper topLevel = null, currentItem = null;
            IEdmModel        model     = EdmModelBuilder.GetEdmModel();
            IEdmEntitySet    customers = model.EntityContainer.FindEntitySet("Customers");

            //  ODataResource resource = null;
            using (MemoryStream ms = new MemoryStream(Encoding.GetEncoding("iso-8859-1").GetBytes(requestData)))
            {
                ODataMessageWrapper requestMessage = new ODataMessageWrapper(ms);

                ODataMessageReader messageReader = new ODataMessageReader((IODataRequestMessage)requestMessage, readerSettings, model);

                Stack <ODataItemWrapper> resStack = new Stack <ODataItemWrapper>();
                ODataReader odataReader           = messageReader.CreateODataResourceReader(customers, customers.EntityType());

                while (odataReader.Read())
                {
                    Console.WriteLine(odataReader.State);

                    switch (odataReader.State)
                    {
                    case ODataReaderState.ResourceStart:
                        ODataResourceWrapper newResource = new ODataResourceWrapper();
                        newResource.Resource = odataReader.Item as ODataResource;

                        resStack.TryPeek(out currentItem);
                        if (currentItem == null)
                        {
                            // TopLevel, do nothing
                            Debug.Assert(topLevel == null);
                            topLevel = newResource;
                        }
                        else
                        {
                            currentItem.Append(newResource);
                        }

                        resStack.Push(newResource);
                        break;

                    case ODataReaderState.ResourceSetStart:
                        ODataResourceSet        resourceSet = (ODataResourceSet)odataReader.Item;
                        ODataResourceSetWrapper setWrapper  = new ODataResourceSetWrapper
                        {
                            ResourceSet = resourceSet
                        };

                        resStack.TryPeek(out currentItem);
                        if (currentItem == null)
                        {
                            // TopLevel, do nothing
                            Debug.Assert(topLevel == null);
                            topLevel = setWrapper;
                        }
                        else
                        {
                            currentItem.Append(setWrapper);
                        }

                        resStack.Push(setWrapper);
                        break;

                    case ODataReaderState.NestedResourceInfoStart:
                        resStack.TryPeek(out currentItem);
                        Debug.Assert(currentItem != null);

                        ODataItem item = odataReader.Item;
                        ODataNestedResourceInfoWrapper infoWrapper = new ODataNestedResourceInfoWrapper
                        {
                            NestedInfo = item as ODataNestedResourceInfo
                        };

                        currentItem.Append(infoWrapper);
                        resStack.Push(infoWrapper);
                        break;

                    case ODataReaderState.ResourceEnd:
                        //currWrapper = resStack.Peek();
                        //currWrapper.Resource = (ODataResource)odataReader.Item;
                        resStack.Pop();
                        break;

                    case ODataReaderState.ResourceSetEnd:

                        resStack.Pop();
                        break;

                    case ODataReaderState.NestedResourceInfoEnd:

                        item = odataReader.Item;

                        resStack.Pop();
                        break;
                    }
                }
            }

            if (topLevel == null)
            {
                return;
            }

            ODataResourceWrapper topLevelResource = topLevel as ODataResourceWrapper;

            if (topLevelResource != null)
            {
                foreach (var a in topLevelResource.Resource.Properties)
                {
                    Console.WriteLine(a.Name + ": " + a.Value);
                }

                foreach (var a in topLevelResource.NestedResourceInfos)
                {
                    Console.WriteLine(a.NestedInfo.Name);
                    ODataResourceSetWrapper setWrapper      = a.NestedWrapper as ODataResourceSetWrapper;
                    ODataResourceWrapper    resourceWrapper = a.NestedWrapper as ODataResourceWrapper;
                    if (resourceWrapper != null)
                    {
                        foreach (var prop in resourceWrapper.Resource.Properties)
                        {
                            Console.WriteLine(prop.Name + ": " + prop.Value);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Read the resource set.
        /// </summary>
        /// <param name="reader">The OData reader.</param>
        /// <param name="itemsStack">The item stack.</param>
        /// <param name="topLevelItem">The top level item.</param>
        private static void ReadResourceSet(ODataReader reader, Stack <ODataItemWrapper> itemsStack, ref ODataItemWrapper topLevelItem)
        {
            Contract.Assert(reader != null);
            Contract.Assert(itemsStack != null);
            Contract.Assert(ODataReaderState.ResourceSetStart == reader.State);

            ODataResourceSet resourceSet = (ODataResourceSet)reader.Item;

            Contract.Assert(resourceSet != null, "ResourceSet should never be null.");

            ODataResourceSetWrapper resourceSetWrapper = new ODataResourceSetWrapper(resourceSet);

            if (itemsStack.Count > 0)
            {
                ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner resource set. inner resource sets always have a nested resource info.");
                Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain resource set as their child.");

                Contract.Assert(parentNestedResourceInfo.NestedLinks == null, "collection single nested property can not contain reference link as its direct child.");
                Contract.Assert(parentNestedResourceInfo.NestedResource == null, "collection nested properties can not contain other resource as their child.");
                Contract.Assert(parentNestedResourceInfo.NestedResourceSet == null, "collection nested properties can not contain multiple resource set as their child.");
                parentNestedResourceInfo.NestedResourceSet = resourceSetWrapper;
            }
            else
            {
                topLevelItem = resourceSetWrapper;
            }

            itemsStack.Push(resourceSetWrapper);
        }