DebuggerService.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 / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Debugger / DebuggerService.cs / 1305376 / DebuggerService.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Debug
{ 
    using System;
    using System.Diagnostics; 
    using System.Collections.Generic; 
    using System.Windows;
    using System.Windows.Documents; 
    using System.Activities;
    using System.Activities.Debugger;
    using System.Activities.Presentation;
    using System.Activities.Presentation.Debug; 
    using System.Activities.Presentation.Hosting;
    using System.Activities.Presentation.Model; 
    using System.Activities.Presentation.Services; 
    using System.Activities.Presentation.View;
    using System.Runtime; 
    using System.Windows.Threading;
    using System.Windows.Media;

    [Fx.Tag.XamlVisible(false)] 
    public class DebuggerService : IDesignerDebugView
    { 
        EditingContext context; 
        ModelItem selectedModelItem;
        SourceLocation currentLocation; 
        SourceLocation currentContext;
        ModelItem currentModelItem;
        ModelItem currentModelItemContext;
        WorkflowViewService viewService; 
        Dictionary breakpoints;
        Dictionary transientBreakpoints;  // Storing removed breakpoints, to support move and undo/redo operations. 
        Dictionary unmappedBreakpoints; // Breakpoints that have no ModelItem yet. 
        const string unresolvedPrefix = "unresolved:";
 

        AttachedProperty isBreakpointEnabledProperty;
        AttachedProperty isBreakpointBoundedProperty;
        AttachedProperty isBreakpointConditionalProperty; 
        AttachedProperty isCurrentLocationProperty;
        AttachedProperty isCurrentContextProperty; 
 
        Dictionary instanceToSourceLocationMapping;
        Dictionary modelItemToSourceLocation; 
        Dictionary sourceLocationToModelItem;

        Dictionary transientUnresolvedActivities;
 
        // This is used to generate unique source line no when the view element does not have a source location
        int lastSourceLineNo = 1; 
 
        bool isReadOnly = false;
        bool isDebugging = false; 

        public DebuggerService(EditingContext context)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 

            this.context = context; 
            this.modelItemToSourceLocation = new Dictionary();
            this.sourceLocationToModelItem = new Dictionary();
            this.breakpoints = new Dictionary();
            // Breakpoints transiently removed from the document (copy/paste/undo/redo). 
            this.transientBreakpoints = new Dictionary();
            this.unmappedBreakpoints = new Dictionary(4); 
            this.instanceToSourceLocationMapping = new Dictionary(); 
            this.transientUnresolvedActivities = new Dictionary();
 
            this.context.Items.Subscribe(new SubscribeContextCallback(this.SelectionChanged));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnViewServiceAvailable));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnAttachedPropertiesServiceAvailable));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnModelServiceAvailable)); 

        } 
 
        //	IDesignerDebugView
 
        // Get the currently selected location from the designer
        // generally this is the location activity currently selected by the user
        public SourceLocation SelectedLocation
        { 
            get
            { 
                return this.GetSourceLocationFromModelItem(this.selectedModelItem); 
            }
        } 

        // Set current location of execution.
        // The location to shown the "yellow" arrow.
        public SourceLocation CurrentLocation 
        {
            get 
            { 
                return this.currentLocation;
            } 

            set
            {
                this.currentLocation = value; 
                ModelItem previousModelItem = this.currentModelItem;
                UpdateCurrentModelItem(); 
                if (this.currentLocation != null && this.currentModelItem == null) 
                {   // This is a rare case but it happens when the designer is not all done with bringing up the view but
                    // Debugger already set this location. 
                    PostBringToViewCurrentLocation(previousModelItem);
                }
                else
                { 
                    BringToViewCurrentLocation(previousModelItem);
                } 
            } 
        }
 
        void BringToViewCurrentLocation(ModelItem previousModelItem)
        {
            SetPropertyValue(previousModelItem, isCurrentLocationProperty, this.currentModelItem);
            if (this.currentModelItem != this.currentModelItemContext) 
            {
                BringToView(this.currentModelItem); 
            } 
        }
 
        // Storing background BringToViewCurrentLocation operation.
        DispatcherOperation bringToViewCurrentLocationOperation = null;

        // Post new BringToViewCurrentLocation operation 
        void PostBringToViewCurrentLocation(ModelItem previousModelItem)
        { 
            // Abort pending operation. 
            if (this.bringToViewCurrentLocationOperation != null)
            { 
                this.bringToViewCurrentLocationOperation.Abort();
                this.bringToViewCurrentLocationOperation = null;
            }
 
            // Post a new background operation.
            this.bringToViewCurrentLocationOperation = Dispatcher.CurrentDispatcher.BeginInvoke( 
                DispatcherPriority.Background, 
                (DispatcherOperationCallback)delegate(object arg)
                { 
                    this.UpdateCurrentModelItem();
                    this.BringToViewCurrentLocation(previousModelItem);
                    this.bringToViewCurrentLocationOperation = null;
                    return null; 
                }
                , 
                null); 
        }
 

        // Set current context (stack frame scope).
        // The highlighted scope of execution.
        public SourceLocation CurrentContext 
        {
            get 
            { 
                return this.currentContext;
            } 
            set
            {
                this.currentContext = value;
                ModelItem previousModelItem = this.currentModelItemContext; 
                UpdateCurrentModelItemContext();
                SetPropertyValue(previousModelItem, this.isCurrentContextProperty, this.currentModelItemContext); 
                BringToView(this.currentModelItemContext); 
            }
        } 

        // Set to true while debugging
        public bool IsDebugging
        { 
            get
            { 
                return this.isDebugging; 
            }
 
            set
            {
                ReadOnlyState readOnlyState = this.context.Items.GetValue();
                if (readOnlyState != null) 
                {
                    // start debugging 
                    if (value && !this.isDebugging) 
                    {
                        this.isDebugging = true; 
                        // backup the read-only state
                        this.isReadOnly = readOnlyState.IsReadOnly;
                        readOnlyState.IsReadOnly = true;
                    } 
                    // finish debugging
                    else if (!value && this.isDebugging) 
                    { 
                        this.isDebugging = false;
                        // restore to previous state before debugging 
                        readOnlyState.IsReadOnly = this.isReadOnly;
                    }
                    this.context.Items.SetValue(new ReadOnlyState() {IsReadOnly = readOnlyState.IsReadOnly});
                } 
            }
        } 
 
        public bool HideSourceFileName
        { 
            get;
            set;
        }
 
        void UpdateCurrentModelItem()
        { 
            this.currentModelItem = this.GetModelItemFromSourceLocation(this.currentLocation, /* forceCreate */ true); 
        }
 
        void UpdateCurrentModelItemContext()
        {
            this.currentModelItemContext = this.GetModelItemFromSourceLocation(this.currentContext, /* forceCreate */ true);
        } 

        void BringToView(ModelItem modelItem) 
        { 
            if (modelItem != null)
            { 
                modelItem.Focus();
            }
        }
 
        void OnAttachedPropertiesServiceAvailable(AttachedPropertiesService attachedPropertiesService)
        { 
            //AttachedProperty isCurrentContextProperty; 

            this.isBreakpointEnabledProperty = new AttachedProperty() 
                {
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Enabled),
                    Name = "IsBreakpointEnabled",
                    OwnerType = typeof(Activity) 
                };
 
            this.isBreakpointBoundedProperty = new AttachedProperty() 
                {
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Bounded), 
                    Name = "IsBreakpointBounded",
                    OwnerType = typeof(Activity)
                };
 
            this.isBreakpointConditionalProperty = new AttachedProperty()
                { 
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Conditional), 
                    Name = "IsBreakpointConditional",
                    OwnerType = typeof(Activity) 
                };

            this.isCurrentLocationProperty = new AttachedProperty()
                { 
                    Getter = (modelItem) => IsCurrentLocation(modelItem),
                    Name = "IsCurrentLocation", 
                    OwnerType = typeof(Activity) 
                };
 
            this.isCurrentContextProperty = new AttachedProperty()
                {
                    Getter = (modelItem) => IsCurrentContext(modelItem),
                    Name = "IsCurrentContext", 
                    OwnerType = typeof(Activity)
                }; 
 
            attachedPropertiesService.AddProperty(isBreakpointEnabledProperty);
            attachedPropertiesService.AddProperty(isBreakpointBoundedProperty); 
            attachedPropertiesService.AddProperty(isBreakpointConditionalProperty);
            attachedPropertiesService.AddProperty(isCurrentLocationProperty);
            attachedPropertiesService.AddProperty(isCurrentContextProperty);
        } 

        void OnModelServiceAvailable(ModelService modelService) 
        { 
            modelService.ModelChanged += new EventHandler(OnModelChanged);
        } 

        void OnModelChanged(object sender, ModelChangedEventArgs e)
        {
            if (e.ItemsRemoved != null) 
            {
                this.transientUnresolvedActivities.Clear();             // can clear all previous transient unresolved activities 
                foreach (ModelItem modelItem in e.ItemsRemoved) 
                {
                    BreakpointTypes breakpointType; 
                    if (this.breakpoints.TryGetValue(modelItem, out breakpointType))
                    {
                        this.transientBreakpoints[modelItem] = breakpointType;   // cache it in case it's added later (move case).
                        SetBreakpointType(modelItem, BreakpointTypes.None); // clear breakpoint 
                    }
 
                    Activity activity = modelItem.GetCurrentValue() as Activity; 
                    if (activity != null)
                    { 
                        // Note: we only delete the activity.
                        // All the activity's children mapping will be flushed during saving.
                        DeleteActivityFromMapping(activity);
                    } 
                }
            } 
        } 

        // Delete a single activity from the mappings. 
        // We only delete unresolved activity, i.e. activity that never been
        // saved.  We leave the resolved activity untouch (otherwise undoing
        // the removed activity will make it as "unresolved" the next time around).
        void DeleteActivityFromMapping(Activity activity) 
        {
            SourceLocation sourceLocation; 
            if (this.instanceToSourceLocationMapping.TryGetValue(activity, out sourceLocation)) 
            {
                if (IsUnresolved(sourceLocation)) 
                {
                    // Move it to transient unresolved activities to support move operation.
                    this.transientUnresolvedActivities.Add(activity, sourceLocation);
 
                    this.instanceToSourceLocationMapping.Remove(activity);
                    ModelItem modelItem; 
                    if (this.sourceLocationToModelItem.TryGetValue(sourceLocation, out modelItem)) 
                    {
                        this.sourceLocationToModelItem.Remove(sourceLocation); 
                        this.modelItemToSourceLocation.Remove(modelItem);
                    }
                }
            } 
        }
 
        bool IsCurrentLocation(ModelItem modelItem) 
        {
            UpdateCurrentModelItem(); 
            return this.currentModelItem == modelItem;
        }

        bool IsCurrentContext(ModelItem modelItem) 
        {
            UpdateCurrentModelItemContext(); 
            return this.currentModelItemContext == modelItem; 
        }
 
        void SelectionChanged(Selection selection)
        {
            this.selectedModelItem = selection.PrimarySelection;
        } 

        // Check if unmapped breakpoint exists for the given sourceLocation, 
        // if so, mapped it to the given model item & remove it from unmapped breakpoints. 
        void TryActivateUnmappedBreakpoint(SourceLocation sourceLocation, ModelItem modelItem)
        { 
            BreakpointTypes breakpointType;
            if (this.unmappedBreakpoints.TryGetValue(sourceLocation, out breakpointType))
            {
                this.SetBreakpointType(modelItem, breakpointType); 
                this.unmappedBreakpoints.Remove(sourceLocation);
            } 
        } 

        void TryActivateAllUnmappedBreakpoints() 
        {
            if (this.unmappedBreakpoints.Count > 0)
            {
                List unmappedLocations = new List(); 
                unmappedLocations.AddRange(this.unmappedBreakpoints.Keys);
                foreach (SourceLocation unmappedLocation in unmappedLocations) 
                { 
                    ModelItem modelItem = this.GetModelItemFromSourceLocation(unmappedLocation);
                    if (modelItem != null) 
                    {
                        TryActivateUnmappedBreakpoint(unmappedLocation, modelItem);
                    }
                } 
            }
        } 
 
        bool IsBreakpointOfType(ModelItem modelItem, BreakpointTypes breakpoinType)
        { 
            bool result = false;
            BreakpointTypes actualBreakpointType;
            TryActivateAllUnmappedBreakpoints();
            if (this.breakpoints.TryGetValue(modelItem, out actualBreakpointType)) 
            {
                result = (actualBreakpointType & breakpoinType) > 0; 
            } 
            return result;
        } 


        void SetBreakpointType(ModelItem modelItem, BreakpointTypes newBreakpointType)
        { 
            BreakpointTypes oldBreakpointType = BreakpointTypes.None;
            if (this.breakpoints.TryGetValue(modelItem, out oldBreakpointType)) 
            { 
                Fx.Assert(oldBreakpointType != BreakpointTypes.None, "Should not store BreakpointType.None");
                if (newBreakpointType == BreakpointTypes.None) 
                {
                    this.breakpoints.Remove(modelItem);
                }
                else 
                {
                    this.breakpoints[modelItem] = newBreakpointType; 
                } 
            }
            else if (newBreakpointType != BreakpointTypes.None) 
            {
                this.breakpoints.Add(modelItem, newBreakpointType);
            }
 
            // Now notifying corresponding properties.
            if ((oldBreakpointType & BreakpointTypes.Bounded) != 
                (newBreakpointType & BreakpointTypes.Bounded)) 
            {
                this.isBreakpointBoundedProperty.NotifyPropertyChanged(modelItem); 
            }

            if ((oldBreakpointType & BreakpointTypes.Enabled) !=
                (newBreakpointType & BreakpointTypes.Enabled)) 
            {
                this.isBreakpointEnabledProperty.NotifyPropertyChanged(modelItem); 
            } 

            if ((oldBreakpointType & BreakpointTypes.Conditional) != 
                (newBreakpointType & BreakpointTypes.Conditional))
            {
                this.isBreakpointConditionalProperty.NotifyPropertyChanged(modelItem);
            } 
        }
 
        // Return exact source location given approximate location. 
        public SourceLocation GetExactLocation(SourceLocation approximateLocation)
        { 
            if (approximateLocation == null)
            {
                throw FxTrace.Exception.ArgumentNull("approximateLocation");
            } 

            SourceLocation exactLocation = null; 
 
            foreach (SourceLocation sourceLocation in this.instanceToSourceLocationMapping.Values)
            { 
                if (sourceLocation.StartLine == approximateLocation.StartLine)
                {
                    exactLocation = sourceLocation;
                    break; 
                }
            } 
 
            if (exactLocation == null)
            {   // Find the next line of the approximateLocation. 
                int minimumDistance = int.MaxValue;
                foreach (SourceLocation sourceLocation in this.instanceToSourceLocationMapping.Values)
                {
                    int lineDistance = sourceLocation.StartLine - approximateLocation.StartLine; 
                    if ((lineDistance > 0) &&
                        ((lineDistance < minimumDistance) || 
                         ((lineDistance == minimumDistance) && (sourceLocation.StartColumn < exactLocation.StartColumn))))  // if same distance, then compare the start column 
                    {
                        exactLocation = sourceLocation; 
                        minimumDistance = lineDistance;
                    }
                }
            } 

            return exactLocation; 
        } 

        // Called after a Save by AddIn to update breakpoints with new locations 
        public IDictionary GetBreakpointLocations()
        {
            IDictionary breakpointLocations = new Dictionary();
 
            // Collect source locations of model items with breakpoints
            if (this.breakpoints.Count > 0 || this.unmappedBreakpoints.Count > 0) 
            { 
                foreach (KeyValuePair entry in this.breakpoints)
                { 
                    SourceLocation breakpointLocation = this.GetSourceLocationFromModelItem(entry.Key);
                    // BreakpointLocation can be null, if the model item is deleted but without notification
                    // through OnModelChanged.  This happens when the breakpoint is located inside child
                    // activity of a deleted activity. 
                    if (breakpointLocation != null)
                    { 
                        breakpointLocations.Add(breakpointLocation, entry.Value); 
                    }
                } 
                foreach (KeyValuePair entry in this.unmappedBreakpoints)
                {
                    breakpointLocations.Add(entry.Key, entry.Value);
                } 
            }
            return breakpointLocations; 
        } 

        // Inserting a new breakpoint of a given type. 
        public void InsertBreakpoint(SourceLocation sourceLocation, BreakpointTypes breakpointType)
        {
            this.UpdateBreakpoint(sourceLocation, breakpointType);
        } 

        // Update the appearance of a given breakpoint to show the given type. 
        public void UpdateBreakpoint(SourceLocation sourceLocation, BreakpointTypes newBreakpointType) 
        {
            ModelItem modelItem = this.GetModelItemFromSourceLocation(sourceLocation); 
            if (modelItem != null)
            {
                SetBreakpointType(modelItem, newBreakpointType);
            } 
            else
            { 
                BreakpointTypes oldBreakpointType; 
                if (this.unmappedBreakpoints.TryGetValue(sourceLocation, out oldBreakpointType))
                { 
                    if (newBreakpointType == BreakpointTypes.None)
                    {
                        this.unmappedBreakpoints.Remove(sourceLocation);
                    } 
                    else
                    { 
                        this.unmappedBreakpoints[sourceLocation] = newBreakpointType; 
                    }
                } 
                else if (newBreakpointType != BreakpointTypes.None)
                {
                    this.unmappedBreakpoints.Add(sourceLocation, newBreakpointType);
                } 
            }
        } 
 

        // Delete a breakpoint. 
        public void DeleteBreakpoint(SourceLocation sourceLocation)
        {
            UpdateBreakpoint(sourceLocation, BreakpointTypes.None);
        } 

        // Reset breakpoints: delete and prepare for breakpoint refresh. 
        public void ResetBreakpoints() 
        {
            ModelItem[] oldModelItems = new ModelItem[this.breakpoints.Keys.Count]; 
            this.breakpoints.Keys.CopyTo(oldModelItems, 0);
            this.breakpoints.Clear();
            this.unmappedBreakpoints.Clear();
 
            // Now notifying update to corresponding properties.
            foreach (ModelItem modelItem in oldModelItems) 
            { 
                this.isBreakpointBoundedProperty.NotifyPropertyChanged(modelItem);
                this.isBreakpointEnabledProperty.NotifyPropertyChanged(modelItem); 
                this.isBreakpointConditionalProperty.NotifyPropertyChanged(modelItem);
            }

        } 

        // Called by Addin after Load/Save.  Addin collects the new mapping from SourceLocationMapping. 
        public void UpdateSourceLocations(Dictionary newSourceLocationMapping) 
        {
            if (newSourceLocationMapping == null) 
            {
                throw FxTrace.Exception.ArgumentNull("newSourceLocationMapping");
            }
 
            // Update unmappedBreakpoints before refreshing the instanceToSourceLocationMapping.
            if (this.unmappedBreakpoints.Count > 0) 
            { 
                Dictionary newUnmappedBreakpoints = new Dictionary(this.unmappedBreakpoints.Count);
                foreach (KeyValuePair kvpEntry in this.instanceToSourceLocationMapping) 
                {
                    if (this.unmappedBreakpoints.ContainsKey(kvpEntry.Value))
                    {
                        Fx.Assert(newSourceLocationMapping.ContainsKey(kvpEntry.Key), "Activity is not found in the newSourceLocationMapping"); 
                        newUnmappedBreakpoints.Add(newSourceLocationMapping[kvpEntry.Key], this.unmappedBreakpoints[kvpEntry.Value]);
                    } 
                } 
                this.unmappedBreakpoints = newUnmappedBreakpoints;
            } 
            this.instanceToSourceLocationMapping = newSourceLocationMapping;
            this.sourceLocationToModelItem.Clear();
            this.modelItemToSourceLocation.Clear();
            this.transientBreakpoints.Clear(); 
            this.transientUnresolvedActivities.Clear();
 
            this.lastSourceLineNo = 1; 

            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 

            if (modelTreeManager != null)
            {
                foreach (KeyValuePair kvp in newSourceLocationMapping) 
                {
                    ModelItem modelItem = modelTreeManager.GetModelItem(kvp.Key); 
                    if (modelItem != null) 
                    {
                        SourceLocation sourceLocation = kvp.Value; 
                        this.sourceLocationToModelItem.Add(sourceLocation, modelItem);
                        this.modelItemToSourceLocation.Add(modelItem, sourceLocation);
                    }
                } 
            }
            TryActivateAllUnmappedBreakpoints(); 
        } 

        // Called by View Service when a new view element is added 
        void ViewChanged(object sender, WorkflowViewService.ViewChangedEventArgs e)
        {
            if (e.AddedElement != null)
            { 
                ModelItem modelItem = e.AddedElement.ModelItem;
                Activity activity = modelItem.GetCurrentValue() as Activity; 
 
                if (activity != null)
                { // Only care for ViewChanged for Activity. 

                    // Create a mapping between SourceLocation and this View Element
                    SourceLocation sourceLocation = this.GetSourceLocationFromModelItemInstance(activity);
                    if (sourceLocation == null) 
                    {
                        // Check if this is for moving an unresolved activity. 
                        if (!this.transientUnresolvedActivities.TryGetValue(activity, out sourceLocation)) 
                        {
                            // The current view element has not been saved yet to the Xaml file 
                            sourceLocation = GenerateUnresolvedLocation();
                        }
                        this.instanceToSourceLocationMapping.Add(activity, sourceLocation);
                    } 

                    this.modelItemToSourceLocation[modelItem] = sourceLocation; 
                    this.sourceLocationToModelItem[sourceLocation] = modelItem; 

                    BreakpointTypes breakpointType; 
                    // check if it's in the transient breakpoint list.
                    if (this.transientBreakpoints.TryGetValue(modelItem, out breakpointType))
                    {
                        this.transientBreakpoints.Remove(modelItem); 
                        SetBreakpointType(modelItem, breakpointType);
                    } 
                    else 
                    {
                        TryActivateUnmappedBreakpoint(sourceLocation, modelItem); 
                    }
                }
            }
        } 

        SourceLocation GenerateUnresolvedLocation() 
        { 
            return new SourceLocation(unresolvedPrefix + this.context.Items.GetValue().LoadedFile, this.lastSourceLineNo++);
        } 

        static bool IsUnresolved(SourceLocation sourceLocation)
        {
            return !string.IsNullOrEmpty(sourceLocation.FileName) && sourceLocation.FileName.StartsWith(unresolvedPrefix, StringComparison.OrdinalIgnoreCase); 
        }
 
        void OnViewServiceAvailable(ViewService viewService) 
        {
            this.viewService = viewService as WorkflowViewService; 
            this.viewService.ViewChanged += new WorkflowViewService.ViewChangedEventHandler(this.ViewChanged);
        }

        SourceLocation GetSourceLocationFromModelItemInstance(object instance) 
        {
            SourceLocation sourceLocation; 
 
            // instanceToSourceLocationMapping contains source locations for all instances
            // immediately after a Load or save.  For instances that have been just dropped into 
            // the Designer from the Toolbox, we want to return null from here and treat them
            // as "Unresolved" in the caller.
            if (this.instanceToSourceLocationMapping.TryGetValue(instance, out sourceLocation))
            { 
                return sourceLocation;
            } 
            else 
            {
                return null; 
            }
        }

        void SetPropertyValue(ModelItem oldModelItem, AttachedProperty property, ModelItem newModelItem) 
        {
            // update the previous ModelItem (what was current before) 
            if (oldModelItem != null) 
            {
                property.NotifyPropertyChanged(oldModelItem); 
            }

            // update the current Modelitem
            if (newModelItem != null) 
            {
                property.NotifyPropertyChanged(newModelItem); 
            } 
        }
 
        SourceLocation GetSourceLocationFromModelItem(ModelItem modelItem)
        {
            SourceLocation sourceLocation = null;
            if (modelItem != null) 
            {
                this.modelItemToSourceLocation.TryGetValue(modelItem, out sourceLocation); 
            } 
            return sourceLocation;
        } 

        ModelItem GetModelItemFromSourceLocation(SourceLocation sourceLocation)
        {
            return GetModelItemFromSourceLocation(sourceLocation, /* forceCreate = */ false); 
        }
 
        ModelItem GetModelItemFromSourceLocation(SourceLocation sourceLocation, bool forceCreate) 
        {
            ModelItem modelItem = null; 
            if (sourceLocation != null)
            {
                if (!this.sourceLocationToModelItem.TryGetValue(sourceLocation, out modelItem))
                { 
                    if (forceCreate)
                    { 
                        Activity foundElement = null; 
                        foreach (KeyValuePair kvp in this.instanceToSourceLocationMapping)
                        { 
                            if (kvp.Value.Equals(sourceLocation))
                            {
                                foundElement = kvp.Key as Activity;
                                break; 
                            }
                        } 
                        if (foundElement != null) 
                        {
 
                            List parentChain = Validation.ValidationService.GetParentChain(foundElement);
                            Fx.Assert(parentChain != null, "Cannot find parent chain for " + foundElement.DisplayName);

                            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 
                            Fx.Assert(modelTreeManager != null, "ModelTreeManager is null."); // ModelTreeManager should not be null
 
                            ModelItem lowestModelItem = null; 
                            foreach (Activity parent in parentChain)
                            { 
                                lowestModelItem = modelTreeManager.GetModelItem(parent);
                                if (lowestModelItem != null)
                                {
                                    break; 
                                }
                            } 
 
                            if (lowestModelItem != null)
                            { 
                                // Walk the tree to create all the model items until it found the model item for the element.
                                modelItem = modelTreeManager.FindFirst(lowestModelItem, (mi) => (mi.GetCurrentValue() == foundElement));

                                if (modelItem != null) 
                                {
                                    this.modelItemToSourceLocation.Add(modelItem, sourceLocation); 
                                    this.sourceLocationToModelItem.Add(sourceLocation, modelItem); 
                                }
                            } 
                        }
                    }
                }
            } 
            return modelItem;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Debug
{ 
    using System;
    using System.Diagnostics; 
    using System.Collections.Generic; 
    using System.Windows;
    using System.Windows.Documents; 
    using System.Activities;
    using System.Activities.Debugger;
    using System.Activities.Presentation;
    using System.Activities.Presentation.Debug; 
    using System.Activities.Presentation.Hosting;
    using System.Activities.Presentation.Model; 
    using System.Activities.Presentation.Services; 
    using System.Activities.Presentation.View;
    using System.Runtime; 
    using System.Windows.Threading;
    using System.Windows.Media;

    [Fx.Tag.XamlVisible(false)] 
    public class DebuggerService : IDesignerDebugView
    { 
        EditingContext context; 
        ModelItem selectedModelItem;
        SourceLocation currentLocation; 
        SourceLocation currentContext;
        ModelItem currentModelItem;
        ModelItem currentModelItemContext;
        WorkflowViewService viewService; 
        Dictionary breakpoints;
        Dictionary transientBreakpoints;  // Storing removed breakpoints, to support move and undo/redo operations. 
        Dictionary unmappedBreakpoints; // Breakpoints that have no ModelItem yet. 
        const string unresolvedPrefix = "unresolved:";
 

        AttachedProperty isBreakpointEnabledProperty;
        AttachedProperty isBreakpointBoundedProperty;
        AttachedProperty isBreakpointConditionalProperty; 
        AttachedProperty isCurrentLocationProperty;
        AttachedProperty isCurrentContextProperty; 
 
        Dictionary instanceToSourceLocationMapping;
        Dictionary modelItemToSourceLocation; 
        Dictionary sourceLocationToModelItem;

        Dictionary transientUnresolvedActivities;
 
        // This is used to generate unique source line no when the view element does not have a source location
        int lastSourceLineNo = 1; 
 
        bool isReadOnly = false;
        bool isDebugging = false; 

        public DebuggerService(EditingContext context)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 

            this.context = context; 
            this.modelItemToSourceLocation = new Dictionary();
            this.sourceLocationToModelItem = new Dictionary();
            this.breakpoints = new Dictionary();
            // Breakpoints transiently removed from the document (copy/paste/undo/redo). 
            this.transientBreakpoints = new Dictionary();
            this.unmappedBreakpoints = new Dictionary(4); 
            this.instanceToSourceLocationMapping = new Dictionary(); 
            this.transientUnresolvedActivities = new Dictionary();
 
            this.context.Items.Subscribe(new SubscribeContextCallback(this.SelectionChanged));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnViewServiceAvailable));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnAttachedPropertiesServiceAvailable));
            this.context.Services.Subscribe(new SubscribeServiceCallback(this.OnModelServiceAvailable)); 

        } 
 
        //	IDesignerDebugView
 
        // Get the currently selected location from the designer
        // generally this is the location activity currently selected by the user
        public SourceLocation SelectedLocation
        { 
            get
            { 
                return this.GetSourceLocationFromModelItem(this.selectedModelItem); 
            }
        } 

        // Set current location of execution.
        // The location to shown the "yellow" arrow.
        public SourceLocation CurrentLocation 
        {
            get 
            { 
                return this.currentLocation;
            } 

            set
            {
                this.currentLocation = value; 
                ModelItem previousModelItem = this.currentModelItem;
                UpdateCurrentModelItem(); 
                if (this.currentLocation != null && this.currentModelItem == null) 
                {   // This is a rare case but it happens when the designer is not all done with bringing up the view but
                    // Debugger already set this location. 
                    PostBringToViewCurrentLocation(previousModelItem);
                }
                else
                { 
                    BringToViewCurrentLocation(previousModelItem);
                } 
            } 
        }
 
        void BringToViewCurrentLocation(ModelItem previousModelItem)
        {
            SetPropertyValue(previousModelItem, isCurrentLocationProperty, this.currentModelItem);
            if (this.currentModelItem != this.currentModelItemContext) 
            {
                BringToView(this.currentModelItem); 
            } 
        }
 
        // Storing background BringToViewCurrentLocation operation.
        DispatcherOperation bringToViewCurrentLocationOperation = null;

        // Post new BringToViewCurrentLocation operation 
        void PostBringToViewCurrentLocation(ModelItem previousModelItem)
        { 
            // Abort pending operation. 
            if (this.bringToViewCurrentLocationOperation != null)
            { 
                this.bringToViewCurrentLocationOperation.Abort();
                this.bringToViewCurrentLocationOperation = null;
            }
 
            // Post a new background operation.
            this.bringToViewCurrentLocationOperation = Dispatcher.CurrentDispatcher.BeginInvoke( 
                DispatcherPriority.Background, 
                (DispatcherOperationCallback)delegate(object arg)
                { 
                    this.UpdateCurrentModelItem();
                    this.BringToViewCurrentLocation(previousModelItem);
                    this.bringToViewCurrentLocationOperation = null;
                    return null; 
                }
                , 
                null); 
        }
 

        // Set current context (stack frame scope).
        // The highlighted scope of execution.
        public SourceLocation CurrentContext 
        {
            get 
            { 
                return this.currentContext;
            } 
            set
            {
                this.currentContext = value;
                ModelItem previousModelItem = this.currentModelItemContext; 
                UpdateCurrentModelItemContext();
                SetPropertyValue(previousModelItem, this.isCurrentContextProperty, this.currentModelItemContext); 
                BringToView(this.currentModelItemContext); 
            }
        } 

        // Set to true while debugging
        public bool IsDebugging
        { 
            get
            { 
                return this.isDebugging; 
            }
 
            set
            {
                ReadOnlyState readOnlyState = this.context.Items.GetValue();
                if (readOnlyState != null) 
                {
                    // start debugging 
                    if (value && !this.isDebugging) 
                    {
                        this.isDebugging = true; 
                        // backup the read-only state
                        this.isReadOnly = readOnlyState.IsReadOnly;
                        readOnlyState.IsReadOnly = true;
                    } 
                    // finish debugging
                    else if (!value && this.isDebugging) 
                    { 
                        this.isDebugging = false;
                        // restore to previous state before debugging 
                        readOnlyState.IsReadOnly = this.isReadOnly;
                    }
                    this.context.Items.SetValue(new ReadOnlyState() {IsReadOnly = readOnlyState.IsReadOnly});
                } 
            }
        } 
 
        public bool HideSourceFileName
        { 
            get;
            set;
        }
 
        void UpdateCurrentModelItem()
        { 
            this.currentModelItem = this.GetModelItemFromSourceLocation(this.currentLocation, /* forceCreate */ true); 
        }
 
        void UpdateCurrentModelItemContext()
        {
            this.currentModelItemContext = this.GetModelItemFromSourceLocation(this.currentContext, /* forceCreate */ true);
        } 

        void BringToView(ModelItem modelItem) 
        { 
            if (modelItem != null)
            { 
                modelItem.Focus();
            }
        }
 
        void OnAttachedPropertiesServiceAvailable(AttachedPropertiesService attachedPropertiesService)
        { 
            //AttachedProperty isCurrentContextProperty; 

            this.isBreakpointEnabledProperty = new AttachedProperty() 
                {
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Enabled),
                    Name = "IsBreakpointEnabled",
                    OwnerType = typeof(Activity) 
                };
 
            this.isBreakpointBoundedProperty = new AttachedProperty() 
                {
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Bounded), 
                    Name = "IsBreakpointBounded",
                    OwnerType = typeof(Activity)
                };
 
            this.isBreakpointConditionalProperty = new AttachedProperty()
                { 
                    Getter = (modelItem) => IsBreakpointOfType(modelItem, BreakpointTypes.Conditional), 
                    Name = "IsBreakpointConditional",
                    OwnerType = typeof(Activity) 
                };

            this.isCurrentLocationProperty = new AttachedProperty()
                { 
                    Getter = (modelItem) => IsCurrentLocation(modelItem),
                    Name = "IsCurrentLocation", 
                    OwnerType = typeof(Activity) 
                };
 
            this.isCurrentContextProperty = new AttachedProperty()
                {
                    Getter = (modelItem) => IsCurrentContext(modelItem),
                    Name = "IsCurrentContext", 
                    OwnerType = typeof(Activity)
                }; 
 
            attachedPropertiesService.AddProperty(isBreakpointEnabledProperty);
            attachedPropertiesService.AddProperty(isBreakpointBoundedProperty); 
            attachedPropertiesService.AddProperty(isBreakpointConditionalProperty);
            attachedPropertiesService.AddProperty(isCurrentLocationProperty);
            attachedPropertiesService.AddProperty(isCurrentContextProperty);
        } 

        void OnModelServiceAvailable(ModelService modelService) 
        { 
            modelService.ModelChanged += new EventHandler(OnModelChanged);
        } 

        void OnModelChanged(object sender, ModelChangedEventArgs e)
        {
            if (e.ItemsRemoved != null) 
            {
                this.transientUnresolvedActivities.Clear();             // can clear all previous transient unresolved activities 
                foreach (ModelItem modelItem in e.ItemsRemoved) 
                {
                    BreakpointTypes breakpointType; 
                    if (this.breakpoints.TryGetValue(modelItem, out breakpointType))
                    {
                        this.transientBreakpoints[modelItem] = breakpointType;   // cache it in case it's added later (move case).
                        SetBreakpointType(modelItem, BreakpointTypes.None); // clear breakpoint 
                    }
 
                    Activity activity = modelItem.GetCurrentValue() as Activity; 
                    if (activity != null)
                    { 
                        // Note: we only delete the activity.
                        // All the activity's children mapping will be flushed during saving.
                        DeleteActivityFromMapping(activity);
                    } 
                }
            } 
        } 

        // Delete a single activity from the mappings. 
        // We only delete unresolved activity, i.e. activity that never been
        // saved.  We leave the resolved activity untouch (otherwise undoing
        // the removed activity will make it as "unresolved" the next time around).
        void DeleteActivityFromMapping(Activity activity) 
        {
            SourceLocation sourceLocation; 
            if (this.instanceToSourceLocationMapping.TryGetValue(activity, out sourceLocation)) 
            {
                if (IsUnresolved(sourceLocation)) 
                {
                    // Move it to transient unresolved activities to support move operation.
                    this.transientUnresolvedActivities.Add(activity, sourceLocation);
 
                    this.instanceToSourceLocationMapping.Remove(activity);
                    ModelItem modelItem; 
                    if (this.sourceLocationToModelItem.TryGetValue(sourceLocation, out modelItem)) 
                    {
                        this.sourceLocationToModelItem.Remove(sourceLocation); 
                        this.modelItemToSourceLocation.Remove(modelItem);
                    }
                }
            } 
        }
 
        bool IsCurrentLocation(ModelItem modelItem) 
        {
            UpdateCurrentModelItem(); 
            return this.currentModelItem == modelItem;
        }

        bool IsCurrentContext(ModelItem modelItem) 
        {
            UpdateCurrentModelItemContext(); 
            return this.currentModelItemContext == modelItem; 
        }
 
        void SelectionChanged(Selection selection)
        {
            this.selectedModelItem = selection.PrimarySelection;
        } 

        // Check if unmapped breakpoint exists for the given sourceLocation, 
        // if so, mapped it to the given model item & remove it from unmapped breakpoints. 
        void TryActivateUnmappedBreakpoint(SourceLocation sourceLocation, ModelItem modelItem)
        { 
            BreakpointTypes breakpointType;
            if (this.unmappedBreakpoints.TryGetValue(sourceLocation, out breakpointType))
            {
                this.SetBreakpointType(modelItem, breakpointType); 
                this.unmappedBreakpoints.Remove(sourceLocation);
            } 
        } 

        void TryActivateAllUnmappedBreakpoints() 
        {
            if (this.unmappedBreakpoints.Count > 0)
            {
                List unmappedLocations = new List(); 
                unmappedLocations.AddRange(this.unmappedBreakpoints.Keys);
                foreach (SourceLocation unmappedLocation in unmappedLocations) 
                { 
                    ModelItem modelItem = this.GetModelItemFromSourceLocation(unmappedLocation);
                    if (modelItem != null) 
                    {
                        TryActivateUnmappedBreakpoint(unmappedLocation, modelItem);
                    }
                } 
            }
        } 
 
        bool IsBreakpointOfType(ModelItem modelItem, BreakpointTypes breakpoinType)
        { 
            bool result = false;
            BreakpointTypes actualBreakpointType;
            TryActivateAllUnmappedBreakpoints();
            if (this.breakpoints.TryGetValue(modelItem, out actualBreakpointType)) 
            {
                result = (actualBreakpointType & breakpoinType) > 0; 
            } 
            return result;
        } 


        void SetBreakpointType(ModelItem modelItem, BreakpointTypes newBreakpointType)
        { 
            BreakpointTypes oldBreakpointType = BreakpointTypes.None;
            if (this.breakpoints.TryGetValue(modelItem, out oldBreakpointType)) 
            { 
                Fx.Assert(oldBreakpointType != BreakpointTypes.None, "Should not store BreakpointType.None");
                if (newBreakpointType == BreakpointTypes.None) 
                {
                    this.breakpoints.Remove(modelItem);
                }
                else 
                {
                    this.breakpoints[modelItem] = newBreakpointType; 
                } 
            }
            else if (newBreakpointType != BreakpointTypes.None) 
            {
                this.breakpoints.Add(modelItem, newBreakpointType);
            }
 
            // Now notifying corresponding properties.
            if ((oldBreakpointType & BreakpointTypes.Bounded) != 
                (newBreakpointType & BreakpointTypes.Bounded)) 
            {
                this.isBreakpointBoundedProperty.NotifyPropertyChanged(modelItem); 
            }

            if ((oldBreakpointType & BreakpointTypes.Enabled) !=
                (newBreakpointType & BreakpointTypes.Enabled)) 
            {
                this.isBreakpointEnabledProperty.NotifyPropertyChanged(modelItem); 
            } 

            if ((oldBreakpointType & BreakpointTypes.Conditional) != 
                (newBreakpointType & BreakpointTypes.Conditional))
            {
                this.isBreakpointConditionalProperty.NotifyPropertyChanged(modelItem);
            } 
        }
 
        // Return exact source location given approximate location. 
        public SourceLocation GetExactLocation(SourceLocation approximateLocation)
        { 
            if (approximateLocation == null)
            {
                throw FxTrace.Exception.ArgumentNull("approximateLocation");
            } 

            SourceLocation exactLocation = null; 
 
            foreach (SourceLocation sourceLocation in this.instanceToSourceLocationMapping.Values)
            { 
                if (sourceLocation.StartLine == approximateLocation.StartLine)
                {
                    exactLocation = sourceLocation;
                    break; 
                }
            } 
 
            if (exactLocation == null)
            {   // Find the next line of the approximateLocation. 
                int minimumDistance = int.MaxValue;
                foreach (SourceLocation sourceLocation in this.instanceToSourceLocationMapping.Values)
                {
                    int lineDistance = sourceLocation.StartLine - approximateLocation.StartLine; 
                    if ((lineDistance > 0) &&
                        ((lineDistance < minimumDistance) || 
                         ((lineDistance == minimumDistance) && (sourceLocation.StartColumn < exactLocation.StartColumn))))  // if same distance, then compare the start column 
                    {
                        exactLocation = sourceLocation; 
                        minimumDistance = lineDistance;
                    }
                }
            } 

            return exactLocation; 
        } 

        // Called after a Save by AddIn to update breakpoints with new locations 
        public IDictionary GetBreakpointLocations()
        {
            IDictionary breakpointLocations = new Dictionary();
 
            // Collect source locations of model items with breakpoints
            if (this.breakpoints.Count > 0 || this.unmappedBreakpoints.Count > 0) 
            { 
                foreach (KeyValuePair entry in this.breakpoints)
                { 
                    SourceLocation breakpointLocation = this.GetSourceLocationFromModelItem(entry.Key);
                    // BreakpointLocation can be null, if the model item is deleted but without notification
                    // through OnModelChanged.  This happens when the breakpoint is located inside child
                    // activity of a deleted activity. 
                    if (breakpointLocation != null)
                    { 
                        breakpointLocations.Add(breakpointLocation, entry.Value); 
                    }
                } 
                foreach (KeyValuePair entry in this.unmappedBreakpoints)
                {
                    breakpointLocations.Add(entry.Key, entry.Value);
                } 
            }
            return breakpointLocations; 
        } 

        // Inserting a new breakpoint of a given type. 
        public void InsertBreakpoint(SourceLocation sourceLocation, BreakpointTypes breakpointType)
        {
            this.UpdateBreakpoint(sourceLocation, breakpointType);
        } 

        // Update the appearance of a given breakpoint to show the given type. 
        public void UpdateBreakpoint(SourceLocation sourceLocation, BreakpointTypes newBreakpointType) 
        {
            ModelItem modelItem = this.GetModelItemFromSourceLocation(sourceLocation); 
            if (modelItem != null)
            {
                SetBreakpointType(modelItem, newBreakpointType);
            } 
            else
            { 
                BreakpointTypes oldBreakpointType; 
                if (this.unmappedBreakpoints.TryGetValue(sourceLocation, out oldBreakpointType))
                { 
                    if (newBreakpointType == BreakpointTypes.None)
                    {
                        this.unmappedBreakpoints.Remove(sourceLocation);
                    } 
                    else
                    { 
                        this.unmappedBreakpoints[sourceLocation] = newBreakpointType; 
                    }
                } 
                else if (newBreakpointType != BreakpointTypes.None)
                {
                    this.unmappedBreakpoints.Add(sourceLocation, newBreakpointType);
                } 
            }
        } 
 

        // Delete a breakpoint. 
        public void DeleteBreakpoint(SourceLocation sourceLocation)
        {
            UpdateBreakpoint(sourceLocation, BreakpointTypes.None);
        } 

        // Reset breakpoints: delete and prepare for breakpoint refresh. 
        public void ResetBreakpoints() 
        {
            ModelItem[] oldModelItems = new ModelItem[this.breakpoints.Keys.Count]; 
            this.breakpoints.Keys.CopyTo(oldModelItems, 0);
            this.breakpoints.Clear();
            this.unmappedBreakpoints.Clear();
 
            // Now notifying update to corresponding properties.
            foreach (ModelItem modelItem in oldModelItems) 
            { 
                this.isBreakpointBoundedProperty.NotifyPropertyChanged(modelItem);
                this.isBreakpointEnabledProperty.NotifyPropertyChanged(modelItem); 
                this.isBreakpointConditionalProperty.NotifyPropertyChanged(modelItem);
            }

        } 

        // Called by Addin after Load/Save.  Addin collects the new mapping from SourceLocationMapping. 
        public void UpdateSourceLocations(Dictionary newSourceLocationMapping) 
        {
            if (newSourceLocationMapping == null) 
            {
                throw FxTrace.Exception.ArgumentNull("newSourceLocationMapping");
            }
 
            // Update unmappedBreakpoints before refreshing the instanceToSourceLocationMapping.
            if (this.unmappedBreakpoints.Count > 0) 
            { 
                Dictionary newUnmappedBreakpoints = new Dictionary(this.unmappedBreakpoints.Count);
                foreach (KeyValuePair kvpEntry in this.instanceToSourceLocationMapping) 
                {
                    if (this.unmappedBreakpoints.ContainsKey(kvpEntry.Value))
                    {
                        Fx.Assert(newSourceLocationMapping.ContainsKey(kvpEntry.Key), "Activity is not found in the newSourceLocationMapping"); 
                        newUnmappedBreakpoints.Add(newSourceLocationMapping[kvpEntry.Key], this.unmappedBreakpoints[kvpEntry.Value]);
                    } 
                } 
                this.unmappedBreakpoints = newUnmappedBreakpoints;
            } 
            this.instanceToSourceLocationMapping = newSourceLocationMapping;
            this.sourceLocationToModelItem.Clear();
            this.modelItemToSourceLocation.Clear();
            this.transientBreakpoints.Clear(); 
            this.transientUnresolvedActivities.Clear();
 
            this.lastSourceLineNo = 1; 

            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 

            if (modelTreeManager != null)
            {
                foreach (KeyValuePair kvp in newSourceLocationMapping) 
                {
                    ModelItem modelItem = modelTreeManager.GetModelItem(kvp.Key); 
                    if (modelItem != null) 
                    {
                        SourceLocation sourceLocation = kvp.Value; 
                        this.sourceLocationToModelItem.Add(sourceLocation, modelItem);
                        this.modelItemToSourceLocation.Add(modelItem, sourceLocation);
                    }
                } 
            }
            TryActivateAllUnmappedBreakpoints(); 
        } 

        // Called by View Service when a new view element is added 
        void ViewChanged(object sender, WorkflowViewService.ViewChangedEventArgs e)
        {
            if (e.AddedElement != null)
            { 
                ModelItem modelItem = e.AddedElement.ModelItem;
                Activity activity = modelItem.GetCurrentValue() as Activity; 
 
                if (activity != null)
                { // Only care for ViewChanged for Activity. 

                    // Create a mapping between SourceLocation and this View Element
                    SourceLocation sourceLocation = this.GetSourceLocationFromModelItemInstance(activity);
                    if (sourceLocation == null) 
                    {
                        // Check if this is for moving an unresolved activity. 
                        if (!this.transientUnresolvedActivities.TryGetValue(activity, out sourceLocation)) 
                        {
                            // The current view element has not been saved yet to the Xaml file 
                            sourceLocation = GenerateUnresolvedLocation();
                        }
                        this.instanceToSourceLocationMapping.Add(activity, sourceLocation);
                    } 

                    this.modelItemToSourceLocation[modelItem] = sourceLocation; 
                    this.sourceLocationToModelItem[sourceLocation] = modelItem; 

                    BreakpointTypes breakpointType; 
                    // check if it's in the transient breakpoint list.
                    if (this.transientBreakpoints.TryGetValue(modelItem, out breakpointType))
                    {
                        this.transientBreakpoints.Remove(modelItem); 
                        SetBreakpointType(modelItem, breakpointType);
                    } 
                    else 
                    {
                        TryActivateUnmappedBreakpoint(sourceLocation, modelItem); 
                    }
                }
            }
        } 

        SourceLocation GenerateUnresolvedLocation() 
        { 
            return new SourceLocation(unresolvedPrefix + this.context.Items.GetValue().LoadedFile, this.lastSourceLineNo++);
        } 

        static bool IsUnresolved(SourceLocation sourceLocation)
        {
            return !string.IsNullOrEmpty(sourceLocation.FileName) && sourceLocation.FileName.StartsWith(unresolvedPrefix, StringComparison.OrdinalIgnoreCase); 
        }
 
        void OnViewServiceAvailable(ViewService viewService) 
        {
            this.viewService = viewService as WorkflowViewService; 
            this.viewService.ViewChanged += new WorkflowViewService.ViewChangedEventHandler(this.ViewChanged);
        }

        SourceLocation GetSourceLocationFromModelItemInstance(object instance) 
        {
            SourceLocation sourceLocation; 
 
            // instanceToSourceLocationMapping contains source locations for all instances
            // immediately after a Load or save.  For instances that have been just dropped into 
            // the Designer from the Toolbox, we want to return null from here and treat them
            // as "Unresolved" in the caller.
            if (this.instanceToSourceLocationMapping.TryGetValue(instance, out sourceLocation))
            { 
                return sourceLocation;
            } 
            else 
            {
                return null; 
            }
        }

        void SetPropertyValue(ModelItem oldModelItem, AttachedProperty property, ModelItem newModelItem) 
        {
            // update the previous ModelItem (what was current before) 
            if (oldModelItem != null) 
            {
                property.NotifyPropertyChanged(oldModelItem); 
            }

            // update the current Modelitem
            if (newModelItem != null) 
            {
                property.NotifyPropertyChanged(newModelItem); 
            } 
        }
 
        SourceLocation GetSourceLocationFromModelItem(ModelItem modelItem)
        {
            SourceLocation sourceLocation = null;
            if (modelItem != null) 
            {
                this.modelItemToSourceLocation.TryGetValue(modelItem, out sourceLocation); 
            } 
            return sourceLocation;
        } 

        ModelItem GetModelItemFromSourceLocation(SourceLocation sourceLocation)
        {
            return GetModelItemFromSourceLocation(sourceLocation, /* forceCreate = */ false); 
        }
 
        ModelItem GetModelItemFromSourceLocation(SourceLocation sourceLocation, bool forceCreate) 
        {
            ModelItem modelItem = null; 
            if (sourceLocation != null)
            {
                if (!this.sourceLocationToModelItem.TryGetValue(sourceLocation, out modelItem))
                { 
                    if (forceCreate)
                    { 
                        Activity foundElement = null; 
                        foreach (KeyValuePair kvp in this.instanceToSourceLocationMapping)
                        { 
                            if (kvp.Value.Equals(sourceLocation))
                            {
                                foundElement = kvp.Key as Activity;
                                break; 
                            }
                        } 
                        if (foundElement != null) 
                        {
 
                            List parentChain = Validation.ValidationService.GetParentChain(foundElement);
                            Fx.Assert(parentChain != null, "Cannot find parent chain for " + foundElement.DisplayName);

                            ModelTreeManager modelTreeManager = this.context.Services.GetService(); 
                            Fx.Assert(modelTreeManager != null, "ModelTreeManager is null."); // ModelTreeManager should not be null
 
                            ModelItem lowestModelItem = null; 
                            foreach (Activity parent in parentChain)
                            { 
                                lowestModelItem = modelTreeManager.GetModelItem(parent);
                                if (lowestModelItem != null)
                                {
                                    break; 
                                }
                            } 
 
                            if (lowestModelItem != null)
                            { 
                                // Walk the tree to create all the model items until it found the model item for the element.
                                modelItem = modelTreeManager.FindFirst(lowestModelItem, (mi) => (mi.GetCurrentValue() == foundElement));

                                if (modelItem != null) 
                                {
                                    this.modelItemToSourceLocation.Add(modelItem, sourceLocation); 
                                    this.sourceLocationToModelItem.Add(sourceLocation, modelItem); 
                                }
                            } 
                        }
                    }
                }
            } 
            return modelItem;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

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