TrackingProfileSerializer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / Tracking / TrackingProfileSerializer.cs / 1305376 / TrackingProfileSerializer.cs

                            using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text; 
using System.Xml;
using System.Xml.Schema; 
using System.IO; 
using System.Reflection;
using System.Diagnostics; 
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Globalization;
 
//using System.Workflow.Activities;
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime; 
using System.Workflow.Runtime.Hosting;
using Hosting = System.Workflow.Runtime.Hosting; 

namespace System.Workflow.Runtime.Tracking
{
    ///  
    /// Used for xml serializing a TrackProfile.
    ///  
    public class TrackingProfileSerializer 
    {
        public TrackingProfileSerializer() 
        {
            _schema = XmlSchema.Read(new StringReader(_xsd), null);
            _schema.Namespaces.Add("", _ns);
        } 

        public XmlSchema Schema 
        { 
            get
            { 
                return _schema;
            }
        }
 
        #region Deserialization
 
        List _vArgs = new List(); 
        bool _vex = false;
        ///  
        /// Deserialize TrackingProfile in xml form to a TrackingProfile object.
        /// 
        /// TextReader containing TrackingProfile in xml form
        /// TrackingProfile 
        /// XmlSchemaException
        /// XmlException 
        /// ArgumentNullException 
        /// ArgumentException
        /// ArgumentOutOfRangeException 
        /// FormatException
        /// OverflowException
        /// InvalidOperationException
        /// TrackingProfileDeserializationException 
        public TrackingProfile Deserialize(TextReader reader)
        { 
            TrackingProfile profile = null; 
            _vArgs = new List();
            _vex = false; 

            if (null == reader)
                throw new ArgumentNullException("reader");
 
            //
            // Specify that if no namespace is declare the default should be interpreted as ours 
            NameTable nt = new NameTable(); 
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
            nsmgr.AddNamespace(String.Empty, _ns); 
            XmlParserContext ctx = new XmlParserContext(nt, nsmgr, null, XmlSpace.None);
            XmlReader pReader = XmlReader.Create(reader, GetSchemaReaderSettings(), ctx);

            try 
            {
                profile = new TrackingProfile(); 
                // 
                // Schema validation will catch if element is missing
                if (!pReader.ReadToDescendant("TrackingProfile")) 
                {
                    //
                    // Will throw exception with validation errors
                    CheckSchemaErrors(); 
                    return null;
                } 
 
                string version = pReader.GetAttribute("version");
                if ((null == version) || (0 == version.Trim().Length)) 
                    throw new TrackingProfileDeserializationException(ExecutionStringManager.InvalidProfileVersion);

                profile.Version = new Version(version);
 
                if (!pReader.ReadToDescendant("TrackPoints"))
                { 
                    // 
                    // Will throw exception with validation errors
                    CheckSchemaErrors(); 
                    return null;
                }

                CreateTrackPoints(pReader, profile); 

                CheckSchemaErrors(); 
            } 
            catch (Exception)
            { 
                profile = null;
                throw;
            }
            finally 
            {
                _vArgs = new List(); 
                _vex = false; 
                pReader.Close();
            } 

            return profile;
        }
 
        private void CheckSchemaErrors()
        { 
            // 
            // If the parsing hit an error->throw
            // Clients can check ValidationEventArgs to get 
            // all errors & warnings that were caught.
            if (_vex)
            {
                TrackingProfileDeserializationException tpde = new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationSchemaError); 
                if (null != _vArgs)
                { 
                    foreach (ValidationEventArgs arg in _vArgs) 
                        tpde.ValidationEventArgs.Add(arg);
                } 
                throw tpde;
            }
        }
 
