private void DeserializeContents(WorkflowMarkupSerializationManager serializationManager, object obj, XmlReader reader)
        {
            if (serializationManager == null)
                throw new ArgumentNullException("serializationManager");
            if (obj == null)
                throw new ArgumentNullException("obj");
            if (reader == null)
                throw new ArgumentNullException("reader");

            if (reader.NodeType != XmlNodeType.Element)
                return;

            // get the serializer
            WorkflowMarkupSerializer serializer = serializationManager.GetSerializer(obj.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;
            if (serializer == null)
            {
                serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerNotAvailable, obj.GetType().FullName), reader));
                return;
            }

            try
            {
                serializer.OnBeforeDeserialize(serializationManager, obj);
            }
            catch (Exception e)
            {
                serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                return;
            }

            bool isEmptyElement = reader.IsEmptyElement;
            string elementNamespace = reader.NamespaceURI;

            List<PropertyInfo> props = new List<PropertyInfo>();
            List<EventInfo> events = new List<EventInfo>();
            // Add the extended properties for primitive types
            if (obj.GetType().IsPrimitive || obj.GetType() == typeof(string) || obj.GetType() == typeof(decimal) ||
                obj.GetType().IsEnum || obj.GetType() == typeof(DateTime) || obj.GetType() == typeof(TimeSpan) ||
                obj.GetType() == typeof(Guid))
            {
                props.AddRange(serializationManager.GetExtendedProperties(obj));
            }
            else
            {
                try
                {
                    props.AddRange(serializer.GetProperties(serializationManager, obj));
                    props.AddRange(serializationManager.GetExtendedProperties(obj));
                    events.AddRange(serializer.GetEvents(serializationManager, obj));
                }
                catch (Exception e)
                {
                    serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerThrewException, obj.GetType(), e.Message), e, reader));
                    return;
                }
            }
            //First we try to deserialize simple properties
            if (reader.HasAttributes)
            {
                while (reader.MoveToNextAttribute())
                {
                    // 
                    if (reader.LocalName.Equals("xmlns", StringComparison.Ordinal) || reader.Prefix.Equals("xmlns", StringComparison.Ordinal))
                        continue;

                    //
                    XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix));
                    if (xmlQualifiedName.Namespace.Equals(StandardXomlKeys.Definitions_XmlNs, StringComparison.Ordinal) &&
                        !IsMarkupExtension(xmlQualifiedName) &&
                        !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, props, xmlQualifiedName) &&
                        !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, xmlQualifiedName))
                    {
                        serializationManager.FireFoundDefTag(new WorkflowMarkupElementEventArgs(reader));
                        continue;
                    }

                    //For simple properties we assume that if . indicates
                    string propName = XmlConvert.DecodeName(reader.LocalName);
                    string propVal = reader.Value;
                    DependencyProperty dependencyProperty = ResolveDependencyProperty(serializationManager, reader, obj, propName);
                    if (dependencyProperty != null)
                    {
                        serializationManager.Context.Push(dependencyProperty);
                        try
                        {
                            if (dependencyProperty.IsEvent)
                                DeserializeEvent(serializationManager, reader, obj, propVal);
                            else
                                DeserializeSimpleProperty(serializationManager, reader, obj, propVal);
                        }
                        finally
                        {
                            Debug.Assert(serializationManager.Context.Current == dependencyProperty, "Serializer did not remove an object it pushed into stack.");
                            serializationManager.Context.Pop();
                        }
                    }
                    else
                    {
                        PropertyInfo property = WorkflowMarkupSerializer.LookupProperty(props, propName);
                        if (property != null)
                        {
                            serializationManager.Context.Push(property);
                            try
                            {
                                DeserializeSimpleProperty(serializationManager, reader, obj, propVal);
                            }
                            finally
                            {
                                Debug.Assert((PropertyInfo)serializationManager.Context.Current == property, "Serializer did not remove an object it pushed into stack.");
                                serializationManager.Context.Pop();
                            }
                        }
                        else
                        {
                            EventInfo evt = WorkflowMarkupSerializer.LookupEvent(events, propName);
                            if (events != null && evt != null)
                            {
                                serializationManager.Context.Push(evt);
                                try
                                {
                                    DeserializeEvent(serializationManager, reader, obj, propVal);
                                }
                                finally
                                {
                                    Debug.Assert((EventInfo)serializationManager.Context.Current == evt, "Serializer did not remove an object it pushed into stack.");
                                    serializationManager.Context.Pop();
                                }
                            }
                            else
                                serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerNoMemberFound, new object[] { propName, obj.GetType().FullName }), reader));
                        }
                    }
                }
            }

            try
            {
                serializer.OnBeforeDeserializeContents(serializationManager, obj);
            }
            catch (Exception e)
            {
                serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                return;
            }

            //Now deserialize compound properties
            try
            {
                serializer.ClearChildren(serializationManager, obj);
            }
            catch (Exception e)
            {
                serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerThrewException, obj.GetType(), e.Message), e, reader));
                return;
            }

            using (ContentProperty contentProperty = new ContentProperty(serializationManager, serializer, obj))
            {
                List<ContentInfo> contents = new List<ContentInfo>();
                if (!isEmptyElement)
                {
                    reader.MoveToElement();
                    int initialDepth = reader.Depth;
                    XmlQualifiedName extendedPropertyQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix));
                    do
                    {
                        // Extended property should be deserialized, this is required for primitive types which have extended property as children
                        // We should  not ignore 
                        if (extendedPropertyQualifiedName != null && !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, extendedPropertyQualifiedName))
                        {
                            extendedPropertyQualifiedName = null;
                            continue;
                        }
                        // this will make it to skip all the nodes
                        if ((initialDepth + 1) < reader.Depth)
                        {
                            bool unnecessaryXmlFound = false;
                            while (reader.Read() && ((initialDepth + 1) < reader.Depth))
                            {
                                // Ignore comments and whitespaces
                                if (reader.NodeType != XmlNodeType.Comment && reader.NodeType != XmlNodeType.Whitespace && !unnecessaryXmlFound)
                                {
                                    serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidDataFoundForType, obj.GetType().FullName), reader));
                                    unnecessaryXmlFound = true;
                                }
                            }
                        }

                        //Push all the PIs into stack so that they are available for type resolution
                        AdvanceReader(reader);
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            //We should only support A.B syntax for compound properties, all others are treated as content
                            XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix));
                            int index = reader.LocalName.IndexOf('.');
                            if (index > 0 || ExtendedPropertyInfo.IsExtendedProperty(serializationManager, xmlQualifiedName))
                            {
                                string propertyName = reader.LocalName.Substring(reader.LocalName.IndexOf('.') + 1);
                                PropertyInfo property = WorkflowMarkupSerializer.LookupProperty(props, propertyName);
                                DependencyProperty dependencyProperty = ResolveDependencyProperty(serializationManager, reader, obj, reader.LocalName);
                                if (dependencyProperty == null && property == null)
                                    serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidElementFoundForType, reader.LocalName, obj.GetType().FullName), reader));
                                else if (dependencyProperty != null)
                                {
                                    PropertyInfo prop = WorkflowMarkupSerializer.LookupProperty(props, dependencyProperty.Name);
                                    //Deserialize the dynamic property
                                    serializationManager.Context.Push(dependencyProperty);
                                    try
                                    {
                                        DeserializeCompoundProperty(serializationManager, reader, obj);
                                    }
                                    finally
                                    {
                                        Debug.Assert(serializationManager.Context.Current == dependencyProperty, "Serializer did not remove an object it pushed into stack.");
                                        serializationManager.Context.Pop();
                                    }
                                }
                                else if (property != null)
                                {
                                    //Deserialize the compound property
                                    serializationManager.Context.Push(property);
                                    try
                                    {
                                        DeserializeCompoundProperty(serializationManager, reader, obj);
                                    }
                                    finally
                                    {
                                        Debug.Assert((PropertyInfo)serializationManager.Context.Current == property, "Serializer did not remove an object it pushed into stack.");
                                        serializationManager.Context.Pop();
                                    }
                                }
                            }
                            else
                            {
                                //Deserialize the children
                                int lineNumber = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LineNumber : 1;
                                int linePosition = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LinePosition : 1;
                                object obj2 = DeserializeObject(serializationManager, reader);
                                if (obj2 != null)
                                {
                                    obj2 = GetValueFromMarkupExtension(serializationManager, obj2);
                                    if (obj2 != null && obj2.GetType() == typeof(string) && ((string)obj2).StartsWith("{}", StringComparison.Ordinal))
                                        obj2 = ((string)obj2).Substring(2);
                                    contents.Add(new ContentInfo(obj2, lineNumber, linePosition));
                                }
                            }
                        }
                        else if (reader.NodeType == XmlNodeType.Text && contentProperty.Property != null)
                        {
                            //If we read the string then we should not advance the reader further instead break
                            int lineNumber = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LineNumber : 1;
                            int linePosition = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LinePosition : 1;
                            contents.Add(new ContentInfo(reader.ReadString(), lineNumber, linePosition));
                            if (initialDepth >= reader.Depth)
                                break;
                        }
                        else
                        {
                            if (reader.NodeType == XmlNodeType.Entity ||
                                reader.NodeType == XmlNodeType.Text ||
                                reader.NodeType == XmlNodeType.CDATA)
                                serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidDataFound, reader.Value.Trim(), obj.GetType().FullName), reader));
                        }
                    } while (reader.Read() && initialDepth < reader.Depth);
                }
                //Make sure that we set contents
                contentProperty.SetContents(contents);
            }
            try
            {
                serializer.OnAfterDeserialize(serializationManager, obj);
            }
            catch (Exception e)
            {
                serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                return;
            }
        }