CompModHelpers.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / Shared / CompModHelpers.cs / 1305376 / CompModHelpers.cs

                            // Copyright (c) Microsoft Corporation. All rights reserved. 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
// THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
// AND INFORMATION REMAINS WITH THE USER. 
 

/********************************************************************** 
 * NOTE: A copy of this file exists at: WF\Activities\Common
 * The two files must be kept in [....].  Any change made here must also
 * be made to WF\Activities\Common\CompModHelpers.cs
*********************************************************************/ 
namespace System.Workflow.ComponentModel.Design
{ 
    using System; 
    using System.CodeDom;
    using System.Collections; 
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.ComponentModel.Design; 
 	using System.ComponentModel.Design.Serialization;
	using System.Workflow.ComponentModel.Serialization; 
	using System.IO; 
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Windows.Forms; 
    using System.Drawing;
    using System.Drawing.Design;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Compiler; 
    using System.Text;
    using System.Reflection; 
    using System.Xml; 
    using System.Globalization;
    using Microsoft.Win32; 
    using System.Runtime.InteropServices;
    using System.Diagnostics.CodeAnalysis;

    #region Class Helpers 
    internal static class Helpers
    { 
        private static readonly string VSExtensionProductRegistrySubKey = "Visual Studio Ext for Windows Workflow"; 
        //
 
        internal static readonly string ProductRootRegKey = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v4.0\Setup\Windows Workflow Foundation";
        internal static readonly string ProductInstallDirectory = GetInstallDirectory(false);
        internal static readonly string ProductSDKInstallDirectory = GetInstallDirectory(true);
        internal static readonly string TypeProviderAssemblyRegValueName = "References"; 

        private static readonly string ProductRootRegKey30 = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.0\Setup\Windows Workflow Foundation"; 
        internal static readonly string ProductInstallDirectory30 = GetInstallDirectory30(); 

        private const string ProductCode = "{B644FB52-BB3D-4C43-80EC-57644210536A}"; 
        private const string ProductSDKCode = "{C8A7718A-FF6D-4DDC-AE36-BBF968D6799B}";
        private const string INSTALLPROPERTY_INSTALLLOCATION = "InstallLocation";

        internal const int FILENAME_MAX = 260; //"stdio.h" 