        private void CreateTrackPoints(XmlReader reader, TrackingProfile profile)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == profile)
                throw new ArgumentNullException("profile");

            if (0 != string.Compare(reader.Name, "TrackPoints", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "TrackPoints.");
 
            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read())
            {
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal)) 
                            CreateActivityTrackPoint(reader, profile); 
                        else if (0 == string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal))
                            CreateUserTrackPoint(reader, profile); 
                        else if (0 == string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal))
                            CreateWorkflowTrackPoint(reader, profile);
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "TrackPoints", StringComparison.Ordinal))
                            return; 
                        break; 
                }
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "TrackPoints.");
        } 

        private void CreateActivityTrackPoint(XmlReader reader, TrackingProfile profile) 
        { 
            if (null == reader)
                throw new ArgumentNullException("reader"); 

            if (null == profile)
                throw new ArgumentNullException("profile");
 
            if (0 != string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ActivityTrackPoint."); 
 
            if (reader.IsEmptyElement)
                return; 

            ActivityTrackPoint point = new ActivityTrackPoint();

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal)) 
                            CreateAnnotations(reader, point.Annotations);
                        else if (0 == string.Compare(reader.Name, "MatchingLocations", StringComparison.Ordinal))
                            CreateActivityTrackingLocations(reader, point.MatchingLocations);
                        else if (0 == string.Compare(reader.Name, "ExcludedLocations", StringComparison.Ordinal)) 
                            CreateActivityTrackingLocations(reader, point.ExcludedLocations);
                        else if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal)) 
                            CreateExtracts(reader, point.Extracts); 
                        //
                        // Xsd validation will catch unknown elements 

                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal)) 
                        {
                            profile.ActivityTrackPoints.Add(point); 
                            return; 
                        }
                        break; 
                }
            }
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ActivityTrackPoint.");
        } 
 
        private void CreateActivityTrackingLocation(XmlReader reader, ActivityTrackingLocation location)
        { 
            if (null == reader)
                throw new ArgumentNullException("reader");

            if (null == location) 
                throw new ArgumentNullException("location");
 
            if (0 != string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ActivityTrackingLocation.");
 
            if (reader.IsEmptyElement)
                return;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "TypeName", StringComparison.Ordinal)) 
                        {
                            if (null != location.ActivityType)
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidType);
 
                            location.ActivityTypeName = reader.ReadString();
                        } 
                        else if (0 == string.Compare(reader.Name, "Type", StringComparison.Ordinal)) 
                        {
                            if (null != location.ActivityTypeName) 
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidType);

                            if (!reader.IsEmptyElement)
                            { 
                                //
                                // Schema validation will catch empty elements, just make sure 
                                // we don't pass GetType a null or empty string and continue. 
                                string type = reader.ReadString();
                                if ((null != type) && (type.Trim().Length > 0)) 
                                    location.ActivityType = Type.GetType(type, true);
                            }
                        }
                        else if (0 == string.Compare(reader.Name, "MatchDerivedTypes", StringComparison.Ordinal)) 
                            location.MatchDerivedTypes = reader.ReadElementContentAsBoolean();
                        else if (0 == string.Compare(reader.Name, "ExecutionStatusEvents", StringComparison.Ordinal)) 
                            CreateStatusEvents(reader, location.ExecutionStatusEvents); 
                        else if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            CreateConditions(reader, location.Conditions); 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal))
                        { 
                            //
                            // If we don't have a type or name create the Activity type to track all activities 
                            if ((null == location.ActivityType) && (null == location.ActivityTypeName)) 
                            {
                                location.ActivityType = typeof(Activity); 
                                location.MatchDerivedTypes = true;
                            }

                            return; 
                        }
                        break; 
                } 
            }
            // 
            // Something bad happened
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ActivityTrackingLocation.");
        }
 
        private void CreateUserTrackPoint(XmlReader reader, TrackingProfile profile)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == profile)
                throw new ArgumentNullException("profile");

            if (0 != string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "UserTrackPoint.");
 
            if (reader.IsEmptyElement) 
                return;
 
            UserTrackPoint point = new UserTrackPoint();

            while (reader.Read())
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, point.Annotations); 
                        else if (0 == string.Compare(reader.Name, "MatchingLocations", StringComparison.Ordinal))
                            CreateUserTrackingLocations(reader, point.MatchingLocations);
                        else if (0 == string.Compare(reader.Name, "ExcludedLocations", StringComparison.Ordinal))
                            CreateUserTrackingLocations(reader, point.ExcludedLocations); 
                        else if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal))
                            CreateExtracts(reader, point.Extracts); 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal))
                        { 
                            profile.UserTrackPoints.Add(point);
                            return; 
                        } 
                        break;
                } 
            }
            //
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "UserTrackPoint."); 
        }
 
        private void CreateUserTrackingLocation(XmlReader reader, UserTrackingLocation location) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == location)
                throw new ArgumentNullException("location"); 

            if (0 != string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "UserTrackingLocation."); 

            if (reader.IsEmptyElement) 
                return;

            string name = null, type = null;
            bool derived = false, seenAct = false, seenArg = false; 

            while (reader.Read()) 
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Activity", StringComparison.Ordinal))
                            seenAct = true;
                        else if (0 == string.Compare(reader.Name, "KeyName", StringComparison.Ordinal)) 
                            location.KeyName = reader.ReadString();
                        else if (0 == string.Compare(reader.Name, "Argument", StringComparison.Ordinal)) 
                            seenArg = true; 
                        else if (0 == string.Compare(reader.Name, "TypeName", StringComparison.Ordinal))
                            name = reader.ReadString(); 
                        else if (0 == string.Compare(reader.Name, "Type", StringComparison.Ordinal))
                            type = reader.ReadString();
                        else if (0 == string.Compare(reader.Name, "MatchDerivedTypes", StringComparison.Ordinal))
                            derived = reader.ReadElementContentAsBoolean(); 
                        else if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            CreateConditions(reader, location.Conditions); 
                        break; 
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                        {
                            if (!seenAct)
                            {
                                location.ActivityType = typeof(Activity); 
                                location.MatchDerivedActivityTypes = true;
                            } 
 
                            if (!seenArg)
                            { 
                                location.ArgumentType = typeof(object);
                                location.MatchDerivedArgumentTypes = true;
                            }
 
                            if ((null == location.ActivityType) && ((null == location.ActivityTypeName) || (0 == location.ActivityTypeName.Trim().Length)) && (null == location.ArgumentType) && ((null == location.ArgumentTypeName) || (0 == location.ArgumentTypeName.Trim().Length)))
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.MissingActivityType); 
 
                            return;
                        } 
                        else if (0 == string.Compare(reader.Name, "Activity", StringComparison.Ordinal))
                        {
                            if (!seenAct)
                            { 
                                location.ActivityType = typeof(Activity);
                                location.MatchDerivedActivityTypes = true; 
                            } 
                            else
                            { 
                                if ((null != type) && (type.Trim().Length > 0))
                                    location.ActivityType = Type.GetType(type, true);
                                else
                                    location.ActivityTypeName = name; 

                                location.MatchDerivedActivityTypes = derived; 
                            } 

                            name = null; 
                            type = null;
                            derived = false;
                        }
                        else if (0 == string.Compare(reader.Name, "Argument", StringComparison.Ordinal)) 
                        {
                            if (!seenArg) 
                            { 
                                location.ArgumentType = typeof(object);
                                location.MatchDerivedArgumentTypes = true; 
                            }
                            else
                            {
                                if ((null != type) && (type.Trim().Length > 0)) 
                                    location.ArgumentType = Type.GetType(type, true);
                                else 
                                    location.ArgumentTypeName = name; 

                                location.MatchDerivedArgumentTypes = derived; 
                            }

                            name = null;
                            type = null; 
                            derived = false;
                        } 
 
                        break;
                } 
            }
            //
            // Something bad happened
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "UserTrackingLocation."); 
        }
 
        private void CreateWorkflowTrackPoint(XmlReader reader, TrackingProfile profile) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == profile)
                throw new ArgumentNullException("profile"); 

            if (0 != string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "WorkflowTrackPoint."); 

            if (reader.IsEmptyElement) 
                return;

            WorkflowTrackPoint point = new WorkflowTrackPoint();
            point.MatchingLocation = new WorkflowTrackingLocation(); 

            while (reader.Read()) 
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, point.Annotations);
                        else if (0 == string.Compare(reader.Name, "TrackingWorkflowEvent", StringComparison.Ordinal)) 
                            point.MatchingLocation.Events.Add((TrackingWorkflowEvent)Enum.Parse(typeof(TrackingWorkflowEvent), reader.ReadString()));
                        // 
                        // Xsd validation will catch unknown elements 
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal))
                        {
                            profile.WorkflowTrackPoints.Add(point);
                            return; 
                        }
                        break; 
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "WorkflowTrackPoint.");
        }
 
        private void CreateStatusEvents(XmlReader reader, IList events)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == events)
                throw new ArgumentNullException("events");

            if (0 != string.Compare("ExecutionStatusEvents", reader.Name, StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ExecutionStatusEvents.");
 
            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read())
            {
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ExecutionStatus", StringComparison.Ordinal)) 
                        { 
                            string status = reader.ReadString();
                            if ((null != status) && (status.Trim().Length > 0)) 
                            {
                                string[] names = Enum.GetNames(typeof(ActivityExecutionStatus));
                                foreach (string s in names)
                                { 
                                    if (0 == string.Compare(s, status, StringComparison.Ordinal))
                                        events.Add((ActivityExecutionStatus)Enum.Parse(typeof(ActivityExecutionStatus), status)); 
                                } 
                            }
                        } 
                        //
                        // Xsd validation will catch unknown elements

                        break; 
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ExecutionStatusEvents", StringComparison.Ordinal)) 
                            return; 
                        break;
                } 
            }
            //
            // Something is funky
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ExecutionStatusEvents."); 
        }
 
        private void CreateConditions(XmlReader reader, TrackingConditionCollection conditions) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == conditions)
                throw new ArgumentNullException("conditions"); 

            if (0 != string.Compare("Conditions", reader.Name, StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Conditions."); 

            if (reader.IsEmptyElement) 
                return;

            while (reader.Read())
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "ActivityTrackingCondition", StringComparison.Ordinal))
                        { 
                            ActivityTrackingCondition condition = new ActivityTrackingCondition();
                            CreateCondition(reader, condition);
                            conditions.Add(condition);
                        } 
                        //
                        // Xsd validation will catch unknown elements 
 
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            return;
                        break;
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Conditions.");
        } 

        private void CreateCondition(XmlReader reader, TrackingCondition condition)
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == condition) 
                throw new ArgumentNullException("condition");
 
            if (0 != string.Compare(condition.GetType().Name, reader.Name, StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + condition.GetType().Name);

            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                {
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Member", StringComparison.Ordinal))
                        { 
                            condition.Member = reader.ReadString();
                        } 
                        else if (0 == string.Compare(reader.Name, "Operator", StringComparison.Ordinal)) 
                        {
                            string op = reader.ReadString(); 
                            if ((null != op) && (op.Trim().Length > 0))
                            {
                                string[] names = Enum.GetNames(typeof(ComparisonOperator));
                                foreach (string s in names) 
                                {
                                    if (0 == string.Compare(s, op, StringComparison.Ordinal)) 
                                        condition.Operator = (ComparisonOperator)Enum.Parse(typeof(ComparisonOperator), op); 
                                }
                            } 
                        }
                        else if (0 == string.Compare(reader.Name, "Value", StringComparison.Ordinal))
                        {
                            if (!reader.IsEmptyElement) 
                                condition.Value = reader.ReadString();
                        } 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, condition.GetType().Name, StringComparison.Ordinal))
                            return; 
                        break;
                } 
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + condition.GetType().Name);
        }

        private void CreateExtracts(XmlReader reader, ExtractCollection extracts) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader"); 

            if (null == extracts) 
                throw new ArgumentNullException("extracts");

            if (0 != string.Compare("Extracts", reader.Name, StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Extracts"); 

            if (reader.IsEmptyElement) 
                return; 

            while (reader.Read()) 
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "ActivityDataTrackingExtract", StringComparison.Ordinal))
                        { 
                            ActivityDataTrackingExtract e = new ActivityDataTrackingExtract(); 
                            CreateExtract(reader, e);
                            extracts.Add(e); 
                        }
                        else if (0 == string.Compare(reader.Name, "WorkflowDataTrackingExtract", StringComparison.Ordinal))
                        {
                            WorkflowDataTrackingExtract e = new WorkflowDataTrackingExtract(); 
                            CreateExtract(reader, e);
                            extracts.Add(e); 
                        } 
                        //
                        // Xsd validation will catch unknown elements 

                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal)) 
                            return;
                        break; 
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Extracts.");
        }
 
        private void CreateExtract(XmlReader reader, TrackingExtract extract)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == extract)
                throw new ArgumentNullException("extract");

            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                {
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Member", StringComparison.Ordinal))
                            extract.Member = reader.ReadString(); 
                        else if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, extract.Annotations); 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, extract.GetType().Name, StringComparison.Ordinal))
                            return; 
                        break;
                } 
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + extract.GetType().Name);
        }

        private void CreateAnnotations(XmlReader reader, TrackingAnnotationCollection annotations) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader"); 

            if (null == annotations) 
                throw new ArgumentNullException("annotations");

            if (0 != string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Annotations."); 

            if (reader.IsEmptyElement) 
                return; 

            while (reader.Read()) 
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "Annotation", StringComparison.Ordinal))
                        { 
                            // 
                            // Preserve null and empty as distinct values
                            // null ==  empty string =  
                            if (!reader.IsEmptyElement)
                                annotations.Add(reader.ReadString());
                            else
                                annotations.Add(null); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Annotations."); 
        } 

        private void CreateActivityTrackingLocations(XmlReader reader, ActivityTrackingLocationCollection activities) 
        {
            if (null == reader)
                throw new ArgumentNullException("reader");
 
            if (null == activities)
                throw new ArgumentNullException("activities"); 
 
            if (reader.IsEmptyElement)
                return; 

            string startName = reader.Name;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal)) 
                        {
                            ActivityTrackingLocation location = new ActivityTrackingLocation();
                            CreateActivityTrackingLocation(reader, location);
                            activities.Add(location); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(startName, reader.Name, StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + startName + "."); 
        } 

        private void CreateUserTrackingLocations(XmlReader reader, UserTrackingLocationCollection user) 
        {
            if (null == reader)
                throw new ArgumentNullException("reader");
 
            if (null == user)
                throw new ArgumentNullException("user"); 
 
            if (reader.IsEmptyElement)
                return; 

            string startName = reader.Name;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                        {
                            UserTrackingLocation location = new UserTrackingLocation();
                            CreateUserTrackingLocation(reader, location);
                            user.Add(location); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(startName, reader.Name, StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + startName + "."); 
        } 

        private XmlReaderSettings GetSchemaReaderSettings() 
        {
            XmlReaderSettings profileSettings = new XmlReaderSettings();

            profileSettings.Schemas.Add(_schema); 
            profileSettings.ValidationType = ValidationType.Schema;
            profileSettings.ConformanceLevel = ConformanceLevel.Document; 
            profileSettings.CloseInput = false; 
            profileSettings.IgnoreComments = true;
            profileSettings.IgnoreProcessingInstructions = true; 
            profileSettings.DtdProcessing = DtdProcessing.Prohibit;
            profileSettings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            return profileSettings; 
        }
 
        private void ValidationCallBack(object sender, ValidationEventArgs e) 
        {
            _vArgs.Add(e); 

            if (e.Severity == XmlSeverityType.Error)
                _vex = true;
        } 

        #endregion 
 
        #region Serialization
 
        /// 
        /// Xml serialize a TrackingProfile.
        /// 
        /// TrackingProfile to serialize. 
        /// TextWriter to store xml text.
        public void Serialize(TextWriter writer, TrackingProfile profile) 
        { 
            if (null == profile)
                throw new ArgumentNullException("profile"); 

            if (null == writer)
                throw new ArgumentNullException("writer");
 
            XmlTextWriter xmlWriter = new XmlTextWriter(writer);
 
            InitWriter(xmlWriter); 

            Write(profile, xmlWriter); 

            xmlWriter.Flush();
            xmlWriter.Close();
        } 

        private void Write(TrackingProfile profile, XmlTextWriter writer) 
        { 
            writer.WriteStartDocument(true);
 
            writer.WriteStartElement("TrackingProfile");
            // Write the namespace declaration.
            writer.WriteAttributeString("xmlns", _ns);
 
            if (null == profile.Version)
                throw new ArgumentException(ExecutionStringManager.InvalidProfileVersion); 
 
            string version = null;
            if (profile.Version.Revision >= 0) 
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}.{2}.{3}", profile.Version.Major, profile.Version.Minor, profile.Version.Build, profile.Version.Revision);
            else if (profile.Version.Build >= 0)
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}.{2}", profile.Version.Major, profile.Version.Minor, profile.Version.Build);
            else if (profile.Version.Minor >= 0) 
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}", profile.Version.Major, profile.Version.Minor);
 
            writer.WriteAttributeString("version", version); 
            WriteTrackPoints(profile, writer);
 
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
 
        #region TrackPoints
 
        private void WriteTrackPoints(TrackingProfile profile, XmlTextWriter writer) 
        {
            // 
            // We must have at least 1 trackpoint or the profile won't be valid
            if (((null == profile.WorkflowTrackPoints) || (0 == profile.WorkflowTrackPoints.Count))
                && ((null == profile.ActivityTrackPoints) || (0 == profile.ActivityTrackPoints.Count))
                && ((null == profile.UserTrackPoints) || (0 == profile.UserTrackPoints.Count))) 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationNoTrackPoints);
 
            int count = 0; 

            writer.WriteStartElement("TrackPoints"); 

            foreach (WorkflowTrackPoint point in profile.WorkflowTrackPoints)
            {
                if (null != point) 
                {
                    WriteWorkflowTrackPoint(point, writer); 
                    count++; 
                }
            } 

            foreach (ActivityTrackPoint point in profile.ActivityTrackPoints)
            {
                if (null != point) 
                {
                    WriteActivityTrackPoint(point, writer); 
                    count++; 
                }
            } 

            foreach (UserTrackPoint point in profile.UserTrackPoints)
            {
                if (null != point) 
                {
                    WriteUserTrackPoint(point, writer); 
                    count++; 
                }
            } 

            //
            // We must have at least 1 trackpoint or the profile isn't valid
            if (0 == count) 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationNoTrackPoints);
 
            writer.WriteEndElement(); 
        }
 
        private void WriteActivityTrackPoint(ActivityTrackPoint point, XmlTextWriter writer)
        {
            if (null == point)
                throw new ArgumentNullException("point"); 
            //
            // Validate this element's required fields 
            if ((null == point.MatchingLocations) || (0 == point.MatchingLocations.Count)) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations);
 
            writer.WriteStartElement("ActivityTrackPoint");

            writer.WriteStartElement("MatchingLocations");
            // 
            // Write the locations that should be matched
            // At least one non null location is required. 
            int count = 0; 
            foreach (ActivityTrackingLocation location in point.MatchingLocations)
            { 
                if (null != location)
                {
                    WriteActivityTrackingLocation(location, writer);
                    count++; 
                }
            } 
 
            if (0 == count)
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations); 

            writer.WriteEndElement();
            //
            // Write the locations that should not be matched (these override the locations to match) 
            // Excludes are not required.
            if ((null != point.ExcludedLocations) && (point.ExcludedLocations.Count > 0)) 
            { 
                writer.WriteStartElement("ExcludedLocations");
 
                foreach (ActivityTrackingLocation location in point.ExcludedLocations)
                {
                    if (null != location)
                        WriteActivityTrackingLocation(location, writer); 
                }
 
                writer.WriteEndElement(); 
            }
            // 
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer);
            //
            // Write extracts, not a required field 
            WriteExtracts(point.Extracts, writer);
 
            writer.WriteEndElement(); 
        }
 
        private void WriteWorkflowTrackPoint(WorkflowTrackPoint point, XmlTextWriter writer)
        {
            //
            // Validate this element's required fields 
            if (null == point.MatchingLocation)
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocation); 
 
            writer.WriteStartElement("WorkflowTrackPoint");
 
            WriteWorkflowTrackingLocation(point.MatchingLocation, writer);
            //
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer); 

            writer.WriteEndElement(); 
        } 

        private void WriteUserTrackPoint(UserTrackPoint point, XmlTextWriter writer) 
        {
            //
            // Validate this element's required fields
            if ((null == point.MatchingLocations) || (0 == point.MatchingLocations.Count)) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations);
 
            writer.WriteStartElement("UserTrackPoint"); 

            writer.WriteStartElement("MatchingLocations"); 

            //
            // Write the locations that should be matched
            // At least one non null location is required. 
            int count = 0;
            foreach (UserTrackingLocation location in point.MatchingLocations) 
            { 
                if (null != location)
                { 
                    WriteUserTrackingLocation(location, writer);
                    count++;
                }
            } 

            if (0 == count) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations); 

            writer.WriteEndElement(); 

            //
            // Write the locations that should not be matched (these override the locations to match)
            // Excludes are not required. 
            if ((null != point.ExcludedLocations) && (point.ExcludedLocations.Count > 0))
            { 
                writer.WriteStartElement("ExcludedLocations"); 

                foreach (UserTrackingLocation location in point.ExcludedLocations) 
                {
                    if (null != location)
                        WriteUserTrackingLocation(location, writer);
                } 

                writer.WriteEndElement(); 
            } 

            // 
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer);
            //
            // Write extracts, not a required field 
            WriteExtracts(point.Extracts, writer);
 
            writer.WriteEndElement(); 
        }
 
        #endregion

        #region Location
 
        private void WriteActivityTrackingLocation(ActivityTrackingLocation loc, XmlTextWriter writer)
        { 
            // 
            // Validate this element's required fields
            if ((null == loc.ActivityType) && ((null == loc.ActivityTypeName) || (0 == loc.ActivityTypeName.Trim().Length))) 
                throw new ArgumentException(ExecutionStringManager.MissingActivityType);

            writer.WriteStartElement("ActivityTrackingLocation");
 
            writer.WriteStartElement("Activity");
 
            if (null != loc.ActivityType) 
                writer.WriteElementString("Type", loc.ActivityType.AssemblyQualifiedName);
            else 
                writer.WriteElementString("TypeName", loc.ActivityTypeName);

            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 

            WriteEvents(loc.ExecutionStatusEvents, writer); 
 
            if ((null != loc.Conditions) && (loc.Conditions.Count > 0))
                WriteConditions(loc.Conditions, writer); 


            writer.WriteEndElement();
        } 

        private void WriteUserTrackingLocation(UserTrackingLocation loc, XmlTextWriter writer) 
        { 
            //
            // Validate this element's required fields 
            if ((null == loc.ActivityType) && ((null == loc.ActivityTypeName) || (0 == loc.ActivityTypeName.Trim().Length)))
                throw new ArgumentException(ExecutionStringManager.MissingActivityType);

            if ((null == loc.ArgumentType) && ((null == loc.ArgumentTypeName) || (0 == loc.ArgumentTypeName.Trim().Length))) 
                throw new ArgumentException(ExecutionStringManager.MissingArgumentType);
 
            writer.WriteStartElement("UserTrackingLocation"); 
            //
            // Write the Acctivity node 
            writer.WriteStartElement("Activity");

            if (null != loc.ActivityType)
                writer.WriteElementString("Type", loc.ActivityType.AssemblyQualifiedName); 
            else
                writer.WriteElementString("TypeName", loc.ActivityTypeName); 
 
            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedActivityTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 
            //
            // Write the key name node if it is non null
            if (null != loc.KeyName)
                writer.WriteElementString("KeyName", loc.KeyName); 
            //
            // Write the Argument node 
            writer.WriteStartElement("Argument"); 

            if (null != loc.ArgumentType) 
                writer.WriteElementString("Type", loc.ArgumentType.AssemblyQualifiedName);
            else
                writer.WriteElementString("TypeName", loc.ArgumentTypeName);
 
            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedArgumentTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 
 
            if ((null != loc.Conditions) && (loc.Conditions.Count > 0))
                WriteConditions(loc.Conditions, writer); 

            writer.WriteEndElement();
        }
 
        private void WriteWorkflowTrackingLocation(WorkflowTrackingLocation loc, XmlTextWriter writer)
        { 
            if ((null == loc.Events) || (0 == loc.Events.Count)) 
                throw new ArgumentException(ExecutionStringManager.MissingWorkflowEvents);
 
            writer.WriteStartElement("MatchingLocation");

            writer.WriteStartElement("WorkflowTrackingLocation");
 
            WriteWorkflowEvents(loc.Events, writer);
 
            writer.WriteEndElement(); 

            writer.WriteEndElement(); 
        }

        #endregion
 
        #region TrackingExtract
 
        private void WriteExtracts(ExtractCollection extracts, XmlTextWriter writer) 
        {
            if ((null == extracts) || (0 == extracts.Count)) 
                return;

            writer.WriteStartElement("Extracts");
 
            foreach (TrackingExtract e in extracts)
            { 
                if (null != e) 
                    WriteExtract(e, writer);
            } 

            writer.WriteEndElement();
        }
 
        private void WriteExtract(TrackingExtract extract, XmlTextWriter writer)
        { 
            Type t = extract.GetType(); 

            if ((extract is ActivityDataTrackingExtract) || (extract is WorkflowDataTrackingExtract)) 
            {
                writer.WriteStartElement(extract.GetType().Name);
                writer.WriteElementString("Member", (null == extract.Member ? string.Empty : extract.Member));
 
                WriteAnnotations(extract.Annotations, writer);
 
                writer.WriteEndElement(); 
            }
            else 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationInvalidExtract);
        }

        #endregion 

        #region Shared 
 
        private void WriteConditions(TrackingConditionCollection conditions, XmlTextWriter writer)
        { 
            if ((null == conditions) || (0 == conditions.Count))
                return;

            writer.WriteStartElement("Conditions"); 

            foreach (TrackingCondition c in conditions) 
            { 
                if (null != c)
                    WriteCondition(c, writer); 
            }

            writer.WriteEndElement();
        } 

        private void WriteCondition(TrackingCondition condition, XmlTextWriter writer) 
        { 
            if (null == condition)
                return; 

            writer.WriteStartElement(condition.GetType().Name);

            writer.WriteElementString("Operator", condition.Operator.ToString()); 

            if ((null == condition.Member) || (0 == condition.Member.Trim().Length)) 
                throw new ArgumentException(ExecutionStringManager.MissingMemberName); 

            writer.WriteElementString("Member", condition.Member); 

            if (null != condition.Value)
            {
                if (string.Empty == condition.Value) 
                {
                    writer.WriteStartElement("Value"); 
                    writer.WriteRaw(string.Empty); 
                    writer.WriteEndElement();
                } 
                else
                    writer.WriteElementString("Value", condition.Value);
            }
 
            writer.WriteEndElement();
        } 
 
        private void WriteAnnotations(TrackingAnnotationCollection annotations, XmlTextWriter writer)
        { 
            if ((null == annotations) || (0 == annotations.Count))
                return;

            writer.WriteStartElement("Annotations"); 
            foreach (string s in annotations)
            { 
                // 
                // Preserve null and empty as distinct values
                // null ==  empty string =  
                writer.WriteStartElement("Annotation");
                if ((null == s) || (s.Length > 0))
                {
                    writer.WriteValue(null == s ? String.Empty : s); 
                    writer.WriteEndElement();
                } 
                else 
                    writer.WriteFullEndElement();
            } 
            writer.WriteEndElement();
        }

        private void WriteEvents(IList events, XmlTextWriter writer) 
        {
            if ((null == events) || (0 == events.Count)) 
                throw new ArgumentException(ExecutionStringManager.MissingActivityEvents); 

            writer.WriteStartElement("ExecutionStatusEvents"); 

            foreach (ActivityExecutionStatus s in events)
            {
                if (!IsStatus((int)s)) 
                    throw new ArgumentException(ExecutionStringManager.InvalidStatus);
 
                writer.WriteStartElement("ExecutionStatus"); 
                writer.WriteValue(s.ToString());
                writer.WriteEndElement(); 
            }

            writer.WriteEndElement();
        } 

        private bool IsStatus(int val) 
        { 
            foreach (ActivityExecutionStatus s in Enum.GetValues(typeof(ActivityExecutionStatus)))
            { 
                if ((int)s == val)
                    return true;
            }
            return false; 
        }
 
        private void WriteWorkflowEvents(IList events, XmlTextWriter writer) 
        {
            if ((null == events) || (0 == events.Count)) 
                return;

            writer.WriteStartElement("TrackingWorkflowEvents");
 
            foreach (TrackingWorkflowEvent s in events)
            { 
                if (!IsWorkflowEvent((int)s)) 
                    throw new ArgumentException(ExecutionStringManager.InvalidWorkflowEvent);
 
                writer.WriteStartElement("TrackingWorkflowEvent");
                writer.WriteValue(s.ToString());
                writer.WriteEndElement();
            } 

            writer.WriteEndElement(); 
        } 

        private bool IsWorkflowEvent(int val) 
        {
            foreach (TrackingWorkflowEvent s in Enum.GetValues(typeof(TrackingWorkflowEvent)))
            {
                if ((int)s == val) 
                    return true;
            } 
            return false; 
        }
 
        #endregion

        private void InitWriter(XmlTextWriter writer)
        { 
            writer.Formatting = Formatting.Indented;
            writer.Indentation = 4; 
        } 

        #endregion 

        #region Schema

        private const string _ns = "http://schemas.microsoft.com/winfx/2006/workflow/trackingprofile"; 
        private XmlSchema _schema = null;
 
        internal const string _xsd = @" 

     

    
        
             
        
         
     

     
        
            
                
                 
                
             
         
    
 
    
        
            
             
            
             
         
    
 
    
        
            
         
    
 
     
        
             
        
    

     
        
             
             
            
         
    

    
         
            
             
             
            
         
    

    
         
            
         
     

     
        
            
        
     

     
         
            
             
            
            
        
     

     
         
            
             
        
    

     
        
             
         
    
 
    
        
            
         
    
 
     
        
             
                
                
            
             
        
     
 
    
         
            
        
    
 
    
         
             
        
     

    
        
             
            
             
         
    
 
    
        
            
             
        
     
 
    
         
            
        
    
 
    
         
             
            
             
            
            
            
         
    
 
     
        
             
        
    

     
        
             
             
            
             
            
            
            
             
            
             
             
            
             
        
    

     
        
             
             
        
     

    
        
             
            
         
     

     
        
            
            
         
    
 
     
        
             
        
    

     
        
             
         
    
