private object TransformAndGetPropertySourceLocation(XamlReader reader, SourceTextScanner sourceTextScanner, SourceLocationFoundCallback sourceLocationFoundCallback)
        {
            // <property name, value's start location>
            Dictionary <string, SourceLocation> propertyValueLocationMapping = new Dictionary <string, SourceLocation>();

            object deserializedObject = null;
            object earlyResult        = null;

            UsingXamlWriter(
                new XamlObjectWriter(reader.SchemaContext),
                delegate(XamlObjectWriter objectWriter)
            {
                if (this.XamlSchemaContext.HasLocalAssembly)
                {
                    this.CopyNamespacesAndAddLocalAssembly(reader, objectWriter);
                }

                if (!(reader is IXamlLineInfo))
                {
                    XamlServices.Transform(reader, objectWriter);
                    earlyResult = objectWriter.Result;
                    return;
                }

                XamlType dynamicActivityPropertyType = this.XamlSchemaContext.GetXamlType(typeof(DynamicActivityProperty));
                while (reader.Read())
                {
                    // read SubTree will moves the reader pointed to
                    // element after its EO. So, we need to use a while
                    while (!reader.IsEof && reader.NodeType == XamlNodeType.StartObject &&
                           dynamicActivityPropertyType == reader.Type)
                    {
                        KeyValuePair <string, SourceLocation> nameSourceLocation = this.TransformDynamicActivityProperty(reader.ReadSubtree(), objectWriter, sourceTextScanner);
                        if (nameSourceLocation.Key != null && nameSourceLocation.Value != null && !propertyValueLocationMapping.ContainsKey(nameSourceLocation.Key))
                        {
                            propertyValueLocationMapping.Add(nameSourceLocation.Key, nameSourceLocation.Value);
                        }
                    }

                    if (!reader.IsEof)
                    {
                        objectWriter.WriteNode(reader);
                    }
                }

                deserializedObject = objectWriter.Result;
            });

            if (earlyResult != null)
            {
                return(earlyResult);
            }

            ActivityBuilder activityBuilder = deserializedObject as ActivityBuilder;

            if (activityBuilder == null)
            {
                return(deserializedObject);
            }

            foreach (KeyValuePair <string, SourceLocation> propertyValueLocation in propertyValueLocationMapping)
            {
                string         propertyName     = propertyValueLocation.Key;
                SourceLocation propertyLocation = propertyValueLocation.Value;
                if (!activityBuilder.Properties.Contains(propertyName))
                {
                    SharedFx.Assert(string.Format(CultureInfo.CurrentCulture, "no such property:{0}", propertyName));
                    continue;
                }

                DynamicActivityProperty property = activityBuilder.Properties[propertyName];

                if (property == null || property.Value == null)
                {
                    SharedFx.Assert(string.Format(CultureInfo.CurrentCulture, "no such property value:{0}", propertyName));
                    continue;
                }

                object expression = (property.Value is Argument) ? ((Argument)property.Value).Expression : null;
                if (expression != null)
                {
                    sourceLocationFoundCallback(expression, propertyLocation);
                }
                else
                {
                    sourceLocationFoundCallback(property.Value, propertyLocation);
                }
            }

            return(deserializedObject);
        }
        private object DeserializeString(string text, DeserializationMode mode, out IList <XamlLoadErrorInfo> loadErrors, out Dictionary <object, SourceLocation> sourceLocations)
        {
            object result = null;

            loadErrors = null;
            Dictionary <object, SourceLocation> collectingSourceLocations   = new Dictionary <object, SourceLocation>(ObjectReferenceEqualityComparer <object> .Default);
            SourceLocationFoundCallback         sourceLocationFoundCallback = new SourceLocationFoundCallback((obj, sourceLocation) =>
            {
                // If an object appear more than once in the XAML stream (e.g. System.Type, which is cached by reflection)
                // we count the first occurrence.
                if (!collectingSourceLocations.ContainsKey(obj))
                {
                    collectingSourceLocations.Add(obj, sourceLocation);
                }

                this.OnSourceLocationFound(obj, sourceLocation);
            });

            this.XamlSchemaContext.ContainsConversionRequiredType = false;
            Dictionary <string, SourceLocation> viewStateDataSourceLocationMapping = null;

            using (XamlDebuggerXmlReader debuggerReader = new XamlDebuggerXmlReader(new StringReader(text), this.XamlSchemaContext))
            {
                using (System.Xaml.XamlReader activityBuilderReader = ActivityXamlServices.CreateBuilderReader(debuggerReader))
                {
                    using (System.Xaml.XamlReader activityTemplateFactoryBuilderReader = new ActivityTemplateFactoryBuilderReader(activityBuilderReader, this.XamlSchemaContext))
                    {
                        debuggerReader.SourceLocationFound += delegate(object sender, SourceLocationFoundEventArgs args)
                        {
                            sourceLocationFoundCallback(args.Target, args.SourceLocation);
                        };

                        this.OnBeforeDeserialize();
                        debuggerReader.CollectNonActivitySourceLocation = this.FrameworkName.Is45OrHigher();

                        using (System.Xaml.XamlReader reader = ViewStateXamlHelper.ConvertViewStateToAttachedProperties(activityTemplateFactoryBuilderReader, this.IdManager, out viewStateDataSourceLocationMapping))
                        {
                            switch (mode)
                            {
#if ERROR_TOLERANT_SUPPORT
                            case DeserializationMode.ErrorTolerant:
                            {
                                ErrorTolerantObjectWriter tolerantWriter = new ErrorTolerantObjectWriter(reader.SchemaContext);
                                tolerantWriter.LocalAssemblyName = this.LocalAssemblyName;
                                XamlServices.Transform(reader, tolerantWriter);
                                loadErrors = this.CheckFileFormatError(tolerantWriter.LoadErrors);
                                result     = tolerantWriter.Result;
                                ErrorActivity.SetHasErrorActivities(result, true);
                            }

                            break;
#endif
                            case DeserializationMode.Default:
                            {
                                result = this.TransformAndGetPropertySourceLocation(reader, new SourceTextScanner(text), sourceLocationFoundCallback);

                                loadErrors = this.CheckFileFormatError(loadErrors);
                            }

                            break;
                            }
                        }
                    }
                }
            }

            sourceLocations = collectingSourceLocations;
            this.OnAfterDeserialize(viewStateDataSourceLocationMapping);
            return(result);
        }