/// <summary>Called internally to deserialize each <see cref="SyndicationElementExtension"/></summary>
        /// <param name="reader">XmlReader for current extension</param>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(XmlReader reader, EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            EpmValueBuilder currentValue = new EpmValueBuilder();

            do
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (currentRoot.HasContent)
                        {
                            // Throw an exception that we hit mixed-content.
                            // <contentElement>value<someElement /></contentElement>
                            // <contentElement><someElement />value</contentElement>
                            throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                        }

                        String elementName = reader.LocalName;
                        String namespaceUri = reader.NamespaceURI;
                        EpmTargetPathSegment newRoot = currentRoot.SubSegments
                                                                  .SingleOrDefault(s => s.SegmentNamespaceUri == namespaceUri && s.SegmentName == elementName);
                        if (newRoot == null)
                        {
                            WebUtil.SkipToEnd(reader, elementName, namespaceUri);
                            continue;
                        }

                        currentRoot = newRoot;
                        
                        this.DeserializeAttributes(reader, currentRoot, element, resourceType);
                        
                        if (currentRoot.HasContent)
                        {
                            if (reader.IsEmptyElement)
                            {
                                if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                                {
                                    resourceType.SetEpmValue(currentRoot, element, String.Empty, this);
                                }

                                currentRoot = currentRoot.ParentSegment;
                            }
                        }
                        
                        break;

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        if (!currentRoot.HasContent)
                        {
                            // Throw an exception that we hit mixed-content.
                            // <noContentElement>value<contentElement>value</contentElement></noContentElement>
                            // <noContentElement><contentElement>value</contentElement>value</noContentElement>
                            throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                        }

                        currentValue.Append(reader.Value);
                        break;
                        
                    case XmlNodeType.EndElement:
                        if (currentRoot.HasContent)
                        {
                            if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                            {
                                resourceType.SetEpmValue(currentRoot, element, currentValue.Value, this);
                            }
                        }

                        currentRoot = currentRoot.ParentSegment;
                        currentValue.Reset();
                        break;

                    case XmlNodeType.Comment:
                    case XmlNodeType.Whitespace:
                        break;

                    case XmlNodeType.None:
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.Attribute:
                    case XmlNodeType.EndEntity:
                    case XmlNodeType.EntityReference:
                    case XmlNodeType.Entity:
                    case XmlNodeType.Document:
                    case XmlNodeType.DocumentType:
                    case XmlNodeType.DocumentFragment:
                    case XmlNodeType.Notation:
                    case XmlNodeType.ProcessingInstruction:
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_InvalidXmlEntity);
                }
            }
            while (currentRoot.ParentSegment != null && reader.Read());
        }
        /// <summary>Called internally to deserialize each <see cref="SyndicationElementExtension"/></summary>
        /// <param name="reader">XmlReader for current extension</param>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(XmlReader reader, EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            EpmValueBuilder currentValue = new EpmValueBuilder();

            do
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                    if (currentRoot.HasContent)
                    {
                        // Throw an exception that we hit mixed-content.
                        // <contentElement>value<someElement /></contentElement>
                        // <contentElement><someElement />value</contentElement>
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                    }

                    String elementName           = reader.LocalName;
                    String namespaceUri          = reader.NamespaceURI;
                    EpmTargetPathSegment newRoot = currentRoot.SubSegments
                                                   .SingleOrDefault(s => s.SegmentNamespaceUri == namespaceUri && s.SegmentName == elementName);
                    if (newRoot == null)
                    {
                        WebUtil.SkipToEnd(reader, elementName, namespaceUri);
                        continue;
                    }

                    currentRoot = newRoot;

                    this.DeserializeAttributes(reader, currentRoot, element, resourceType);

                    if (currentRoot.HasContent)
                    {
                        if (reader.IsEmptyElement)
                        {
                            if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                            {
                                resourceType.SetEpmValue(currentRoot, element, String.Empty, this);
                            }

                            currentRoot = currentRoot.ParentSegment;
                        }
                    }

                    break;

                case XmlNodeType.CDATA:
                case XmlNodeType.Text:
                case XmlNodeType.SignificantWhitespace:
                    if (!currentRoot.HasContent)
                    {
                        // Throw an exception that we hit mixed-content.
                        // <noContentElement>value<contentElement>value</contentElement></noContentElement>
                        // <noContentElement><contentElement>value</contentElement>value</noContentElement>
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                    }

                    currentValue.Append(reader.Value);
                    break;

                case XmlNodeType.EndElement:
                    if (currentRoot.HasContent)
                    {
                        if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                        {
                            resourceType.SetEpmValue(currentRoot, element, currentValue.Value, this);
                        }
                    }

                    currentRoot = currentRoot.ParentSegment;
                    currentValue.Reset();
                    break;

                case XmlNodeType.Comment:
                case XmlNodeType.Whitespace:
                    break;

                case XmlNodeType.None:
                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.Attribute:
                case XmlNodeType.EndEntity:
                case XmlNodeType.EntityReference:
                case XmlNodeType.Entity:
                case XmlNodeType.Document:
                case XmlNodeType.DocumentType:
                case XmlNodeType.DocumentFragment:
                case XmlNodeType.Notation:
                case XmlNodeType.ProcessingInstruction:
                    throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_InvalidXmlEntity);
                }
            }while (currentRoot.ParentSegment != null && reader.Read());
        }