"; 
        #endregion Schema
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text; 
using System.Xml;
using System.Xml.Schema; 
using System.IO; 
using System.Reflection;
using System.Diagnostics; 
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Globalization;
 
//using System.Workflow.Activities;
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime; 
using System.Workflow.Runtime.Hosting;
using Hosting = System.Workflow.Runtime.Hosting; 

namespace System.Workflow.Runtime.Tracking
{
    ///  
    /// Used for xml serializing a TrackProfile.
    ///  
    public class TrackingProfileSerializer 
    {
        public TrackingProfileSerializer() 
        {
            _schema = XmlSchema.Read(new StringReader(_xsd), null);
            _schema.Namespaces.Add("", _ns);
        } 

        public XmlSchema Schema 
        { 
            get
            { 
                return _schema;
            }
        }
 
        #region Deserialization
 
        List _vArgs = new List(); 
        bool _vex = false;
        ///  
        /// Deserialize TrackingProfile in xml form to a TrackingProfile object.
        /// 
        /// TextReader containing TrackingProfile in xml form
        /// TrackingProfile 
        /// XmlSchemaException
        /// XmlException 
        /// ArgumentNullException 
        /// ArgumentException
        /// ArgumentOutOfRangeException 
        /// FormatException
        /// OverflowException
        /// InvalidOperationException
        /// TrackingProfileDeserializationException 
        public TrackingProfile Deserialize(TextReader reader)
        { 
            TrackingProfile profile = null; 
            _vArgs = new List();
            _vex = false; 

            if (null == reader)
                throw new ArgumentNullException("reader");
 
            //
            // Specify that if no namespace is declare the default should be interpreted as ours 
            NameTable nt = new NameTable(); 
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
            nsmgr.AddNamespace(String.Empty, _ns); 
            XmlParserContext ctx = new XmlParserContext(nt, nsmgr, null, XmlSpace.None);
            XmlReader pReader = XmlReader.Create(reader, GetSchemaReaderSettings(), ctx);

            try 
            {
                profile = new TrackingProfile(); 
                // 
                // Schema validation will catch if element is missing
                if (!pReader.ReadToDescendant("TrackingProfile")) 
                {
                    //
                    // Will throw exception with validation errors
                    CheckSchemaErrors(); 
                    return null;
                } 
 
                string version = pReader.GetAttribute("version");
                if ((null == version) || (0 == version.Trim().Length)) 
                    throw new TrackingProfileDeserializationException(ExecutionStringManager.InvalidProfileVersion);

                profile.Version = new Version(version);
 
                if (!pReader.ReadToDescendant("TrackPoints"))
                { 
                    // 
                    // Will throw exception with validation errors
                    CheckSchemaErrors(); 
                    return null;
                }

                CreateTrackPoints(pReader, profile); 

                CheckSchemaErrors(); 
            } 
            catch (Exception)
            { 
                profile = null;
                throw;
            }
            finally 
            {
                _vArgs = new List(); 
                _vex = false; 
                pReader.Close();
            } 

            return profile;
        }
 
