internal void SerializeContents(WorkflowMarkupSerializationManager serializationManager, object obj, XmlWriter writer, bool dictionaryKey)
        {
            if (serializationManager == null)
                throw new ArgumentNullException("serializationManager");
            if (obj == null)
                throw new ArgumentNullException("obj");
            if (writer == null)
                throw new ArgumentNullException("writer");

            WorkflowMarkupSerializer serializer = null;
            try
            {
                //Now get the serializer to persist the properties, if the serializer is not found then we dont serialize the properties
                serializer = serializationManager.GetSerializer(obj.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;

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

            }

            if (serializer == null)
            {
                serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNotAvailableForSerialize, obj.GetType().FullName)));
                return;
            }

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

            Hashtable allProperties = new Hashtable();
            ArrayList complexProperties = new ArrayList();

            IDictionary<DependencyProperty, object> dependencyProperties = null;
            List<PropertyInfo> properties = new List<PropertyInfo>();
            List<EventInfo> events = new List<EventInfo>();
            Hashtable designTimeTypeNames = null;

            // Serialize the extended properties for primitive types also
            if (obj.GetType().IsPrimitive || obj.GetType() == typeof(string) || obj.GetType() == typeof(decimal) ||
                obj.GetType() == typeof(DateTime) || obj.GetType() == typeof(TimeSpan) || obj.GetType().IsEnum ||
                obj.GetType() == typeof(Guid))
            {
                if (obj.GetType() == typeof(char) || obj.GetType() == typeof(byte) ||
                    obj.GetType() == typeof(System.Int16) || obj.GetType() == typeof(decimal) ||
                    obj.GetType() == typeof(DateTime) || obj.GetType() == typeof(TimeSpan) ||
                    obj.GetType().IsEnum || obj.GetType() == typeof(Guid))
                {
                    //These non CLS-compliant are not supported in the XmlWriter 
                    if ((obj.GetType() != typeof(char)) || (char)obj != '\0')
                    {
                        //These non CLS-compliant are not supported in the XmlReader 
                        string stringValue = String.Empty;
                        if (obj.GetType() == typeof(DateTime))
                        {
                            stringValue = ((DateTime)obj).ToString("o", CultureInfo.InvariantCulture);
                        }
                        else
                        {
                            TypeConverter typeConverter = TypeDescriptor.GetConverter(obj.GetType());
                            if (typeConverter != null && typeConverter.CanConvertTo(typeof(string)))
                                stringValue = typeConverter.ConvertTo(null, CultureInfo.InvariantCulture, obj, typeof(string)) as string;
                            else
                                stringValue = Convert.ToString(obj, CultureInfo.InvariantCulture);
                        }

                        writer.WriteValue(stringValue);
                    }
                }
                else if (obj.GetType() == typeof(string))
                {
                    string attribValue = obj as string;
                    attribValue = attribValue.Replace('\0', ' ');
                    if (!(attribValue.StartsWith("{", StringComparison.Ordinal) && attribValue.EndsWith("}", StringComparison.Ordinal)))
                        writer.WriteValue(attribValue);
                    else
                        writer.WriteValue("{}" + attribValue);
                }
                else
                {
                    writer.WriteValue(obj);
                }
                // For Key properties, we don;t want to get the extended properties
                if (!dictionaryKey)
                    properties.AddRange(serializationManager.GetExtendedProperties(obj));
            }
            else
            {
                // Serialize properties
                //We first get all the properties, once we have them all, we start distinguishing between
                //simple and complex properties, the reason for that is XmlWriter needs to write attributes
                //first and elements later

                // Dependency events are treated as the same as dependency properties.


                try
                {
                    if (obj is DependencyObject && ((DependencyObject)obj).UserData.Contains(UserDataKeys.DesignTimeTypeNames))
                        designTimeTypeNames = ((DependencyObject)obj).UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
                    dependencyProperties = serializer.GetDependencyProperties(serializationManager, obj);
                    properties.AddRange(serializer.GetProperties(serializationManager, obj));
                    // For Key properties, we don;t want to get the extended properties
                    if (!dictionaryKey)
                        properties.AddRange(serializationManager.GetExtendedProperties(obj));
                    events.AddRange(serializer.GetEvents(serializationManager, obj));
                }
                catch (Exception e)
                {
                    serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                    return;
                }
            }
            if (dependencyProperties != null)
            {
                // For attached properties that does not have a corresponding real property on the object, if the value is a design time
                // type, it may not be set through dependency property SetValue, therefore will not be present in the dependencyProperties
                // collection, we'll have to get the dependency property object ourselves.
                if (designTimeTypeNames != null)
                {
                    foreach (object key in designTimeTypeNames.Keys)
                    {
                        DependencyProperty dependencyProperty = key as DependencyProperty;
                        if (dependencyProperty != null && !dependencyProperties.ContainsKey(dependencyProperty))
                            dependencyProperties.Add(dependencyProperty, designTimeTypeNames[dependencyProperty]);
                    }
                }

                // Add all dependency properties to the master collection.
                foreach (DependencyProperty dependencyProperty in dependencyProperties.Keys)
                {
                    string propertyName = String.Empty;
                    if (dependencyProperty.IsAttached)
                    {
                        string prefix = String.Empty;
                        XmlQualifiedName qualifiedName = serializationManager.GetXmlQualifiedName(dependencyProperty.OwnerType, out prefix);
                        propertyName = qualifiedName.Name + "." + dependencyProperty.Name;
                    }
                    else
                    {
                        propertyName = dependencyProperty.Name;
                    }

                    if (dependencyProperty.IsAttached || !dependencyProperty.DefaultMetadata.IsMetaProperty)
                        allProperties.Add(propertyName, dependencyProperty);
                }
            }

            if (properties != null)
            {
                foreach (PropertyInfo propInfo in properties)
                {
                    // Do not serialize properties that have corresponding dynamic properties.
                    if (propInfo != null && !allProperties.ContainsKey(propInfo.Name))
                        allProperties.Add(propInfo.Name, propInfo);
                }
            }

            if (events != null)
            {
                foreach (EventInfo eventInfo in events)
                {
                    // Do not serialize events that have corresponding dynamic properties.
                    if (eventInfo != null && !allProperties.ContainsKey(eventInfo.Name))
                        allProperties.Add(eventInfo.Name, eventInfo);
                }
            }

            using (ContentProperty contentProperty = new ContentProperty(serializationManager, serializer, obj))
            {
                foreach (object propertyObj in allProperties.Values)
                {
                    string propertyName = String.Empty;
                    object propertyValue = null;
                    Type propertyInfoType = null;

                    try
                    {
                        if (propertyObj is PropertyInfo)
                        {
                            PropertyInfo property = propertyObj as PropertyInfo;

                            // If the property has parameters we can not serialize it , we just move on.
                            ParameterInfo[] indexParameters = property.GetIndexParameters();
                            if (indexParameters != null && indexParameters.Length > 0)
                                continue;

                            propertyName = property.Name;
                            propertyValue = null;
                            if (property.CanRead)
                            {
                                propertyValue = property.GetValue(obj, null);
                                if (propertyValue == null && TypeProvider.IsAssignable(typeof(Type), property.PropertyType))
                                {
                                    // See if we have a design time value for the property
                                    DependencyProperty dependencyProperty = DependencyProperty.FromName(property.Name, property.ReflectedType);
                                    if (dependencyProperty != null)
                                        propertyValue = Helpers.GetDesignTimeTypeName(obj, dependencyProperty);

                                    if (propertyValue == null)
                                    {
                                        string key = property.ReflectedType.FullName + "." + property.Name;
                                        propertyValue = Helpers.GetDesignTimeTypeName(obj, key);
                                    }
                                    if (propertyValue != null)
                                        propertyValue = new TypeExtension((string)propertyValue);
                                }
                            }
                            propertyInfoType = property.PropertyType;
                        }
                        else if (propertyObj is EventInfo)
                        {
                            EventInfo evt = propertyObj as EventInfo;
                            propertyName = evt.Name;
                            propertyValue = WorkflowMarkupSerializationHelpers.GetEventHandlerName(obj, evt.Name);
                            if ((propertyValue == null || (propertyValue is string && string.IsNullOrEmpty((string)propertyValue)))
                                && obj is DependencyObject)
                            {
                                // The object is not created through deserialization, we should check to see if the delegate is 
                                // created and added to list.  We can only serialize the handler if its target type is the same
                                // as the activity type that's be designed.
                                DependencyProperty dependencyProperty = DependencyProperty.FromName(propertyName, obj.GetType());
                                if (dependencyProperty != null)
                                {
                                    Activity activity = serializationManager.Context[typeof(Activity)] as Activity;
                                    Delegate handler = ((DependencyObject)obj).GetHandler(dependencyProperty) as Delegate;
                                    if (handler != null && activity != null && TypeProvider.Equals(handler.Target.GetType(), Helpers.GetRootActivity(activity).GetType()))
                                        propertyValue = handler;
                                }
                            }
                            propertyInfoType = evt.EventHandlerType;
                        }
                        else if (propertyObj is DependencyProperty)
                        {
                            DependencyProperty dependencyProperty = propertyObj as DependencyProperty;
                            propertyName = dependencyProperty.Name;
                            propertyValue = dependencyProperties[dependencyProperty];
                            propertyInfoType = dependencyProperty.PropertyType;
                        }
                    }
                    catch (Exception e)
                    {
                        while (e is TargetInvocationException && e.InnerException != null)
                            e = e.InnerException;

                        serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerPropertyGetFailed, new object[] { propertyName, obj.GetType().FullName, e.Message })));
                        continue;
                    }

                    if (propertyObj is PropertyInfo && contentProperty.Property == (PropertyInfo)propertyObj)
                        continue;

                    Type propertyValueType = null;
                    if (propertyValue != null)
                    {
                        propertyValue = GetMarkupExtensionFromValue(propertyValue);
                        propertyValueType = propertyValue.GetType();
                    }
                    else if (propertyObj is PropertyInfo)
                    {
                        propertyValue = new NullExtension();
                        propertyValueType = propertyValue.GetType();
                        Attribute[] attributes = Attribute.GetCustomAttributes(propertyObj as PropertyInfo, typeof(DefaultValueAttribute), true);
                        if (attributes.Length > 0)
                        {
                            DefaultValueAttribute defaultValueAttr = attributes[0] as DefaultValueAttribute;
                            if (defaultValueAttr.Value == null)
                                propertyValue = null;
                        }
                    }
                    if (propertyValue != null)
                        propertyValueType = propertyValue.GetType();

                    //Now get the serializer to persist the properties, if the serializer is not found then we dont serialize the properties
                    serializationManager.Context.Push(propertyObj);
                    WorkflowMarkupSerializer propValueSerializer = null;
                    try
                    {
                        propValueSerializer = serializationManager.GetSerializer(propertyValueType, typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;
                    }
                    catch (Exception e)
                    {
                        serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                        serializationManager.Context.Pop();
                        continue;
                    }
                    if (propValueSerializer == null)
                    {
                        serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNotAvailableForSerialize, propertyValueType.FullName)));
                        serializationManager.Context.Pop();
                        continue;
                    }

                    // ask serializer if we can serialize
                    try
                    {
                        if (propValueSerializer.ShouldSerializeValue(serializationManager, propertyValue))
                        {
                            //NOTE: THE FOLLOWING CONDITION ABOUT propertyInfoType != typeof(object) is VALID AS WE SHOULD NOT SERIALIZE A PROPERTY OF TYPE OBJECT TO STRING
                            //IF WE DO THAT THEN WE DO NOT KNOWN WHAT WAS THE TYPE OF ORIGINAL OBJECT AND SERIALIZER WONT BE ABLE TO GET THE STRING BACK INTO THE CORRECT TYPE,
                            //AS THE TYPE INFORMATION IS LOST
                            if (propValueSerializer.CanSerializeToString(serializationManager, propertyValue) && propertyInfoType != typeof(object))
                            {
                                using (new SafeXmlNodeWriter(serializationManager, obj, propertyObj, XmlNodeType.Attribute))
                                {
                                    //This is a work around to special case the markup extension serializer as it writes to the stream using writer
                                    if (propValueSerializer is MarkupExtensionSerializer)
                                    {
                                        propValueSerializer.SerializeToString(serializationManager, propertyValue);
                                    }
                                    else
                                    {
                                        string stringValue = propValueSerializer.SerializeToString(serializationManager, propertyValue);
                                        if (!string.IsNullOrEmpty(stringValue))
                                        {
                                            stringValue = stringValue.Replace('\0', ' ');
                                            if (propertyValue is MarkupExtension || !(stringValue.StartsWith("{", StringComparison.Ordinal) && stringValue.EndsWith("}", StringComparison.Ordinal)))
                                                writer.WriteString(stringValue);
                                            else
                                                writer.WriteString("{}" + stringValue);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                complexProperties.Add(propertyObj);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNoSerializeLogic, new object[] { propertyName, obj.GetType().FullName }), e));
                    }
                    finally
                    {
                        Debug.Assert(serializationManager.Context.Current == propertyObj, "Serializer did not remove an object it pushed into stack.");
                        serializationManager.Context.Pop();
                    }
                }

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

                // serialize compound properties as child elements of the current node.
                foreach (object propertyObj in complexProperties)
                {
                    // get value and check for null
                    string propertyName = String.Empty;
                    object propertyValue = null;
                    Type ownerType = null;
                    bool isReadOnly = false;

                    try
                    {
                        if (propertyObj is PropertyInfo)
                        {
                            PropertyInfo property = propertyObj as PropertyInfo;
                            propertyName = property.Name;
                            propertyValue = property.CanRead ? property.GetValue(obj, null) : null;
                            ownerType = obj.GetType();
                            isReadOnly = (!property.CanWrite);
                        }
                        else if (propertyObj is DependencyProperty)
                        {
                            DependencyProperty dependencyProperty = propertyObj as DependencyProperty;
                            propertyName = dependencyProperty.Name;
                            propertyValue = dependencyProperties[dependencyProperty];
                            ownerType = dependencyProperty.OwnerType;
                            isReadOnly = ((dependencyProperty.DefaultMetadata.Options & DependencyPropertyOptions.ReadOnly) == DependencyPropertyOptions.ReadOnly);
                        }
                    }
                    catch (Exception e)
                    {
                        while (e is TargetInvocationException && e.InnerException != null)
                            e = e.InnerException;

                        serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerPropertyGetFailed, propertyName, ownerType.FullName, e.Message)));
                        continue;
                    }

                    if (propertyObj is PropertyInfo && (PropertyInfo)propertyObj == contentProperty.Property)
                        continue;

                    if (propertyValue != null)
                    {
                        propertyValue = GetMarkupExtensionFromValue(propertyValue);

                        WorkflowMarkupSerializer propValueSerializer = serializationManager.GetSerializer(propertyValue.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;
                        if (propValueSerializer != null)
                        {
                            using (new SafeXmlNodeWriter(serializationManager, obj, propertyObj, XmlNodeType.Element))
                            {
                                if (isReadOnly)
                                    propValueSerializer.SerializeContents(serializationManager, propertyValue, writer, false);
                                else
                                    propValueSerializer.SerializeObject(serializationManager, propertyValue, writer);
                            }
                        }
                        else
                        {
                            serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNotAvailableForSerialize, propertyValue.GetType().FullName)));
                        }
                    }
                }

                // serialize the contents
                try
                {
                    object contents = contentProperty.GetContents();
                    if (contents != null)
                    {
                        contents = GetMarkupExtensionFromValue(contents);

                        WorkflowMarkupSerializer propValueSerializer = serializationManager.GetSerializer(contents.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;
                        if (propValueSerializer == null)
                        {
                            serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNotAvailableForSerialize, contents.GetType())));
                        }
                        else
                        {
                            //



                            //NOTE: THE FOLLOWING CONDITION ABOUT contentProperty.Property.PropertyType != typeof(object) is VALID AS WE SHOULD NOT SERIALIZE A PROPERTY OF TYPE OBJECT TO STRING
                            //IF WE DO THAT THEN WE DO NOT KNOWN WHAT WAS THE TYPE OF ORIGINAL OBJECT AND SERIALIZER WONT BE ABLE TO GET THE STRING BACK INTO THE CORRECT TYPE,
                            //AS THE TYPE INFORMATION IS LOST
                            if (propValueSerializer.CanSerializeToString(serializationManager, contents) &&
                                (contentProperty.Property == null || contentProperty.Property.PropertyType != typeof(object)))
                            {
                                string stringValue = propValueSerializer.SerializeToString(serializationManager, contents);
                                if (!string.IsNullOrEmpty(stringValue))
                                {
                                    stringValue = stringValue.Replace('\0', ' ');
                                    if (contents is MarkupExtension || !(stringValue.StartsWith("{", StringComparison.Ordinal) && stringValue.EndsWith("}", StringComparison.Ordinal)))
                                        writer.WriteString(stringValue);
                                    else
                                        writer.WriteString("{}" + stringValue);
                                }
                            }
                            else if (CollectionMarkupSerializer.IsValidCollectionType(contents.GetType()))
                            {
                                if (contentProperty.Property == null)
                                {
                                    IEnumerable enumerableContents = contents as IEnumerable;
                                    foreach (object childObj in enumerableContents)
                                    {
                                        if (childObj == null)
                                        {
                                            SerializeObject(serializationManager, new NullExtension(), writer);
                                        }
                                        else
                                        {
                                            object childObj2 = childObj;
                                            bool dictionaryEntry = (childObj2 is DictionaryEntry);
                                            try
                                            {
                                                if (dictionaryEntry)
                                                {
                                                    serializationManager.WorkflowMarkupStack.Push(childObj);
                                                    childObj2 = ((DictionaryEntry)childObj2).Value;
                                                }
                                                childObj2 = GetMarkupExtensionFromValue(childObj2);
                                                WorkflowMarkupSerializer childObjectSerializer = serializationManager.GetSerializer(childObj2.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer;
                                                if (childObjectSerializer != null)
                                                    childObjectSerializer.SerializeObject(serializationManager, childObj2, writer);
                                                else
                                                    serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerNotAvailableForSerialize, childObj2.GetType())));
                                            }
                                            finally
                                            {
                                                if (dictionaryEntry)
                                                    serializationManager.WorkflowMarkupStack.Pop();
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    propValueSerializer.SerializeContents(serializationManager, contents, writer, false);
                                }
                            }
                            else
                            {
                                propValueSerializer.SerializeObject(serializationManager, contents, writer);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e));
                    return;
                }
            }

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