        [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "LastIndexOf(\"\\\") not a security issue.")] 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static string PerUserRegistryKey
        { 
            get
            {
                string keyPath = String.Empty;
                using (RegistryKey userRegistryKey = Application.UserAppDataRegistry) 
                {
                    keyPath = userRegistryKey.ToString().Substring(Registry.CurrentUser.ToString().Length + 1); 
                    keyPath = keyPath.Substring(0, keyPath.LastIndexOf("\\")); 
                    keyPath += "\\" + VSExtensionProductRegistrySubKey;
                } 
                return keyPath;
            }
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private static string TypeProviderRegistryKeyPath 
        { 
            get
            { 
                return PerUserRegistryKey + "\\TypeProvider";
            }
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool IsFileNameValid(string fileName) 
        { 
            int length = Path.GetInvalidPathChars().GetLength(0) + 5;
            char[] invalidChars = new char[length]; 
            Path.GetInvalidPathChars().CopyTo(invalidChars, 0);
            invalidChars[length - 5] = ':';
            invalidChars[length - 4] = '?';
            invalidChars[length - 3] = '*'; 
            invalidChars[length - 2] = '/';
            invalidChars[length - 1] = '\\'; 
 
            return (fileName != null &&
                    fileName.Length != 0 && 
                    fileName.Length <= FILENAME_MAX &&
                    fileName.IndexOfAny(invalidChars) == -1);
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool AreAllActivities(ICollection c) 
        { 
            if (c == null)
                throw new ArgumentNullException("c"); 

            foreach (object obj in c)
            {
                if (!(obj is Activity)) 
                    return false;
            } 
            return true; 
        }
 
        // this will return IDictionary, whose keys are parent and value is arraylist of child activities
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static IDictionary PairUpCommonParentActivities(ICollection activities)
        { 
            if (activities == null)
                throw new ArgumentNullException("activities"); 
 
            Hashtable commonParentActivities = new Hashtable();
            foreach (Activity activity in activities) 
            {
                if (activity.Parent != null)
                {
                    ArrayList childActivities = (ArrayList)commonParentActivities[activity.Parent]; 
                    if (childActivities == null)
                    { 
                        childActivities = new ArrayList(); 
                        commonParentActivities.Add(activity.Parent, childActivities);
                    } 
                    childActivities.Add(activity);
                }
            }
            return commonParentActivities; 
        }
 
        // this will remove any activity from the collection whose parent is already there in the collection 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static Activity[] GetTopLevelActivities(ICollection activities) 
        {
            if (activities == null)
                throw new ArgumentNullException("activities");
 
            List filteredActivities = new List();
            foreach (object obj in activities) 
            { 
                Activity activity = obj as Activity;
                if (activity != null) 
                {
                    bool foundParent = false;
                    Activity parentActivity = activity.Parent;
                    while (parentActivity != null && !foundParent) 
                    {
                        foreach (object obj2 in activities) 
                        { 
                            if (obj2 == parentActivity)
                            { 
                                foundParent = true;
                                break;
                            }
                        } 
                        parentActivity = parentActivity.Parent;
                    } 
 
                    if (!foundParent)
                        filteredActivities.Add(activity); 
                }
            }
            return filteredActivities.ToArray();
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Activity[] GetNestedActivities(CompositeActivity compositeActivity) 
        {
 
            if (compositeActivity == null)
                throw new ArgumentNullException("compositeActivity");

            IList childActivities = null; 
            ArrayList nestedActivities = new ArrayList();
            Queue compositeActivities = new Queue(); 
            compositeActivities.Enqueue(compositeActivity); 
            while (compositeActivities.Count > 0)
            { 
                CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
                childActivities = compositeActivity2.Activities;

                foreach (Activity activity in childActivities) 
                {
                    nestedActivities.Add(activity); 
                    if (activity is CompositeActivity) 
                        compositeActivities.Enqueue(activity);
                } 
            }
            return (Activity[])nestedActivities.ToArray(typeof(Activity));
        }
 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static IList GetIdentifiersInCompositeActivity(CompositeActivity compositeActivity) 
        {
            ArrayList identifiers = new ArrayList(); 
            if (compositeActivity != null)
            {
                identifiers.Add(compositeActivity.Name);
                IList allChildren = GetAllNestedActivities(compositeActivity); 
                foreach (Activity activity in allChildren)
                    identifiers.Add(activity.Name); 
            } 
            return ArrayList.ReadOnly(identifiers);
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static Activity[] GetAllNestedActivities(CompositeActivity compositeActivity)
        { 
            if (compositeActivity == null)
                throw new ArgumentNullException("compositeActivity"); 
 
			ArrayList nestedActivities = new ArrayList();
 
 	    // Note: GetAllNestedActivities will not check for black box activities.
            // This is to allow it to be invoked from within the activity's
            // constructor.
            //if(Helpers.IsCustomActivity(compositeActivity)) 
                //return (Activity[])nestedActivities.ToArray(typeof(Activity));
 
            Queue compositeActivities = new Queue(); 
            compositeActivities.Enqueue(compositeActivity);
            while (compositeActivities.Count > 0) 
            {
                CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
                if (compositeActivity2 == compositeActivity || !Helpers.IsCustomActivity(compositeActivity2))
                { 
                    foreach (Activity activity in compositeActivity2.Activities)
                    { 
                        nestedActivities.Add(activity); 
                        if (activity is CompositeActivity)
                            compositeActivities.Enqueue(activity); 
                    }

                    foreach (Activity activity in compositeActivity2.EnabledActivities)
                    { 
                        if (!nestedActivities.Contains(activity))
                        { 
                            nestedActivities.Add(activity); 
                            if (activity is CompositeActivity)
                                compositeActivities.Enqueue(activity); 
                        }
                    }
                }
            } 
            return (Activity[])nestedActivities.ToArray(typeof(Activity));
        } 
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static string MergeNamespaces(string primaryNs, string secondaryNs) 
        {
            string newNs = primaryNs;
            if (secondaryNs != null && secondaryNs.Length > 0)
            { 
                if (newNs != null && newNs.Length > 0)
                    newNs += ("." + secondaryNs); 
                else 
                    newNs = secondaryNs;
            } 

            if (newNs == null)
                newNs = string.Empty;
            return newNs; 
        }
 
        internal static Activity GetRootActivity(Activity activity) 
		{
 			if (activity == null) 
 				throw new ArgumentNullException("activity");

            while (activity.Parent != null)
                activity = activity.Parent; 

            return activity; 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Stream SerializeDesignersToStream(ICollection activities)
        {
            Stream stateStream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(stateStream); 

            Queue serializedComponents = new Queue(); 
            foreach (IComponent activity in activities) 
                serializedComponents.Enqueue(activity);
 
            while (serializedComponents.Count > 0)
            {
                IComponent component = serializedComponents.Dequeue();
                if (component != null && component.Site != null) 
                {
                    IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost; 
                    if (designerHost == null) 
                        throw new InvalidOperationException(
							SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name)); 

                    ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
                    if (activityDesigner != null)
                    { 
                        try
                        { 
                            ((IPersistUIState)activityDesigner).SaveViewState(writer); 

                            CompositeActivity compositeActivity = component as CompositeActivity; 
                            if (compositeActivity != null)
                            {
                                foreach (IComponent childActivity in compositeActivity.Activities)
                                { 
                                    serializedComponents.Enqueue(childActivity);
                                } 
                            } 
                        }
                        catch 
                        {
                        }
                    }
                } 
            }
 
            return stateStream; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static void DeserializeDesignersFromStream(ICollection activities, Stream stateStream)
        {
            if (stateStream.Length == 0) 
                return;
 
            BinaryReader reader = new BinaryReader(stateStream); 
            stateStream.Seek(0, SeekOrigin.Begin);
 
            Queue serializedComponents = new Queue();
            foreach (IComponent component in activities)
                serializedComponents.Enqueue(component);
 
            while (serializedComponents.Count > 0)
            { 
                IComponent component = serializedComponents.Dequeue(); 
                if (component != null && component.Site != null)
                { 
                    IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
                    if (designerHost == null)
                        throw new InvalidOperationException(
 							SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name)); 

                    ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner; 
                    if (activityDesigner != null) 
                    {
                        try 
                        {
                            ((IPersistUIState)activityDesigner).LoadViewState(reader);

                            CompositeActivity compositeActivity = component as CompositeActivity; 
                            if (compositeActivity != null)
                            { 
                                foreach (IComponent childActivity in compositeActivity.Activities) 
                                {
                                    serializedComponents.Enqueue(childActivity); 
                                }
                            }
                        }
                        catch 
                        {
                        } 
                    } 
                }
            } 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static string GetBaseIdentifier(Activity activity) 
        {
            string baseIdentifier = activity.GetType().Name; 
            StringBuilder b = new StringBuilder(baseIdentifier.Length); 
            for (int i = 0; i < baseIdentifier.Length; i++)
            { 
                if (Char.IsUpper(baseIdentifier[i]) && (i == 0 || i == baseIdentifier.Length - 1 || Char.IsUpper(baseIdentifier[i + 1])))
                {
                    b.Append(Char.ToLowerInvariant(baseIdentifier[i]));
                } 
                else
                { 
                    b.Append(baseIdentifier.Substring(i)); 
                    break;
                } 
            }
            return b.ToString();
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		internal static string GetRootNamespace(IServiceProvider serviceProvider) 
		{ 
			if (serviceProvider == null)
 				throw new ArgumentNullException("serviceProvider"); 

            string rootNs = string.Empty;
            IWorkflowCompilerOptionsService compilerOptionsService = (IWorkflowCompilerOptionsService)serviceProvider.GetService(typeof(IWorkflowCompilerOptionsService));
            if (compilerOptionsService != null && compilerOptionsService.RootNamespace != null) 
                rootNs = compilerOptionsService.RootNamespace; //e.g. WorkflowApp1
            return rootNs; 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Type GetDataSourceClass(Activity activity, IServiceProvider serviceProvider)
        {
			if (activity == null)
 				throw new ArgumentNullException("activity"); 
 			if (serviceProvider == null)
				throw new ArgumentNullException("serviceProvider"); 
 
            Type activityType = null;
            string className = null; 
            if (activity == GetRootActivity(activity))
                className = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;

 			if (!String.IsNullOrEmpty(className)) 
			{
				ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider)); 
				if (typeProvider == null) 
 					throw new InvalidOperationException(
						SR.GetString(SR.General_MissingService, typeof(ITypeProvider).Name)); 

                activityType = typeProvider.GetType(className);
            }
            else 
            {
                return activity.GetType(); 
            } 

            return activityType; 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static Activity GetDataSourceActivity(Activity activity, string inputName, out string name) 
        {
            if (activity == null) 
                throw new ArgumentNullException("activity"); 
            if (string.IsNullOrEmpty(inputName))
                throw new ArgumentException("inputName"); 

            name = inputName;
            if (inputName.IndexOf('.') == -1)
                return activity; 

            int indexOfDot = inputName.LastIndexOf('.'); 
            string scopeID = inputName.Substring(0, indexOfDot); 
            name = inputName.Substring(indexOfDot + 1);
 
            Activity contextActivity = Helpers.ParseActivityForBind(activity, scopeID);
            if (contextActivity == null)
                contextActivity = Helpers.ParseActivity(Helpers.GetRootActivity(activity), scopeID);
 
            // activity can be either the qualified id of the scope activity or the qualified id of the custom activity.
            return contextActivity; 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static void GetNamespaceAndClassName(string fullQualifiedName, out string namespaceName, out string className)
        {
            namespaceName = String.Empty;
            className = String.Empty; 

            if (fullQualifiedName == null) 
                return; 

            int indexOfDot = fullQualifiedName.LastIndexOf('.'); 
            if (indexOfDot != -1)
            {
                namespaceName = fullQualifiedName.Substring(0, indexOfDot);
                className = fullQualifiedName.Substring(indexOfDot + 1); 
            }
            else 
            { 
                className = fullQualifiedName;
            } 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static CodeTypeDeclaration GetCodeNamespaceAndClass(CodeNamespaceCollection namespaces, string namespaceName, string className, out CodeNamespace codeNamespace) 
        {
            codeNamespace = null; 
            foreach (CodeNamespace ns in namespaces) 
            {
                if (ns.Name == namespaceName) 
                {
                    codeNamespace = ns;
                    break;
                } 
            }
 
            CodeTypeDeclaration codeTypeDeclaration = null; 
            if (codeNamespace != null)
            { 
                foreach (CodeTypeDeclaration typeDecl in codeNamespace.Types)
                {
                    if (typeDecl.Name == className)
                    { 
                        codeTypeDeclaration = typeDecl;
                        break; 
                    } 
                }
            } 
            return codeTypeDeclaration;
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static string GetClassName(string fullQualifiedName)
        { 
            if (fullQualifiedName == null) 
                return null;
 
            string className = fullQualifiedName;
            int indexOfDot = fullQualifiedName.LastIndexOf('.');
            if (indexOfDot != -1)
                className = fullQualifiedName.Substring(indexOfDot + 1); 
            return className;
        } 
 

        [DllImport("msi.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)] 
        private static extern int MsiGetProductInfoW(string szProduct, string szProperty, StringBuilder lpValueBuf, ref int pcchValueBuf);
        private static string GetInstallDirectory(bool getSDKDir)
        {
            string path = string.Empty; 
            try
            { 
                //ERROR_UNKNOWN_PROPERTY           1608L 
                //ERROR_INVALID_PARAMETER          87L
                int length = FILENAME_MAX + 1; 
                StringBuilder location = new StringBuilder(length);
                int hr = MsiGetProductInfoW(getSDKDir ? ProductSDKCode : ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
                int error = Marshal.GetLastWin32Error();
                if (hr == 0) 
                {
                    path = location.ToString(); 
                } 
                else
                { 
                    Debug.WriteLine("Error loading install directory: " + error.ToString(CultureInfo.CurrentCulture));
                }

            } 
            catch
            { 
            } 

            if (string.IsNullOrEmpty(path)) 
            {
                try
                {
                    if (!getSDKDir) 
                    {
                        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey)) 
                        { 
                            if (key != null)
                                path = (string)key.GetValue("InstallDir"); 
                        }
                    }
                }
                catch 
                {
                } 
            } 

            // 
            if (string.IsNullOrEmpty(path))
                path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            return path; 
        }
 
        private static string GetInstallDirectory30() 
        {
            string path = string.Empty; 
            try
            {
                //ERROR_UNKNOWN_PROPERTY           1608L
                //ERROR_INVALID_PARAMETER          87L 
                int length = FILENAME_MAX + 1;
                StringBuilder location = new StringBuilder(length); 
                int hr = MsiGetProductInfoW(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length); 
                int error = Marshal.GetLastWin32Error();
                if (hr == 0) 
                {
                    path = location.ToString();
                }
                else 
                {
                    Debug.WriteLine("Error loading 3.0 install directory: " + error.ToString(CultureInfo.CurrentCulture)); 
                } 

            } 
            catch
            {
            }
 
            if (string.IsNullOrEmpty(path))
            { 
                try 
                {
                    using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey30)) 
                    {
                        if (key != null)
                        {
                            path = (string)key.GetValue("InstallDir"); 
                        }
                    } 
                } 
                catch
                { 
                }
            }

            return path; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Type GetBaseType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
        { 
            //When we are emitting code for the dynamic properties we might get the propertyinfo as null
            if (owner == null)
                throw new ArgumentNullException("owner");
 
            if (serviceProvider == null)
                throw new ArgumentNullException("serviceProvider"); 
 
            if (property != null)
            { 
                IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
                if (basetypeProvider != null)
                {
                    Type type = basetypeProvider.GetPropertyType(serviceProvider, property.Name); 
                    if (type != null)
                        return type; 
                } 

                return property.PropertyType; 
            }

            return null;
        } 

        // 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static AccessTypes GetAccessType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
        { 
            //When we are emitting code for the dynamic properties we might get the propertyinfo as null
            if (owner == null)
                throw new ArgumentNullException("owner");
 
            if (serviceProvider == null)
                throw new ArgumentNullException("serviceProvider"); 
 
            if (property != null)
            { 
                IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
                if (basetypeProvider != null)
                    return basetypeProvider.GetAccessType(serviceProvider, property.Name);
            } 

            return AccessTypes.Read; 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static bool IsChildActivity(CompositeActivity parent, Activity activity)
        {
            foreach (Activity containedActivity in parent.Activities)
            { 
                if (activity == containedActivity)
                    return true; 
 
                if (containedActivity is CompositeActivity &&
                    Helpers.IsChildActivity(containedActivity as CompositeActivity, activity)) 
                    return true;
            }

            return false; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static bool TypesEqual(CodeTypeReference typeLeft, Type typeRight)
        { 
            if (typeRight.IsArray && typeLeft.ArrayRank != typeRight.GetArrayRank()) return false;
            //
            if (!typeLeft.BaseType.Equals(typeRight.FullName)) return false;
 
            if (typeLeft.ArrayRank > 0)
                return TypesEqual(typeLeft.ArrayElementType, typeRight.GetElementType()); 
            return true; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool TypesEqual(CodeTypeReference typeLeft, CodeTypeReference typeRight)
        {
            if (typeLeft.ArrayRank != typeRight.ArrayRank) return false; 
            if (!typeLeft.BaseType.Equals(typeRight.BaseType)) return false;
 
            if (typeLeft.ArrayRank > 0) 
                return TypesEqual(typeLeft.ArrayElementType, typeRight.ArrayElementType);
            return true; 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static DesignerSerializationVisibility GetSerializationVisibility(MemberInfo memberInfo) 
        {
 
            if (memberInfo == null) 
                throw new ArgumentNullException("memberInfo");
 
            DesignerSerializationVisibility designerSerializationVisibility = DesignerSerializationVisibility.Visible;

            // Calling GetCustomAttributes on PropertyInfo or EventInfo when the inherit parameter of GetCustomAttributes
            // is true does not walk the type hierarchy. But System.Attribute.GetCustomAttributes causes perf issues. 
            object[] attributes = memberInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true);
            if (attributes.Length > 0) 
                designerSerializationVisibility = (attributes[0] as DesignerSerializationVisibilityAttribute).Visibility; 
            else if (Attribute.IsDefined(memberInfo, typeof(DesignerSerializationVisibilityAttribute)))
                designerSerializationVisibility = (Attribute.GetCustomAttribute(memberInfo, typeof(DesignerSerializationVisibilityAttribute)) as DesignerSerializationVisibilityAttribute).Visibility; 

            return designerSerializationVisibility;
        }
 
        // Method parameters must match exactly
        // 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static MethodInfo GetMethodExactMatch(Type type, string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
        { 
            MethodInfo foundMethod = null;
            MethodInfo[] methods = type.GetMethods(bindingAttr);
            foreach (MethodInfo method in methods)
            { 
                bool matchName = ((bindingAttr & BindingFlags.IgnoreCase) == BindingFlags.IgnoreCase) ? string.Compare(method.Name, name, StringComparison.OrdinalIgnoreCase) == 0 : string.Compare(method.Name, name, StringComparison.Ordinal) == 0;
                if (matchName) 
                { 
                    bool mismatch = false;
                    if (types != null) 
                    {
                        ParameterInfo[] parameters = method.GetParameters();
                        if (parameters.GetLength(0) == types.Length)
                        { 
                            for (int index = 0; !mismatch && index < parameters.Length; index++)
                                mismatch = (parameters[index].ParameterType == null) || (!parameters[index].ParameterType.IsAssignableFrom(types[index])); 
                        } 
                        else
                            mismatch = true; 
                    }
                    if (!mismatch)
                    {
                        foundMethod = method; 
                        break;
                    } 
                } 
            }
 
            return foundMethod;
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static T GetAttributeFromObject(object attributeObject) where T : Attribute
        { 
            if (attributeObject is AttributeInfoAttribute) 
                return (T)((AttributeInfoAttribute)attributeObject).AttributeInfo.CreateAttribute();
 
            if (attributeObject is T)
                return (T)attributeObject;

            return null; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Type GetDelegateFromEvent(EventInfo eventInfo)
        { 
            if (eventInfo.EventHandlerType != null)
                return eventInfo.EventHandlerType;

            return TypeProvider.GetEventHandlerType(eventInfo); 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static void AddTypeProviderAssembliesFromRegistry(TypeProvider typeProvider, IServiceProvider serviceProvider)
        { 
            if (typeProvider == null)
                throw new ArgumentNullException("typeProvider");
            if (serviceProvider == null)
                throw new ArgumentNullException("serviceProvider"); 

            RegistryKey referenceKey = Registry.CurrentUser.OpenSubKey(TypeProviderRegistryKeyPath); 
            if (referenceKey != null) 
            {
                ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator; 
                foreach (string assemblyName in ((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName)))
                {
                    try
                    { 
                        if (typeProviderCreator != null)
                        { 
                            bool addAssembly = true; 
                            Assembly assembly = typeProviderCreator.GetTransientAssembly(AssemblyName.GetAssemblyName(assemblyName));
                            // Check to see if a copy of the assembly is already added. 
                            if (assembly != null)
                            {
                                foreach (Type type in assembly.GetTypes())
                                { 
                                    if (typeProvider.GetType(type.AssemblyQualifiedName) != null)
                                        addAssembly = false; 
                                    break; 
                                }
                                if (addAssembly) 
                                    typeProvider.AddAssembly(assembly);
                            }
                        }
                        else 
                            // AddAssemblyReference should take care of duplicates.
                            typeProvider.AddAssemblyReference(assemblyName); 
 
                    }
                    catch 
                    {
                        // Continue loading.
                    }
                } 

                referenceKey.Close(); 
            } 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static void UpdateTypeProviderAssembliesRegistry(string assemblyName)
        {
            RegistryKey referenceKey = Registry.CurrentUser.CreateSubKey(TypeProviderRegistryKeyPath); 
            if (referenceKey != null)
            { 
                try 
                {
                    ArrayList references = null; 
                    if (referenceKey.ValueCount > 0)
                        references = new ArrayList((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName));
                    else
                        references = new ArrayList(); 

                    if (!references.Contains(assemblyName)) 
                    { 
                        references.Add(assemblyName);
                        referenceKey.SetValue(TypeProviderAssemblyRegValueName, ((string[])references.ToArray(typeof(string)))); 
                    }
                }
                catch
                { 
                    //We eat the exception
                } 
                finally 
                {
                    referenceKey.Close(); 
                }
            }
        }
 
        internal static CompositeActivity GetDeclaringActivity(Activity activity)
        { 
            if (activity == null) 
                throw new ArgumentNullException("activity");
 
            CompositeActivity parent = activity.Parent;
            while (parent != null)
            {
                // This will be the root 
                if (parent.Parent == null)
                    return parent; 
 
                // Any custom activity found is the declaring activity
                if (IsCustomActivity(parent)) 
                    return parent;

                parent = parent.Parent;
            } 
            return null;
        } 
 
        internal static bool IsActivityLocked(Activity activity)
        { 
            if (activity == null)
                throw new ArgumentNullException("activity");

            CompositeActivity parent = activity.Parent; 
            while (parent != null)
            { 
                // If root, not locked 
                if (parent.Parent == null)
                    return false; 

                // Any custom activity found, then locked
                if (IsCustomActivity(parent))
                    return true; 

                parent = parent.Parent; 
            } 

            return false; 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static Activity GetEnclosingActivity(Activity activity) 
        {
            Activity enclosingActivity; 
 
            if (IsActivityLocked(activity))
                enclosingActivity = Helpers.GetDeclaringActivity(activity); 
            else
                enclosingActivity = GetRootActivity(activity);

            return enclosingActivity; 
        }
 
        // This function returns all the executable activities including secondary flow activities. 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        public static IList GetAllEnabledActivities(CompositeActivity compositeActivity) 
        {
            if (compositeActivity == null)
                throw new ArgumentNullException("compositeActivity");
 
            List allActivities = new List(compositeActivity.EnabledActivities);
            foreach (Activity childActivity in compositeActivity.Activities) 
            { 
                if (childActivity.Enabled &&
                        IsFrameworkActivity(childActivity)) 
                    allActivities.Add(childActivity);
            }
            return allActivities;
        } 
        public static bool IsFrameworkActivity(Activity activity)
        { 
            return (activity is CancellationHandlerActivity || 
                        activity is CompensationHandlerActivity ||
                        activity is FaultHandlersActivity); 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static MethodInfo GetInterfaceMethod(Type interfaceType, string methodName) 
        {
            MethodInfo methodInfo = null; 
            string interfaceName = String.Empty; 
            string method = String.Empty;
 
            if (methodName.LastIndexOf('.') > 0)
            {
                interfaceName = methodName.Substring(0, methodName.LastIndexOf('.'));
                method = methodName.Substring(methodName.LastIndexOf('.') + 1); 
            }
 
            if (!String.IsNullOrEmpty(interfaceName)) 
            {
                foreach (Type inheritedInterface in interfaceType.GetInterfaces()) 
                {
                    if (String.Compare(inheritedInterface.FullName, interfaceName, StringComparison.Ordinal) == 0)
                    {
                        methodInfo = inheritedInterface.GetMethod(method); 
                        break;
                    } 
                } 
            }
            else 
            {
                methodInfo = interfaceType.GetMethod(methodName);
            }
 
            return methodInfo;
        } 
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static XmlWriter CreateXmlWriter(object output) 
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("\t"); 
            settings.OmitXmlDeclaration = true;
            settings.CloseOutput = true; 
 
            if (output is string)
                return XmlWriter.Create(output as string, settings); 
            else if (output is TextWriter)
                return XmlWriter.Create(output as TextWriter, settings);
            else
            { 
                Debug.Assert(false, "Invalid argument type.  'output' must either be string or TextWriter.");
                return null; 
            } 
        }
 
        #region DesignTimeType Support
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static string GetDesignTimeTypeName(object owner, object key)
        { 
            string typeName = null;
            DependencyObject dependencyObject = owner as DependencyObject; 
            if (dependencyObject != null && key != null) 
            {
                if (dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames)) 
                {
                    Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
                    if (typeNames != null && typeNames.ContainsKey(key))
                        typeName = typeNames[key] as string; 
                }
            } 
            return typeName; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static void SetDesignTimeTypeName(object owner, object key, string value)
        {
            DependencyObject dependencyObject = owner as DependencyObject; 
            if (dependencyObject != null && key != null)
            { 
                if (!dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames)) 
                    dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] = new Hashtable();
 
                Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
                typeNames[key] = value;
            }
        } 
        #endregion
 
        #region Helpers from ExecutableCompModHelpers 
        // This only works for composite activity.
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static bool IsCustomActivity(CompositeActivity compositeActivity)
        {
            if (compositeActivity == null)
                throw new ArgumentNullException("compositeActivity"); 

            if (compositeActivity.UserData.Contains(UserDataKeys.CustomActivity)) 
            { 
                return (bool)(compositeActivity.UserData[UserDataKeys.CustomActivity]);
            } 
            else
            {
                try
                { 
                    CompositeActivity activity = Activator.CreateInstance(compositeActivity.GetType()) as CompositeActivity;
 					if (activity != null && activity.Activities.Count > 0) 
 					{ 
						compositeActivity.UserData[UserDataKeys.CustomActivityDefaultName] = activity.Name;
 						compositeActivity.UserData[UserDataKeys.CustomActivity] = true;// 
						return true;
					}
                }
                catch 
                {
                    // 
                } 
            }
 
			compositeActivity.UserData[UserDataKeys.CustomActivity] = false;//
            return false;
        }
 
        [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Activity ParseActivity(Activity parsingContext, string activityName) 
        {
            if (parsingContext == null) 
                throw new ArgumentNullException("parsingContext");
            if (activityName == null)
                throw new ArgumentNullException("activityName");
 
            string currentAtivityName = activityName;
            string nextActivityName = string.Empty; 
            int indexOfDot = activityName.IndexOf("."); 
            if (indexOfDot != -1)
            { 
                currentAtivityName = activityName.Substring(0, indexOfDot);
                nextActivityName = activityName.Substring(indexOfDot + 1);
                if (nextActivityName.Length == 0)
                    return null; 
            }
 
            Activity currentActivity = GetActivity(parsingContext, currentAtivityName); 
            if (currentActivity != null)
            { 
                if (nextActivityName.Length > 0)
                {
                    if (!(currentActivity is CompositeActivity) || !IsCustomActivity(currentActivity as CompositeActivity))
                        // current activity must be a custom activity, otherwise there should be no dots in the name. 
                        return null;
 
                    string[] names = nextActivityName.Split('.'); 
                    for (int i = 0; i < names.Length; i++)
                    { 
                        Activity nextActivity = GetActivity(currentActivity, names[i]);
                        if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
                            return null;
 
                        CompositeActivity declaringActivity = GetDeclaringActivity(nextActivity);
                        if (currentActivity != declaringActivity) 
                            return null; 

                        currentActivity = nextActivity; 
                    }

                    return currentActivity;
                } 
                else
                { 
                    // This activity should always be unlocked, unless if GetChildActivity() is called from 
                    // within the custom activity's companion class, then we don't have the full qualified ID available
                    // at that time.  We allow this to succeed only if the declaring activity is the same as the declaring 
                    // activity of the context activity passed in.
                    if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
                    {
                        if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext)) 
                            return null;
                    } 
 
                    return currentActivity;
                } 
            }

            return null;
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static Activity ParseActivityForBind(Activity context, string activityName) 
        {
            if (context == null) 
                throw new ArgumentNullException("context");
            if (activityName == null)
                throw new ArgumentNullException("activityName");
 
            if (string.Equals(activityName, "/Self", StringComparison.Ordinal))
            { 
                return context; 
            }
            else if (activityName.StartsWith("/Parent", StringComparison.OrdinalIgnoreCase)) 
            {
                Activity activity = context;
                string[] paths = activityName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < paths.Length && activity != null; i++) 
                {
                    string parent = paths[i].Trim(); 
                    activity = (string.Equals(parent, "Parent", StringComparison.OrdinalIgnoreCase)) ? activity.Parent : null; 
                }
                return activity; 
            }
            else if (Helpers.IsActivityLocked(context))
            {
                // Look for the matching activity inside the custom activity context first.  This is because if a bind 
                // is coming from a custom activity, it's activity ref ID may not match the qualified ID of the
                // the activity. 
                Activity activity = null; 
                Activity declaringActivity = Helpers.GetDeclaringActivity(context);
                Guid currentContextGuid = GetRuntimeContextGuid(context); 
                Guid declaringContextGuid = GetRuntimeContextGuid(declaringActivity);

                Activity currentContextActivity = context;
                Activity parentContextActivity = context.Parent; 
                Guid parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
                while (activity == null && declaringContextGuid != currentContextGuid) 
                { 
                    // WinOE Bug 17931: if the context id is different, it means that this activity is running in a child context (such as
                    // the children of a replicator or a while).  we need to resolve the activity within the child context 
                    // first.  If we go up to the declaring activity, we'd be finding children of the template instead of
                    // the actual running instance.
                    while (parentContextActivity != null && parentContextGuid == currentContextGuid)
                    { 
                        currentContextActivity = parentContextActivity;
                        parentContextActivity = parentContextActivity.Parent; 
                        parentContextGuid = GetRuntimeContextGuid(parentContextActivity); 
                    }
 
                    activity = Helpers.ParseActivity(currentContextActivity, activityName);
                    currentContextGuid = parentContextGuid;
                }
 
                if (activity == null)
                { 
                    // Check the declaring activity 
                    activity = Helpers.ParseActivity(declaringActivity, activityName);
                } 

                // Nothing found, let's see if this is bind to the custom activity itself.
                if (activity == null)
                { 
                    if (!declaringActivity.UserData.Contains(UserDataKeys.CustomActivityDefaultName))
                    { 
                        //we need to activate a new instance of the declaringActivity's type and check if its name equals to the one we are looking for 
                        Activity newCustomActivity = Activator.CreateInstance(declaringActivity.GetType()) as Activity;
                        declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName] = newCustomActivity.Name; 
                    }

                    if (((string)declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName]) == activityName)
                        activity = declaringActivity; 
                }
 
                // if this is a locked activity, its bind reference must be within its declaring activity. We should not try 
                // to resolve it beyond that scope.
                return activity; 
            }

            Activity targetActivity = null;
            Activity parentActivity = context; 

            //if it's a custom activity and it has parent, start looking for the target activity at the parent level 
            //otherwise we'll get children of the custom activity 
            bool mayLookInside = false;//we may look inside the custom activity if the target is not found outside
            CompositeActivity compositeParentActivity = parentActivity as CompositeActivity; 
            if (compositeParentActivity != null && parentActivity.Parent != null && IsCustomActivity(compositeParentActivity))
            {
                mayLookInside = true;
                parentActivity = parentActivity.Parent; 
            }
 
            while (targetActivity == null && parentActivity != null) 
            {
                targetActivity = parentActivity.GetActivityByName(activityName, true); 
                parentActivity = parentActivity.Parent;
            }

            if (mayLookInside && targetActivity == null) 
            {
                //if we have not found an appropriate activity at the parent level, try looking inside 
                //we dont need to look outside (loop while parent is not null) - it has already been done above 
                parentActivity = context;
                targetActivity = parentActivity.GetActivityByName(activityName, true); 
            }


            return (targetActivity == null) ? Helpers.ParseActivity(Helpers.GetRootActivity(context), activityName) : targetActivity; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        private static Guid GetRuntimeContextGuid(Activity currentActivity)
        { 
            Activity contextActivity = currentActivity;
            Guid contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
            while (contextGuid == Guid.Empty && contextActivity.Parent != null)
            { 
                contextActivity = contextActivity.Parent;
                contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty); 
            } 
            return contextGuid;
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
        { 
            CompositeActivity declaringContext = context as CompositeActivity;
 
            CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity); 

            // If the context activity is locked and it is a primitive activity 
            // or NOT a custom activity then we need to find its enclosing
            // custom activity.
            if (Helpers.IsActivityLocked(context) &&
                    (declaringContext == null || !Helpers.IsCustomActivity(declaringContext)) 
                )
                declaringContext = Helpers.GetDeclaringActivity(context); 
 
            if (declaringContext == declaringActivityOfCurrent)
                return true; 
            else
                return false;
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool IsAlternateFlowActivity(Activity activity) 
        { 
            if (activity == null)
                return false; 

            bool isAlternateFlowActivityAttribute = false;
            //dont want to use reflection to check for the alternate flow attribute
            //this is a fix for a perf issue - use of reflection in a ui loop 
            if (!activity.UserData.Contains(typeof(AlternateFlowActivityAttribute)))
            { 
                isAlternateFlowActivityAttribute = activity.GetType().GetCustomAttributes(typeof(AlternateFlowActivityAttribute), true).Length != 0; 
                activity.UserData[typeof(AlternateFlowActivityAttribute)] = isAlternateFlowActivityAttribute;
            } 
            else
            {
                isAlternateFlowActivityAttribute = (bool)activity.UserData[typeof(AlternateFlowActivityAttribute)];
            } 

            return isAlternateFlowActivityAttribute; 
        } 

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        private static Activity GetActivity(Activity containerActivity, string id)
        {
            if (containerActivity != null)
            { 
                Queue activities = new Queue();
                activities.Enqueue(containerActivity); 
                while (activities.Count > 0) 
                {
                    Activity activity = (Activity)activities.Dequeue(); 
                    if (activity.Enabled)
                    {
                        if (activity.Name == id)
                            return activity; 

                        if (activity is CompositeActivity) 
                        { 
                            foreach (Activity child in ((CompositeActivity)activity).Activities)
                                activities.Enqueue(child); 
                        }
                    }
                }
            } 
            return null;
        } 
        #endregion 
    }
    #endregion 

    #region Class TypeDescriptorContext (SHARED WITH ACTIVITIES, ORCHESTRATIONDESIGNER)
    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
        Justification = "Not all assemblies that include this file instantiate the class.")] 
    internal sealed class TypeDescriptorContext : ITypeDescriptorContext
    { 
        private IServiceProvider serviceProvider; 
        private PropertyDescriptor propDesc;
        private object instance; 

        public TypeDescriptorContext(IServiceProvider serviceProvider, PropertyDescriptor propDesc, object instance)
        {
            this.serviceProvider = serviceProvider; 
            this.propDesc = propDesc;
            this.instance = instance; 
        } 

        public IContainer Container 
        {
            get
            {
                return (IContainer)this.serviceProvider.GetService(typeof(IContainer)); 
            }
        } 
        public object Instance 
        {
            get 
            {
                return this.instance;
            }
        } 
        public PropertyDescriptor PropertyDescriptor
        { 
            get 
            {
                return this.propDesc; 
            }
        }
        public object GetService(Type serviceType)
        { 
            return this.serviceProvider.GetService(serviceType);
        } 
 
        public bool OnComponentChanging()
        { 
            IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
            if (componentChangeService != null)
            {
                try 
                {
                    componentChangeService.OnComponentChanging(this.instance, this.propDesc); 
                } 
                catch (CheckoutException ce)
                { 
                    if (ce == CheckoutException.Canceled)
                        return false;
                    throw ce;
                } 
            }
 
            return true; 
        }
        public void OnComponentChanged() 
        {
            IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
            if (componentChangeService != null)
                componentChangeService.OnComponentChanged(this.instance, this.propDesc, null, null); 
        }
    } 
    #endregion 

    // This class has been added as a fix for bug 18214 in order to 
    // create an independent code-path for debugger's use of ParseActivity functionality.
    // The GetActivity method of this class uses QualifiedName instead of Name property
    // for finding activities.
    internal static class DebuggerHelpers 
    {
        [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")] 
        internal static Activity ParseActivity(Activity parsingContext, string activityName) 
        {
            if (parsingContext == null) 
                throw new ArgumentNullException("parsingContext");
            if (activityName == null)
                throw new ArgumentNullException("activityName");
 
            string currentAtivityName = activityName;
            string nextActivityName = string.Empty; 
            int indexOfDot = activityName.IndexOf("."); 
            if (indexOfDot != -1)
            { 
                currentAtivityName = activityName.Substring(0, indexOfDot);
                nextActivityName = activityName.Substring(indexOfDot + 1);
                if (nextActivityName.Length == 0)
                    return null; 
            }
 
            Activity currentActivity = null; 
            currentActivity = GetActivity(parsingContext, currentAtivityName);
 
            // The check for parsingContext.Parent != null is added here because IsCustomActivity returns true for root activities.
            if (currentActivity == null && (parsingContext is CompositeActivity) && parsingContext.Parent != null && Helpers.IsCustomActivity(parsingContext as CompositeActivity))
                currentActivity = GetActivity(parsingContext, parsingContext.QualifiedName + "." + currentAtivityName);
 
            if (currentActivity != null)
            { 
                if (nextActivityName.Length > 0) 
                {
                    if (!(currentActivity is CompositeActivity) || !Helpers.IsCustomActivity(currentActivity as CompositeActivity)) 
                        // current activity must be a custom activity, otherwise there should be no dots in the name.
                        return null;

                    string[] names = nextActivityName.Split('.'); 
                    for (int i = 0; i < names.Length; i++)
                    { 
                        Activity nextActivity = GetActivity(currentActivity, currentActivity.QualifiedName + "." + names[i]); 
                        if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
                            return null; 

                        CompositeActivity declaringActivity = Helpers.GetDeclaringActivity(nextActivity);
                        if (currentActivity != declaringActivity)
                            return null; 

                        currentActivity = nextActivity; 
                    } 

                    return currentActivity; 
                }
                else
                {
                    // This activity should always be unlocked, unless if GetChildActivity() is called from 
                    // within the custom activity's companion class, then we don't have the full qualified ID available
                    // at that time.  We allow this to succeed only if the declaring activity is the same as the declaring 
                    // activity of the context activity passed in. 
                    if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
                    { 
                        if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
                            return null;
                    }
 
                    return currentActivity;
                } 
            } 

            return null; 
        }

        private static Activity GetActivity(Activity containerActivity, string id)
        { 
            if (containerActivity != null)
            { 
                Queue activities = new Queue(); 
                activities.Enqueue(containerActivity);
                while (activities.Count > 0) 
                {
                    Activity activity = (Activity)activities.Dequeue();
                    if (activity.Enabled)
                    { 
                        if (activity.QualifiedName == id)
                            return activity; 
 
                        if (activity is CompositeActivity)
                        { 
                            foreach (Activity child in ((CompositeActivity)activity).Activities)
                                activities.Enqueue(child);
                        }
                    } 
                }
            } 
            return null; 
        }
 
        private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
        {
            CompositeActivity declaringContext = context as CompositeActivity;
 
            CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
 
            // If the context activity is locked and it is a primitive activity 
            // or NOT a custom activity then we need to find its enclosing
            // custom activity. 
            if (Helpers.IsActivityLocked(context) &&
                    (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
                )
                declaringContext = Helpers.GetDeclaringActivity(context); 

            if (declaringContext == declaringActivityOfCurrent) 
                return true; 
            else
                return false; 
        }
    }
}

// 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