        private void CheckSchemaErrors()
        { 
            // 
            // If the parsing hit an error->throw
            // Clients can check ValidationEventArgs to get 
            // all errors & warnings that were caught.
            if (_vex)
            {
                TrackingProfileDeserializationException tpde = new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationSchemaError); 
                if (null != _vArgs)
                { 
                    foreach (ValidationEventArgs arg in _vArgs) 
                        tpde.ValidationEventArgs.Add(arg);
                } 
                throw tpde;
            }
        }
 
        private void CreateTrackPoints(XmlReader reader, TrackingProfile profile)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == profile)
                throw new ArgumentNullException("profile");

            if (0 != string.Compare(reader.Name, "TrackPoints", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "TrackPoints.");
 
            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read())
            {
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal)) 
                            CreateActivityTrackPoint(reader, profile); 
                        else if (0 == string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal))
                            CreateUserTrackPoint(reader, profile); 
                        else if (0 == string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal))
                            CreateWorkflowTrackPoint(reader, profile);
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "TrackPoints", StringComparison.Ordinal))
                            return; 
                        break; 
                }
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "TrackPoints.");
        } 

        private void CreateActivityTrackPoint(XmlReader reader, TrackingProfile profile) 
        { 
            if (null == reader)
                throw new ArgumentNullException("reader"); 

            if (null == profile)
                throw new ArgumentNullException("profile");
 
            if (0 != string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ActivityTrackPoint."); 
 
            if (reader.IsEmptyElement)
                return; 

            ActivityTrackPoint point = new ActivityTrackPoint();

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal)) 
                            CreateAnnotations(reader, point.Annotations);
                        else if (0 == string.Compare(reader.Name, "MatchingLocations", StringComparison.Ordinal))
                            CreateActivityTrackingLocations(reader, point.MatchingLocations);
                        else if (0 == string.Compare(reader.Name, "ExcludedLocations", StringComparison.Ordinal)) 
                            CreateActivityTrackingLocations(reader, point.ExcludedLocations);
                        else if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal)) 
                            CreateExtracts(reader, point.Extracts); 
                        //
                        // Xsd validation will catch unknown elements 

                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ActivityTrackPoint", StringComparison.Ordinal)) 
                        {
                            profile.ActivityTrackPoints.Add(point); 
                            return; 
                        }
                        break; 
                }
            }
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ActivityTrackPoint.");
        } 
 
        private void CreateActivityTrackingLocation(XmlReader reader, ActivityTrackingLocation location)
        { 
            if (null == reader)
                throw new ArgumentNullException("reader");

            if (null == location) 
                throw new ArgumentNullException("location");
 
            if (0 != string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ActivityTrackingLocation.");
 
            if (reader.IsEmptyElement)
                return;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "TypeName", StringComparison.Ordinal)) 
                        {
                            if (null != location.ActivityType)
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidType);
 
                            location.ActivityTypeName = reader.ReadString();
                        } 
                        else if (0 == string.Compare(reader.Name, "Type", StringComparison.Ordinal)) 
                        {
                            if (null != location.ActivityTypeName) 
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidType);

                            if (!reader.IsEmptyElement)
                            { 
                                //
                                // Schema validation will catch empty elements, just make sure 
                                // we don't pass GetType a null or empty string and continue. 
                                string type = reader.ReadString();
                                if ((null != type) && (type.Trim().Length > 0)) 
                                    location.ActivityType = Type.GetType(type, true);
                            }
                        }
                        else if (0 == string.Compare(reader.Name, "MatchDerivedTypes", StringComparison.Ordinal)) 
                            location.MatchDerivedTypes = reader.ReadElementContentAsBoolean();
                        else if (0 == string.Compare(reader.Name, "ExecutionStatusEvents", StringComparison.Ordinal)) 
                            CreateStatusEvents(reader, location.ExecutionStatusEvents); 
                        else if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            CreateConditions(reader, location.Conditions); 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal))
                        { 
                            //
                            // If we don't have a type or name create the Activity type to track all activities 
                            if ((null == location.ActivityType) && (null == location.ActivityTypeName)) 
                            {
                                location.ActivityType = typeof(Activity); 
                                location.MatchDerivedTypes = true;
                            }

                            return; 
                        }
                        break; 
                } 
            }
            // 
            // Something bad happened
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ActivityTrackingLocation.");
        }
 
        private void CreateUserTrackPoint(XmlReader reader, TrackingProfile profile)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == profile)
                throw new ArgumentNullException("profile");

            if (0 != string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "UserTrackPoint.");
 
            if (reader.IsEmptyElement) 
                return;
 
            UserTrackPoint point = new UserTrackPoint();

            while (reader.Read())
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, point.Annotations); 
                        else if (0 == string.Compare(reader.Name, "MatchingLocations", StringComparison.Ordinal))
                            CreateUserTrackingLocations(reader, point.MatchingLocations);
                        else if (0 == string.Compare(reader.Name, "ExcludedLocations", StringComparison.Ordinal))
                            CreateUserTrackingLocations(reader, point.ExcludedLocations); 
                        else if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal))
                            CreateExtracts(reader, point.Extracts); 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "UserTrackPoint", StringComparison.Ordinal))
                        { 
                            profile.UserTrackPoints.Add(point);
                            return; 
                        } 
                        break;
                } 
            }
            //
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "UserTrackPoint."); 
        }
 
        private void CreateUserTrackingLocation(XmlReader reader, UserTrackingLocation location) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == location)
                throw new ArgumentNullException("location"); 

            if (0 != string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "UserTrackingLocation."); 

            if (reader.IsEmptyElement) 
                return;

            string name = null, type = null;
            bool derived = false, seenAct = false, seenArg = false; 

            while (reader.Read()) 
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Activity", StringComparison.Ordinal))
                            seenAct = true;
                        else if (0 == string.Compare(reader.Name, "KeyName", StringComparison.Ordinal)) 
                            location.KeyName = reader.ReadString();
                        else if (0 == string.Compare(reader.Name, "Argument", StringComparison.Ordinal)) 
                            seenArg = true; 
                        else if (0 == string.Compare(reader.Name, "TypeName", StringComparison.Ordinal))
                            name = reader.ReadString(); 
                        else if (0 == string.Compare(reader.Name, "Type", StringComparison.Ordinal))
                            type = reader.ReadString();
                        else if (0 == string.Compare(reader.Name, "MatchDerivedTypes", StringComparison.Ordinal))
                            derived = reader.ReadElementContentAsBoolean(); 
                        else if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            CreateConditions(reader, location.Conditions); 
                        break; 
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                        {
                            if (!seenAct)
                            {
                                location.ActivityType = typeof(Activity); 
                                location.MatchDerivedActivityTypes = true;
                            } 
 
                            if (!seenArg)
                            { 
                                location.ArgumentType = typeof(object);
                                location.MatchDerivedArgumentTypes = true;
                            }
 
                            if ((null == location.ActivityType) && ((null == location.ActivityTypeName) || (0 == location.ActivityTypeName.Trim().Length)) && (null == location.ArgumentType) && ((null == location.ArgumentTypeName) || (0 == location.ArgumentTypeName.Trim().Length)))
                                throw new TrackingProfileDeserializationException(ExecutionStringManager.MissingActivityType); 
 
                            return;
                        } 
                        else if (0 == string.Compare(reader.Name, "Activity", StringComparison.Ordinal))
                        {
                            if (!seenAct)
                            { 
                                location.ActivityType = typeof(Activity);
                                location.MatchDerivedActivityTypes = true; 
                            } 
                            else
                            { 
                                if ((null != type) && (type.Trim().Length > 0))
                                    location.ActivityType = Type.GetType(type, true);
                                else
                                    location.ActivityTypeName = name; 

                                location.MatchDerivedActivityTypes = derived; 
                            } 

                            name = null; 
                            type = null;
                            derived = false;
                        }
                        else if (0 == string.Compare(reader.Name, "Argument", StringComparison.Ordinal)) 
                        {
                            if (!seenArg) 
                            { 
                                location.ArgumentType = typeof(object);
                                location.MatchDerivedArgumentTypes = true; 
                            }
                            else
                            {
                                if ((null != type) && (type.Trim().Length > 0)) 
                                    location.ArgumentType = Type.GetType(type, true);
                                else 
                                    location.ArgumentTypeName = name; 

                                location.MatchDerivedArgumentTypes = derived; 
                            }

                            name = null;
                            type = null; 
                            derived = false;
                        } 
 
                        break;
                } 
            }
            //
            // Something bad happened
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "UserTrackingLocation."); 
        }
 
        private void CreateWorkflowTrackPoint(XmlReader reader, TrackingProfile profile) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == profile)
                throw new ArgumentNullException("profile"); 

            if (0 != string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "WorkflowTrackPoint."); 

            if (reader.IsEmptyElement) 
                return;

            WorkflowTrackPoint point = new WorkflowTrackPoint();
            point.MatchingLocation = new WorkflowTrackingLocation(); 

            while (reader.Read()) 
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, point.Annotations);
                        else if (0 == string.Compare(reader.Name, "TrackingWorkflowEvent", StringComparison.Ordinal)) 
                            point.MatchingLocation.Events.Add((TrackingWorkflowEvent)Enum.Parse(typeof(TrackingWorkflowEvent), reader.ReadString()));
                        // 
                        // Xsd validation will catch unknown elements 
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "WorkflowTrackPoint", StringComparison.Ordinal))
                        {
                            profile.WorkflowTrackPoints.Add(point);
                            return; 
                        }
                        break; 
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "WorkflowTrackPoint.");
        }
 
        private void CreateStatusEvents(XmlReader reader, IList events)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == events)
                throw new ArgumentNullException("events");

            if (0 != string.Compare("ExecutionStatusEvents", reader.Name, StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "ExecutionStatusEvents.");
 
            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read())
            {
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ExecutionStatus", StringComparison.Ordinal)) 
                        { 
                            string status = reader.ReadString();
                            if ((null != status) && (status.Trim().Length > 0)) 
                            {
                                string[] names = Enum.GetNames(typeof(ActivityExecutionStatus));
                                foreach (string s in names)
                                { 
                                    if (0 == string.Compare(s, status, StringComparison.Ordinal))
                                        events.Add((ActivityExecutionStatus)Enum.Parse(typeof(ActivityExecutionStatus), status)); 
                                } 
                            }
                        } 
                        //
                        // Xsd validation will catch unknown elements

                        break; 
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "ExecutionStatusEvents", StringComparison.Ordinal)) 
                            return; 
                        break;
                } 
            }
            //
            // Something is funky
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "ExecutionStatusEvents."); 
        }
 
        private void CreateConditions(XmlReader reader, TrackingConditionCollection conditions) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");

            if (null == conditions)
                throw new ArgumentNullException("conditions"); 

            if (0 != string.Compare("Conditions", reader.Name, StringComparison.Ordinal)) 
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Conditions."); 

            if (reader.IsEmptyElement) 
                return;

            while (reader.Read())
            { 
                switch (reader.NodeType)
                { 
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "ActivityTrackingCondition", StringComparison.Ordinal))
                        { 
                            ActivityTrackingCondition condition = new ActivityTrackingCondition();
                            CreateCondition(reader, condition);
                            conditions.Add(condition);
                        } 
                        //
                        // Xsd validation will catch unknown elements 
 
                        break;
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "Conditions", StringComparison.Ordinal))
                            return;
                        break;
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Conditions.");
        } 

        private void CreateCondition(XmlReader reader, TrackingCondition condition)
        {
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == condition) 
                throw new ArgumentNullException("condition");
 
            if (0 != string.Compare(condition.GetType().Name, reader.Name, StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + condition.GetType().Name);

            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                {
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Member", StringComparison.Ordinal))
                        { 
                            condition.Member = reader.ReadString();
                        } 
                        else if (0 == string.Compare(reader.Name, "Operator", StringComparison.Ordinal)) 
                        {
                            string op = reader.ReadString(); 
                            if ((null != op) && (op.Trim().Length > 0))
                            {
                                string[] names = Enum.GetNames(typeof(ComparisonOperator));
                                foreach (string s in names) 
                                {
                                    if (0 == string.Compare(s, op, StringComparison.Ordinal)) 
                                        condition.Operator = (ComparisonOperator)Enum.Parse(typeof(ComparisonOperator), op); 
                                }
                            } 
                        }
                        else if (0 == string.Compare(reader.Name, "Value", StringComparison.Ordinal))
                        {
                            if (!reader.IsEmptyElement) 
                                condition.Value = reader.ReadString();
                        } 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, condition.GetType().Name, StringComparison.Ordinal))
                            return; 
                        break;
                } 
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + condition.GetType().Name);
        }

        private void CreateExtracts(XmlReader reader, ExtractCollection extracts) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader"); 

            if (null == extracts) 
                throw new ArgumentNullException("extracts");

            if (0 != string.Compare("Extracts", reader.Name, StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Extracts"); 

            if (reader.IsEmptyElement) 
                return; 

            while (reader.Read()) 
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "ActivityDataTrackingExtract", StringComparison.Ordinal))
                        { 
                            ActivityDataTrackingExtract e = new ActivityDataTrackingExtract(); 
                            CreateExtract(reader, e);
                            extracts.Add(e); 
                        }
                        else if (0 == string.Compare(reader.Name, "WorkflowDataTrackingExtract", StringComparison.Ordinal))
                        {
                            WorkflowDataTrackingExtract e = new WorkflowDataTrackingExtract(); 
                            CreateExtract(reader, e);
                            extracts.Add(e); 
                        } 
                        //
                        // Xsd validation will catch unknown elements 

                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, "Extracts", StringComparison.Ordinal)) 
                            return;
                        break; 
                } 
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Extracts.");
        }
 
        private void CreateExtract(XmlReader reader, TrackingExtract extract)
        { 
            if (null == reader) 
                throw new ArgumentNullException("reader");
 
            if (null == extract)
                throw new ArgumentNullException("extract");

            if (reader.IsEmptyElement) 
                return;
 
            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                {
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "Member", StringComparison.Ordinal))
                            extract.Member = reader.ReadString(); 
                        else if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            CreateAnnotations(reader, extract.Annotations); 
                        // 
                        // Xsd validation will catch unknown elements
 
                        break;
                    case XmlNodeType.EndElement:
                        if (0 == string.Compare(reader.Name, extract.GetType().Name, StringComparison.Ordinal))
                            return; 
                        break;
                } 
            } 
            //
            // Only valid exit is on an EndElement that matches the element that is passed in. 
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + extract.GetType().Name);
        }

        private void CreateAnnotations(XmlReader reader, TrackingAnnotationCollection annotations) 
        {
            if (null == reader) 
                throw new ArgumentNullException("reader"); 

            if (null == annotations) 
                throw new ArgumentNullException("annotations");

            if (0 != string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationInvalidPosition + "Annotations."); 

            if (reader.IsEmptyElement) 
                return; 

            while (reader.Read()) 
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element: 
                        if (0 == string.Compare(reader.Name, "Annotation", StringComparison.Ordinal))
                        { 
                            // 
                            // Preserve null and empty as distinct values
                            // null ==  empty string =  
                            if (!reader.IsEmptyElement)
                                annotations.Add(reader.ReadString());
                            else
                                annotations.Add(null); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(reader.Name, "Annotations", StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + "Annotations."); 
        } 

        private void CreateActivityTrackingLocations(XmlReader reader, ActivityTrackingLocationCollection activities) 
        {
            if (null == reader)
                throw new ArgumentNullException("reader");
 
            if (null == activities)
                throw new ArgumentNullException("activities"); 
 
            if (reader.IsEmptyElement)
                return; 

            string startName = reader.Name;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "ActivityTrackingLocation", StringComparison.Ordinal)) 
                        {
                            ActivityTrackingLocation location = new ActivityTrackingLocation();
                            CreateActivityTrackingLocation(reader, location);
                            activities.Add(location); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(startName, reader.Name, StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + startName + "."); 
        } 

        private void CreateUserTrackingLocations(XmlReader reader, UserTrackingLocationCollection user) 
        {
            if (null == reader)
                throw new ArgumentNullException("reader");
 
            if (null == user)
                throw new ArgumentNullException("user"); 
 
            if (reader.IsEmptyElement)
                return; 

            string startName = reader.Name;

            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                { 
                    case XmlNodeType.Element:
                        if (0 == string.Compare(reader.Name, "UserTrackingLocation", StringComparison.Ordinal)) 
                        {
                            UserTrackingLocation location = new UserTrackingLocation();
                            CreateUserTrackingLocation(reader, location);
                            user.Add(location); 
                        }
                        break; 
                    case XmlNodeType.EndElement: 
                        if (0 == string.Compare(startName, reader.Name, StringComparison.Ordinal))
                            return; 
                        break;
                }
            }
            // 
            // Only valid exit is on an EndElement that matches the element that is passed in.
            throw new TrackingProfileDeserializationException(ExecutionStringManager.TrackingDeserializationCloseElementNotFound + startName + "."); 
        } 

        private XmlReaderSettings GetSchemaReaderSettings() 
        {
            XmlReaderSettings profileSettings = new XmlReaderSettings();

            profileSettings.Schemas.Add(_schema); 
            profileSettings.ValidationType = ValidationType.Schema;
            profileSettings.ConformanceLevel = ConformanceLevel.Document; 
            profileSettings.CloseInput = false; 
            profileSettings.IgnoreComments = true;
            profileSettings.IgnoreProcessingInstructions = true; 
            profileSettings.DtdProcessing = DtdProcessing.Prohibit;
            profileSettings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            return profileSettings; 
        }
 
        private void ValidationCallBack(object sender, ValidationEventArgs e) 
        {
            _vArgs.Add(e); 

            if (e.Severity == XmlSeverityType.Error)
                _vex = true;
        } 

        #endregion 
 
        #region Serialization
 
        /// 
        /// Xml serialize a TrackingProfile.
        /// 
        /// TrackingProfile to serialize. 
        /// TextWriter to store xml text.
        public void Serialize(TextWriter writer, TrackingProfile profile) 
        { 
            if (null == profile)
                throw new ArgumentNullException("profile"); 

            if (null == writer)
                throw new ArgumentNullException("writer");
 
            XmlTextWriter xmlWriter = new XmlTextWriter(writer);
 
            InitWriter(xmlWriter); 

            Write(profile, xmlWriter); 

            xmlWriter.Flush();
            xmlWriter.Close();
        } 

        private void Write(TrackingProfile profile, XmlTextWriter writer) 
        { 
            writer.WriteStartDocument(true);
 
            writer.WriteStartElement("TrackingProfile");
            // Write the namespace declaration.
            writer.WriteAttributeString("xmlns", _ns);
 
            if (null == profile.Version)
                throw new ArgumentException(ExecutionStringManager.InvalidProfileVersion); 
 
            string version = null;
            if (profile.Version.Revision >= 0) 
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}.{2}.{3}", profile.Version.Major, profile.Version.Minor, profile.Version.Build, profile.Version.Revision);
            else if (profile.Version.Build >= 0)
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}.{2}", profile.Version.Major, profile.Version.Minor, profile.Version.Build);
            else if (profile.Version.Minor >= 0) 
                version = string.Format(NumberFormatInfo.InvariantInfo, "{0}.{1}", profile.Version.Major, profile.Version.Minor);
 
            writer.WriteAttributeString("version", version); 
            WriteTrackPoints(profile, writer);
 
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
 
        #region TrackPoints
 
        private void WriteTrackPoints(TrackingProfile profile, XmlTextWriter writer) 
        {
            // 
            // We must have at least 1 trackpoint or the profile won't be valid
            if (((null == profile.WorkflowTrackPoints) || (0 == profile.WorkflowTrackPoints.Count))
                && ((null == profile.ActivityTrackPoints) || (0 == profile.ActivityTrackPoints.Count))
                && ((null == profile.UserTrackPoints) || (0 == profile.UserTrackPoints.Count))) 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationNoTrackPoints);
 
            int count = 0; 

            writer.WriteStartElement("TrackPoints"); 

            foreach (WorkflowTrackPoint point in profile.WorkflowTrackPoints)
            {
                if (null != point) 
                {
                    WriteWorkflowTrackPoint(point, writer); 
                    count++; 
                }
            } 

            foreach (ActivityTrackPoint point in profile.ActivityTrackPoints)
            {
                if (null != point) 
                {
                    WriteActivityTrackPoint(point, writer); 
                    count++; 
                }
            } 

            foreach (UserTrackPoint point in profile.UserTrackPoints)
            {
                if (null != point) 
                {
                    WriteUserTrackPoint(point, writer); 
                    count++; 
                }
            } 

            //
            // We must have at least 1 trackpoint or the profile isn't valid
            if (0 == count) 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationNoTrackPoints);
 
            writer.WriteEndElement(); 
        }
 
        private void WriteActivityTrackPoint(ActivityTrackPoint point, XmlTextWriter writer)
        {
            if (null == point)
                throw new ArgumentNullException("point"); 
            //
            // Validate this element's required fields 
            if ((null == point.MatchingLocations) || (0 == point.MatchingLocations.Count)) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations);
 
            writer.WriteStartElement("ActivityTrackPoint");

            writer.WriteStartElement("MatchingLocations");
            // 
            // Write the locations that should be matched
            // At least one non null location is required. 
            int count = 0; 
            foreach (ActivityTrackingLocation location in point.MatchingLocations)
            { 
                if (null != location)
                {
                    WriteActivityTrackingLocation(location, writer);
                    count++; 
                }
            } 
 
            if (0 == count)
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations); 

            writer.WriteEndElement();
            //
            // Write the locations that should not be matched (these override the locations to match) 
            // Excludes are not required.
            if ((null != point.ExcludedLocations) && (point.ExcludedLocations.Count > 0)) 
            { 
                writer.WriteStartElement("ExcludedLocations");
 
                foreach (ActivityTrackingLocation location in point.ExcludedLocations)
                {
                    if (null != location)
                        WriteActivityTrackingLocation(location, writer); 
                }
 
                writer.WriteEndElement(); 
            }
            // 
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer);
            //
            // Write extracts, not a required field 
            WriteExtracts(point.Extracts, writer);
 
            writer.WriteEndElement(); 
        }
 
        private void WriteWorkflowTrackPoint(WorkflowTrackPoint point, XmlTextWriter writer)
        {
            //
            // Validate this element's required fields 
            if (null == point.MatchingLocation)
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocation); 
 
            writer.WriteStartElement("WorkflowTrackPoint");
 
            WriteWorkflowTrackingLocation(point.MatchingLocation, writer);
            //
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer); 

            writer.WriteEndElement(); 
        } 

        private void WriteUserTrackPoint(UserTrackPoint point, XmlTextWriter writer) 
        {
            //
            // Validate this element's required fields
            if ((null == point.MatchingLocations) || (0 == point.MatchingLocations.Count)) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations);
 
            writer.WriteStartElement("UserTrackPoint"); 

            writer.WriteStartElement("MatchingLocations"); 

            //
            // Write the locations that should be matched
            // At least one non null location is required. 
            int count = 0;
            foreach (UserTrackingLocation location in point.MatchingLocations) 
            { 
                if (null != location)
                { 
                    WriteUserTrackingLocation(location, writer);
                    count++;
                }
            } 

            if (0 == count) 
                throw new ArgumentException(ExecutionStringManager.NoMatchingLocations); 

            writer.WriteEndElement(); 

            //
            // Write the locations that should not be matched (these override the locations to match)
            // Excludes are not required. 
            if ((null != point.ExcludedLocations) && (point.ExcludedLocations.Count > 0))
            { 
                writer.WriteStartElement("ExcludedLocations"); 

                foreach (UserTrackingLocation location in point.ExcludedLocations) 
                {
                    if (null != location)
                        WriteUserTrackingLocation(location, writer);
                } 

                writer.WriteEndElement(); 
            } 

            // 
            // Write annotations, not a required field
            WriteAnnotations(point.Annotations, writer);
            //
            // Write extracts, not a required field 
            WriteExtracts(point.Extracts, writer);
 
            writer.WriteEndElement(); 
        }
 
        #endregion

        #region Location
 
        private void WriteActivityTrackingLocation(ActivityTrackingLocation loc, XmlTextWriter writer)
        { 
            // 
            // Validate this element's required fields
            if ((null == loc.ActivityType) && ((null == loc.ActivityTypeName) || (0 == loc.ActivityTypeName.Trim().Length))) 
                throw new ArgumentException(ExecutionStringManager.MissingActivityType);

            writer.WriteStartElement("ActivityTrackingLocation");
 
            writer.WriteStartElement("Activity");
 
            if (null != loc.ActivityType) 
                writer.WriteElementString("Type", loc.ActivityType.AssemblyQualifiedName);
            else 
                writer.WriteElementString("TypeName", loc.ActivityTypeName);

            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 

            WriteEvents(loc.ExecutionStatusEvents, writer); 
 
            if ((null != loc.Conditions) && (loc.Conditions.Count > 0))
                WriteConditions(loc.Conditions, writer); 


            writer.WriteEndElement();
        } 

        private void WriteUserTrackingLocation(UserTrackingLocation loc, XmlTextWriter writer) 
        { 
            //
            // Validate this element's required fields 
            if ((null == loc.ActivityType) && ((null == loc.ActivityTypeName) || (0 == loc.ActivityTypeName.Trim().Length)))
                throw new ArgumentException(ExecutionStringManager.MissingActivityType);

            if ((null == loc.ArgumentType) && ((null == loc.ArgumentTypeName) || (0 == loc.ArgumentTypeName.Trim().Length))) 
                throw new ArgumentException(ExecutionStringManager.MissingArgumentType);
 
            writer.WriteStartElement("UserTrackingLocation"); 
            //
            // Write the Acctivity node 
            writer.WriteStartElement("Activity");

            if (null != loc.ActivityType)
                writer.WriteElementString("Type", loc.ActivityType.AssemblyQualifiedName); 
            else
                writer.WriteElementString("TypeName", loc.ActivityTypeName); 
 
            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedActivityTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 
            //
            // Write the key name node if it is non null
            if (null != loc.KeyName)
                writer.WriteElementString("KeyName", loc.KeyName); 
            //
            // Write the Argument node 
            writer.WriteStartElement("Argument"); 

            if (null != loc.ArgumentType) 
                writer.WriteElementString("Type", loc.ArgumentType.AssemblyQualifiedName);
            else
                writer.WriteElementString("TypeName", loc.ArgumentTypeName);
 
            writer.WriteElementString("MatchDerivedTypes", loc.MatchDerivedArgumentTypes.ToString().ToLower(CultureInfo.InvariantCulture));
            writer.WriteEndElement(); 
 
            if ((null != loc.Conditions) && (loc.Conditions.Count > 0))
                WriteConditions(loc.Conditions, writer); 

            writer.WriteEndElement();
        }
 
        private void WriteWorkflowTrackingLocation(WorkflowTrackingLocation loc, XmlTextWriter writer)
        { 
            if ((null == loc.Events) || (0 == loc.Events.Count)) 
                throw new ArgumentException(ExecutionStringManager.MissingWorkflowEvents);
 
            writer.WriteStartElement("MatchingLocation");

            writer.WriteStartElement("WorkflowTrackingLocation");
 
            WriteWorkflowEvents(loc.Events, writer);
 
            writer.WriteEndElement(); 

            writer.WriteEndElement(); 
        }

        #endregion
 
        #region TrackingExtract
 
        private void WriteExtracts(ExtractCollection extracts, XmlTextWriter writer) 
        {
            if ((null == extracts) || (0 == extracts.Count)) 
                return;

            writer.WriteStartElement("Extracts");
 
            foreach (TrackingExtract e in extracts)
            { 
                if (null != e) 
                    WriteExtract(e, writer);
            } 

            writer.WriteEndElement();
        }
 
        private void WriteExtract(TrackingExtract extract, XmlTextWriter writer)
        { 
            Type t = extract.GetType(); 

            if ((extract is ActivityDataTrackingExtract) || (extract is WorkflowDataTrackingExtract)) 
            {
                writer.WriteStartElement(extract.GetType().Name);
                writer.WriteElementString("Member", (null == extract.Member ? string.Empty : extract.Member));
 
                WriteAnnotations(extract.Annotations, writer);
 
                writer.WriteEndElement(); 
            }
            else 
                throw new ArgumentException(ExecutionStringManager.TrackingSerializationInvalidExtract);
        }

        #endregion 

        #region Shared 
 
        private void WriteConditions(TrackingConditionCollection conditions, XmlTextWriter writer)
        { 
            if ((null == conditions) || (0 == conditions.Count))
                return;

            writer.WriteStartElement("Conditions"); 

            foreach (TrackingCondition c in conditions) 
            { 
                if (null != c)
                    WriteCondition(c, writer); 
            }

            writer.WriteEndElement();
        } 

        private void WriteCondition(TrackingCondition condition, XmlTextWriter writer) 
        { 
            if (null == condition)
                return; 

            writer.WriteStartElement(condition.GetType().Name);

            writer.WriteElementString("Operator", condition.Operator.ToString()); 

            if ((null == condition.Member) || (0 == condition.Member.Trim().Length)) 
                throw new ArgumentException(ExecutionStringManager.MissingMemberName); 

            writer.WriteElementString("Member", condition.Member); 

            if (null != condition.Value)
            {
                if (string.Empty == condition.Value) 
                {
                    writer.WriteStartElement("Value"); 
                    writer.WriteRaw(string.Empty); 
                    writer.WriteEndElement();
                } 
                else
                    writer.WriteElementString("Value", condition.Value);
            }
 
            writer.WriteEndElement();
        } 
 
        private void WriteAnnotations(TrackingAnnotationCollection annotations, XmlTextWriter writer)
        { 
            if ((null == annotations) || (0 == annotations.Count))
                return;

            writer.WriteStartElement("Annotations"); 
            foreach (string s in annotations)
            { 
                // 
                // Preserve null and empty as distinct values
                // null ==  empty string =  
                writer.WriteStartElement("Annotation");
                if ((null == s) || (s.Length > 0))
                {
                    writer.WriteValue(null == s ? String.Empty : s); 
                    writer.WriteEndElement();
                } 
                else 
                    writer.WriteFullEndElement();
            } 
            writer.WriteEndElement();
        }

        private void WriteEvents(IList events, XmlTextWriter writer) 
        {
            if ((null == events) || (0 == events.Count)) 
                throw new ArgumentException(ExecutionStringManager.MissingActivityEvents); 

            writer.WriteStartElement("ExecutionStatusEvents"); 

            foreach (ActivityExecutionStatus s in events)
            {
                if (!IsStatus((int)s)) 
                    throw new ArgumentException(ExecutionStringManager.InvalidStatus);
 
                writer.WriteStartElement("ExecutionStatus"); 
                writer.WriteValue(s.ToString());
                writer.WriteEndElement(); 
            }

            writer.WriteEndElement();
        } 

        private bool IsStatus(int val) 
        { 
            foreach (ActivityExecutionStatus s in Enum.GetValues(typeof(ActivityExecutionStatus)))
            { 
                if ((int)s == val)
                    return true;
            }
            return false; 
        }
 
        private void WriteWorkflowEvents(IList events, XmlTextWriter writer) 
        {
            if ((null == events) || (0 == events.Count)) 
                return;

            writer.WriteStartElement("TrackingWorkflowEvents");
 
            foreach (TrackingWorkflowEvent s in events)
            { 
                if (!IsWorkflowEvent((int)s)) 
                    throw new ArgumentException(ExecutionStringManager.InvalidWorkflowEvent);
 
                writer.WriteStartElement("TrackingWorkflowEvent");
                writer.WriteValue(s.ToString());
                writer.WriteEndElement();
            } 

            writer.WriteEndElement(); 
        } 

        private bool IsWorkflowEvent(int val) 
        {
            foreach (TrackingWorkflowEvent s in Enum.GetValues(typeof(TrackingWorkflowEvent)))
            {
                if ((int)s == val) 
                    return true;
            } 
            return false; 
        }
 
        #endregion

        private void InitWriter(XmlTextWriter writer)
        { 
            writer.Formatting = Formatting.Indented;
            writer.Indentation = 4; 
        } 

        #endregion 

        #region Schema

        private const string _ns = "http://schemas.microsoft.com/winfx/2006/workflow/trackingprofile"; 
        private XmlSchema _schema = null;
 
        internal const string _xsd = @" 

     

    
        
             
        
         
     

     
        
            
                
                 
                
             
         
    
 
    
        
            
             
            
             
         
    
 
    
        
            
         
    
 
     
        
             
        
    

     
        
             
             
            
         
    

    
         
            
             
             
            
         
    

    
         
            
         
     

     
        
            
        
     

     
         
            
             
            
            
        
     

     
         
            
             
        
    

     
        
             
         
    
 
    
        
            
         
    
 
     
        
             
                
                
            
             
        
     
 
    
         
            
        
    
 
    
         
             
        
     

    
        
             
            
             
         
    
 
    
        
            
             
        
     
 
    
         
            
        
    
 
    
         
             
            
             
            
            
            
         
    
 
     
        
             
        
    

     
        
             
             
            
             
            
            
            
             
            
             
             
            
             
        
    

     
        
             
             
        
     

    
        
             
            
         
     

     
        
            
            
         
    
 
     
        
             
        
    

     
        
             
         
    
"; 
        #endregion Schema
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK