904f2cb3041e96c02fdb7f64b67ef50dc67bc61c
[mono.git] / mcs / class / referencesource / System.Workflow.Activities / Common / CompModHelpers.cs
1 // Copyright (c) Microsoft Corporation. All rights reserved. 
2 //  
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE 
7 // AND INFORMATION REMAINS WITH THE USER. 
8 //  
9
10 /*********************************************************************
11  * NOTE: A copy of this file exists at: WF\Common\Shared
12  * The two files must be kept in sync.  Any change made here must also
13  * be made to WF\Common\Shared\CompModHelpers.cs
14 *********************************************************************/
15
16 namespace System.Workflow.Activities.Common
17 {
18     using System;
19     using System.CodeDom;
20     using System.Collections;
21     using System.Collections.Generic;
22     using System.ComponentModel;
23     using System.Diagnostics;
24     using System.ComponentModel.Design;
25     using System.ComponentModel.Design.Serialization;
26     using System.Workflow.ComponentModel.Serialization;
27     using System.IO;
28     using System.Runtime.Serialization.Formatters.Binary;
29     using System.Windows.Forms;
30     using System.Drawing;
31     using System.Drawing.Design;
32     using System.Workflow.ComponentModel;
33     using System.Workflow.ComponentModel.Compiler;
34     using System.Text;
35     using System.Reflection;
36     using System.Xml;
37     using System.Globalization;
38     using Microsoft.Win32;
39     using System.Runtime.InteropServices;
40     using System.Diagnostics.CodeAnalysis;
41     using System.Workflow.ComponentModel.Design;
42
43     #region Class Helpers
44     internal static class Helpers
45     {
46         private static readonly string VSExtensionProductRegistrySubKey = "Visual Studio Ext for Windows Workflow";
47         // 
48
49         internal static readonly string ProductRootRegKey = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v4.0\Setup\Windows Workflow Foundation";
50         internal static readonly string ProductInstallDirectory = GetInstallDirectory(false);
51         internal static readonly string ProductSDKInstallDirectory = GetInstallDirectory(true);
52         internal static readonly string TypeProviderAssemblyRegValueName = "References";
53
54         private static readonly string ProductRootRegKey30 = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.0\Setup\Windows Workflow Foundation";
55         internal static readonly string ProductInstallDirectory30 = GetInstallDirectory30();
56
57         private const string ProductCode = "{B644FB52-BB3D-4C43-80EC-57644210536A}";
58         private const string ProductSDKCode = "{C8A7718A-FF6D-4DDC-AE36-BBF968D6799B}";
59         private const string INSTALLPROPERTY_INSTALLLOCATION = "InstallLocation";
60
61         internal const int FILENAME_MAX = 260; //"stdio.h"
62
63         [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "LastIndexOf(\"\\\") not a security issue.")]
64         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
65         internal static string PerUserRegistryKey
66         {
67             get
68             {
69                 string keyPath = String.Empty;
70                 using (RegistryKey userRegistryKey = Application.UserAppDataRegistry)
71                 {
72                     keyPath = userRegistryKey.ToString().Substring(Registry.CurrentUser.ToString().Length + 1);
73                     keyPath = keyPath.Substring(0, keyPath.LastIndexOf("\\"));
74                     keyPath += "\\" + VSExtensionProductRegistrySubKey;
75                 }
76                 return keyPath;
77             }
78         }
79
80         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
81         private static string TypeProviderRegistryKeyPath
82         {
83             get
84             {
85                 return PerUserRegistryKey + "\\TypeProvider";
86             }
87         }
88
89         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
90         internal static bool IsFileNameValid(string fileName)
91         {
92             int length = Path.GetInvalidPathChars().GetLength(0) + 5;
93             char[] invalidChars = new char[length];
94             Path.GetInvalidPathChars().CopyTo(invalidChars, 0);
95             invalidChars[length - 5] = ':';
96             invalidChars[length - 4] = '?';
97             invalidChars[length - 3] = '*';
98             invalidChars[length - 2] = '/';
99             invalidChars[length - 1] = '\\';
100
101             return (fileName != null &&
102                     fileName.Length != 0 &&
103                     fileName.Length <= FILENAME_MAX &&
104                     fileName.IndexOfAny(invalidChars) == -1);
105         }
106
107         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
108         internal static bool AreAllActivities(ICollection c)
109         {
110             if (c == null)
111                 throw new ArgumentNullException("c");
112
113             foreach (object obj in c)
114             {
115                 if (!(obj is Activity))
116                     return false;
117             }
118             return true;
119         }
120
121         // this will return IDictionary, whose keys are parent and value is arraylist of child activities
122         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
123         internal static IDictionary PairUpCommonParentActivities(ICollection activities)
124         {
125             if (activities == null)
126                 throw new ArgumentNullException("activities");
127
128             Hashtable commonParentActivities = new Hashtable();
129             foreach (Activity activity in activities)
130             {
131                 if (activity.Parent != null)
132                 {
133                     ArrayList childActivities = (ArrayList)commonParentActivities[activity.Parent];
134                     if (childActivities == null)
135                     {
136                         childActivities = new ArrayList();
137                         commonParentActivities.Add(activity.Parent, childActivities);
138                     }
139                     childActivities.Add(activity);
140                 }
141             }
142             return commonParentActivities;
143         }
144
145         // this will remove any activity from the collection whose parent is already there in the collection
146         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
147         internal static Activity[] GetTopLevelActivities(ICollection activities)
148         {
149             if (activities == null)
150                 throw new ArgumentNullException("activities");
151
152             List<Activity> filteredActivities = new List<Activity>();
153             foreach (object obj in activities)
154             {
155                 Activity activity = obj as Activity;
156                 if (activity != null)
157                 {
158                     bool foundParent = false;
159                     Activity parentActivity = activity.Parent;
160                     while (parentActivity != null && !foundParent)
161                     {
162                         foreach (object obj2 in activities)
163                         {
164                             if (obj2 == parentActivity)
165                             {
166                                 foundParent = true;
167                                 break;
168                             }
169                         }
170                         parentActivity = parentActivity.Parent;
171                     }
172
173                     if (!foundParent)
174                         filteredActivities.Add(activity);
175                 }
176             }
177             return filteredActivities.ToArray();
178         }
179
180         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
181         internal static Activity[] GetNestedActivities(CompositeActivity compositeActivity)
182         {
183
184             if (compositeActivity == null)
185                 throw new ArgumentNullException("compositeActivity");
186
187             IList<Activity> childActivities = null;
188             ArrayList nestedActivities = new ArrayList();
189             Queue compositeActivities = new Queue();
190             compositeActivities.Enqueue(compositeActivity);
191             while (compositeActivities.Count > 0)
192             {
193                 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
194                 childActivities = compositeActivity2.Activities;
195
196                 foreach (Activity activity in childActivities)
197                 {
198                     nestedActivities.Add(activity);
199                     if (activity is CompositeActivity)
200                         compositeActivities.Enqueue(activity);
201                 }
202             }
203             return (Activity[])nestedActivities.ToArray(typeof(Activity));
204         }
205
206
207         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
208         internal static IList GetIdentifiersInCompositeActivity(CompositeActivity compositeActivity)
209         {
210             ArrayList identifiers = new ArrayList();
211             if (compositeActivity != null)
212             {
213                 identifiers.Add(compositeActivity.Name);
214                 IList<Activity> allChildren = GetAllNestedActivities(compositeActivity);
215                 foreach (Activity activity in allChildren)
216                     identifiers.Add(activity.Name);
217             }
218             return ArrayList.ReadOnly(identifiers);
219         }
220
221         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
222         internal static Activity[] GetAllNestedActivities(CompositeActivity compositeActivity)
223         {
224             if (compositeActivity == null)
225                 throw new ArgumentNullException("compositeActivity");
226
227             ArrayList nestedActivities = new ArrayList();
228
229             // Note: GetAllNestedActivities will not check for black box activities.
230             // This is to allow it to be invoked from within the activity's 
231             // constructor.
232             //if(Helpers.IsCustomActivity(compositeActivity))
233             //return (Activity[])nestedActivities.ToArray(typeof(Activity));
234
235             Queue compositeActivities = new Queue();
236             compositeActivities.Enqueue(compositeActivity);
237             while (compositeActivities.Count > 0)
238             {
239                 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
240                 if (compositeActivity2 == compositeActivity || !Helpers.IsCustomActivity(compositeActivity2))
241                 {
242                     foreach (Activity activity in compositeActivity2.Activities)
243                     {
244                         nestedActivities.Add(activity);
245                         if (activity is CompositeActivity)
246                             compositeActivities.Enqueue(activity);
247                     }
248
249                     foreach (Activity activity in compositeActivity2.EnabledActivities)
250                     {
251                         if (!nestedActivities.Contains(activity))
252                         {
253                             nestedActivities.Add(activity);
254                             if (activity is CompositeActivity)
255                                 compositeActivities.Enqueue(activity);
256                         }
257                     }
258                 }
259             }
260             return (Activity[])nestedActivities.ToArray(typeof(Activity));
261         }
262
263         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
264         internal static string MergeNamespaces(string primaryNs, string secondaryNs)
265         {
266             string newNs = primaryNs;
267             if (secondaryNs != null && secondaryNs.Length > 0)
268             {
269                 if (newNs != null && newNs.Length > 0)
270                     newNs += ("." + secondaryNs);
271                 else
272                     newNs = secondaryNs;
273             }
274
275             if (newNs == null)
276                 newNs = string.Empty;
277             return newNs;
278         }
279
280         internal static Activity GetRootActivity(Activity activity)
281         {
282             if (activity == null)
283                 throw new ArgumentNullException("activity");
284
285             while (activity.Parent != null)
286                 activity = activity.Parent;
287
288             return activity;
289         }
290
291         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
292         internal static Stream SerializeDesignersToStream(ICollection activities)
293         {
294             Stream stateStream = new MemoryStream();
295             BinaryWriter writer = new BinaryWriter(stateStream);
296
297             Queue<IComponent> serializedComponents = new Queue<IComponent>();
298             foreach (IComponent activity in activities)
299                 serializedComponents.Enqueue(activity);
300
301             while (serializedComponents.Count > 0)
302             {
303                 IComponent component = serializedComponents.Dequeue();
304                 if (component != null && component.Site != null)
305                 {
306                     IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
307                     if (designerHost == null)
308                         throw new InvalidOperationException(
309                             SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
310
311                     ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
312                     if (activityDesigner != null)
313                     {
314                         try
315                         {
316                             ((IPersistUIState)activityDesigner).SaveViewState(writer);
317
318                             CompositeActivity compositeActivity = component as CompositeActivity;
319                             if (compositeActivity != null)
320                             {
321                                 foreach (IComponent childActivity in compositeActivity.Activities)
322                                 {
323                                     serializedComponents.Enqueue(childActivity);
324                                 }
325                             }
326                         }
327                         catch
328                         {
329                         }
330                     }
331                 }
332             }
333
334             return stateStream;
335         }
336
337         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
338         internal static void DeserializeDesignersFromStream(ICollection activities, Stream stateStream)
339         {
340             if (stateStream.Length == 0)
341                 return;
342
343             BinaryReader reader = new BinaryReader(stateStream);
344             stateStream.Seek(0, SeekOrigin.Begin);
345
346             Queue<IComponent> serializedComponents = new Queue<IComponent>();
347             foreach (IComponent component in activities)
348                 serializedComponents.Enqueue(component);
349
350             while (serializedComponents.Count > 0)
351             {
352                 IComponent component = serializedComponents.Dequeue();
353                 if (component != null && component.Site != null)
354                 {
355                     IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
356                     if (designerHost == null)
357                         throw new InvalidOperationException(
358                             SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
359
360                     ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
361                     if (activityDesigner != null)
362                     {
363                         try
364                         {
365                             ((IPersistUIState)activityDesigner).LoadViewState(reader);
366
367                             CompositeActivity compositeActivity = component as CompositeActivity;
368                             if (compositeActivity != null)
369                             {
370                                 foreach (IComponent childActivity in compositeActivity.Activities)
371                                 {
372                                     serializedComponents.Enqueue(childActivity);
373                                 }
374                             }
375                         }
376                         catch
377                         {
378                         }
379                     }
380                 }
381             }
382         }
383
384         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
385         internal static string GetBaseIdentifier(Activity activity)
386         {
387             string baseIdentifier = activity.GetType().Name;
388             StringBuilder b = new StringBuilder(baseIdentifier.Length);
389             for (int i = 0; i < baseIdentifier.Length; i++)
390             {
391                 if (Char.IsUpper(baseIdentifier[i]) && (i == 0 || i == baseIdentifier.Length - 1 || Char.IsUpper(baseIdentifier[i + 1])))
392                 {
393                     b.Append(Char.ToLowerInvariant(baseIdentifier[i]));
394                 }
395                 else
396                 {
397                     b.Append(baseIdentifier.Substring(i));
398                     break;
399                 }
400             }
401             return b.ToString();
402         }
403
404         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
405         internal static string GetRootNamespace(IServiceProvider serviceProvider)
406         {
407             if (serviceProvider == null)
408                 throw new ArgumentNullException("serviceProvider");
409
410             string rootNs = string.Empty;
411             IWorkflowCompilerOptionsService compilerOptionsService = (IWorkflowCompilerOptionsService)serviceProvider.GetService(typeof(IWorkflowCompilerOptionsService));
412             if (compilerOptionsService != null && compilerOptionsService.RootNamespace != null)
413                 rootNs = compilerOptionsService.RootNamespace; //e.g. WorkflowApp1
414             return rootNs;
415         }
416
417         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
418         internal static Type GetDataSourceClass(Activity activity, IServiceProvider serviceProvider)
419         {
420             if (activity == null)
421                 throw new ArgumentNullException("activity");
422             if (serviceProvider == null)
423                 throw new ArgumentNullException("serviceProvider");
424
425             Type activityType = null;
426             string className = null;
427             if (activity == GetRootActivity(activity))
428                 className = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;
429
430             if (!String.IsNullOrEmpty(className))
431             {
432                 ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider));
433                 if (typeProvider == null)
434                     throw new InvalidOperationException(
435                         SR.GetString(SR.General_MissingService, typeof(ITypeProvider).Name));
436
437                 activityType = typeProvider.GetType(className);
438             }
439             else
440             {
441                 return activity.GetType();
442             }
443
444             return activityType;
445         }
446
447         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
448         internal static Activity GetDataSourceActivity(Activity activity, string inputName, out string name)
449         {
450             if (activity == null)
451                 throw new ArgumentNullException("activity");
452             if (string.IsNullOrEmpty(inputName))
453                 throw new ArgumentException("inputName");
454
455             name = inputName;
456             if (inputName.IndexOf('.') == -1)
457                 return activity;
458
459             int indexOfDot = inputName.LastIndexOf('.');
460             string scopeID = inputName.Substring(0, indexOfDot);
461             name = inputName.Substring(indexOfDot + 1);
462
463             Activity contextActivity = Helpers.ParseActivityForBind(activity, scopeID);
464             if (contextActivity == null)
465                 contextActivity = Helpers.ParseActivity(Helpers.GetRootActivity(activity), scopeID);
466
467             // activity can be either the qualified id of the scope activity or the qualified id of the custom activity.
468             return contextActivity;
469         }
470
471         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
472         internal static void GetNamespaceAndClassName(string fullQualifiedName, out string namespaceName, out string className)
473         {
474             namespaceName = String.Empty;
475             className = String.Empty;
476
477             if (fullQualifiedName == null)
478                 return;
479
480             int indexOfDot = fullQualifiedName.LastIndexOf('.');
481             if (indexOfDot != -1)
482             {
483                 namespaceName = fullQualifiedName.Substring(0, indexOfDot);
484                 className = fullQualifiedName.Substring(indexOfDot + 1);
485             }
486             else
487             {
488                 className = fullQualifiedName;
489             }
490         }
491
492         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
493         internal static CodeTypeDeclaration GetCodeNamespaceAndClass(CodeNamespaceCollection namespaces, string namespaceName, string className, out CodeNamespace codeNamespace)
494         {
495             codeNamespace = null;
496             foreach (CodeNamespace ns in namespaces)
497             {
498                 if (ns.Name == namespaceName)
499                 {
500                     codeNamespace = ns;
501                     break;
502                 }
503             }
504
505             CodeTypeDeclaration codeTypeDeclaration = null;
506             if (codeNamespace != null)
507             {
508                 foreach (CodeTypeDeclaration typeDecl in codeNamespace.Types)
509                 {
510                     if (typeDecl.Name == className)
511                     {
512                         codeTypeDeclaration = typeDecl;
513                         break;
514                     }
515                 }
516             }
517             return codeTypeDeclaration;
518         }
519
520         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
521         internal static string GetClassName(string fullQualifiedName)
522         {
523             if (fullQualifiedName == null)
524                 return null;
525
526             string className = fullQualifiedName;
527             int indexOfDot = fullQualifiedName.LastIndexOf('.');
528             if (indexOfDot != -1)
529                 className = fullQualifiedName.Substring(indexOfDot + 1);
530             return className;
531         }
532
533
534         [DllImport("msi.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
535         private static extern int MsiGetProductInfoW(string szProduct, string szProperty, StringBuilder lpValueBuf, ref int pcchValueBuf);
536         private static string GetInstallDirectory(bool getSDKDir)
537         {
538             string path = string.Empty;
539             try
540             {
541                 //ERROR_UNKNOWN_PROPERTY           1608L
542                 //ERROR_INVALID_PARAMETER          87L
543                 int length = FILENAME_MAX + 1;
544                 StringBuilder location = new StringBuilder(length);
545                 int hr = MsiGetProductInfoW(getSDKDir ? ProductSDKCode : ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
546                 int error = Marshal.GetLastWin32Error();
547                 if (hr == 0)
548                 {
549                     path = location.ToString();
550                 }
551                 else
552                 {
553                     Debug.WriteLine("Error loading install directory: " + error.ToString(CultureInfo.CurrentCulture));
554                 }
555
556             }
557             catch
558             {
559             }
560
561             if (string.IsNullOrEmpty(path))
562             {
563                 try
564                 {
565                     if (!getSDKDir)
566                     {
567                         using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey))
568                         {
569                             if (key != null)
570                                 path = (string)key.GetValue("InstallDir");
571                         }
572                     }
573                 }
574                 catch
575                 {
576                 }
577             }
578
579             // 
580             if (string.IsNullOrEmpty(path))
581                 path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
582
583             return path;
584         }
585
586         private static string GetInstallDirectory30()
587         {
588             string path = string.Empty;
589             try
590             {
591                 //ERROR_UNKNOWN_PROPERTY           1608L
592                 //ERROR_INVALID_PARAMETER          87L
593                 int length = FILENAME_MAX + 1;
594                 StringBuilder location = new StringBuilder(length);
595                 int hr = MsiGetProductInfoW(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
596                 int error = Marshal.GetLastWin32Error();
597                 if (hr == 0)
598                 {
599                     path = location.ToString();
600                 }
601                 else
602                 {
603                     Debug.WriteLine("Error loading 3.0 install directory: " + error.ToString(CultureInfo.CurrentCulture));
604                 }
605
606             }
607             catch
608             {
609             }
610
611             if (string.IsNullOrEmpty(path))
612             {
613                 try
614                 {
615                     using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey30))
616                     {
617                         if (key != null)
618                         {
619                             path = (string)key.GetValue("InstallDir");
620                         }
621                     }
622                 }
623                 catch
624                 {
625                 }
626             }
627
628             return path;
629         }
630
631         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
632         internal static Type GetBaseType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
633         {
634             //When we are emitting code for the dynamic properties we might get the propertyinfo as null
635             if (owner == null)
636                 throw new ArgumentNullException("owner");
637
638             if (serviceProvider == null)
639                 throw new ArgumentNullException("serviceProvider");
640
641             if (property != null)
642             {
643                 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
644                 if (basetypeProvider != null)
645                 {
646                     Type type = basetypeProvider.GetPropertyType(serviceProvider, property.Name);
647                     if (type != null)
648                         return type;
649                 }
650
651                 return property.PropertyType;
652             }
653
654             return null;
655         }
656
657         //
658         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
659         internal static AccessTypes GetAccessType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
660         {
661             //When we are emitting code for the dynamic properties we might get the propertyinfo as null
662             if (owner == null)
663                 throw new ArgumentNullException("owner");
664
665             if (serviceProvider == null)
666                 throw new ArgumentNullException("serviceProvider");
667
668             if (property != null)
669             {
670                 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
671                 if (basetypeProvider != null)
672                     return basetypeProvider.GetAccessType(serviceProvider, property.Name);
673             }
674
675             return AccessTypes.Read;
676         }
677
678         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
679         internal static bool IsChildActivity(CompositeActivity parent, Activity activity)
680         {
681             foreach (Activity containedActivity in parent.Activities)
682             {
683                 if (activity == containedActivity)
684                     return true;
685
686                 if (containedActivity is CompositeActivity &&
687                     Helpers.IsChildActivity(containedActivity as CompositeActivity, activity))
688                     return true;
689             }
690
691             return false;
692         }
693
694         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
695         internal static bool TypesEqual(CodeTypeReference typeLeft, Type typeRight)
696         {
697             if (typeRight.IsArray && typeLeft.ArrayRank != typeRight.GetArrayRank()) return false;
698             // 
699             if (!typeLeft.BaseType.Equals(typeRight.FullName)) return false;
700
701             if (typeLeft.ArrayRank > 0)
702                 return TypesEqual(typeLeft.ArrayElementType, typeRight.GetElementType());
703             return true;
704         }
705
706         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
707         internal static bool TypesEqual(CodeTypeReference typeLeft, CodeTypeReference typeRight)
708         {
709             if (typeLeft.ArrayRank != typeRight.ArrayRank) return false;
710             if (!typeLeft.BaseType.Equals(typeRight.BaseType)) return false;
711
712             if (typeLeft.ArrayRank > 0)
713                 return TypesEqual(typeLeft.ArrayElementType, typeRight.ArrayElementType);
714             return true;
715         }
716
717         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
718         internal static DesignerSerializationVisibility GetSerializationVisibility(MemberInfo memberInfo)
719         {
720
721             if (memberInfo == null)
722                 throw new ArgumentNullException("memberInfo");
723
724             DesignerSerializationVisibility designerSerializationVisibility = DesignerSerializationVisibility.Visible;
725
726             // Calling GetCustomAttributes on PropertyInfo or EventInfo when the inherit parameter of GetCustomAttributes 
727             // is true does not walk the type hierarchy. But System.Attribute.GetCustomAttributes causes perf issues.
728             object[] attributes = memberInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true);
729             if (attributes.Length > 0)
730                 designerSerializationVisibility = (attributes[0] as DesignerSerializationVisibilityAttribute).Visibility;
731             else if (Attribute.IsDefined(memberInfo, typeof(DesignerSerializationVisibilityAttribute)))
732                 designerSerializationVisibility = (Attribute.GetCustomAttribute(memberInfo, typeof(DesignerSerializationVisibilityAttribute)) as DesignerSerializationVisibilityAttribute).Visibility;
733
734             return designerSerializationVisibility;
735         }
736
737         // Method parameters must match exactly
738         // 
739         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
740         internal static MethodInfo GetMethodExactMatch(Type type, string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
741         {
742             MethodInfo foundMethod = null;
743             MethodInfo[] methods = type.GetMethods(bindingAttr);
744             foreach (MethodInfo method in methods)
745             {
746                 bool matchName = ((bindingAttr & BindingFlags.IgnoreCase) == BindingFlags.IgnoreCase) ? string.Compare(method.Name, name, StringComparison.OrdinalIgnoreCase) == 0 : string.Compare(method.Name, name, StringComparison.Ordinal) == 0;
747                 if (matchName)
748                 {
749                     bool mismatch = false;
750                     if (types != null)
751                     {
752                         ParameterInfo[] parameters = method.GetParameters();
753                         if (parameters.GetLength(0) == types.Length)
754                         {
755                             for (int index = 0; !mismatch && index < parameters.Length; index++)
756                                 mismatch = (parameters[index].ParameterType == null) || (!parameters[index].ParameterType.IsAssignableFrom(types[index]));
757                         }
758                         else
759                             mismatch = true;
760                     }
761                     if (!mismatch)
762                     {
763                         foundMethod = method;
764                         break;
765                     }
766                 }
767             }
768
769             return foundMethod;
770         }
771
772         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
773         internal static T GetAttributeFromObject<T>(object attributeObject) where T : Attribute
774         {
775             if (attributeObject is AttributeInfoAttribute)
776                 return (T)((AttributeInfoAttribute)attributeObject).AttributeInfo.CreateAttribute();
777
778             if (attributeObject is T)
779                 return (T)attributeObject;
780
781             return null;
782         }
783
784         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
785         internal static Type GetDelegateFromEvent(EventInfo eventInfo)
786         {
787             if (eventInfo.EventHandlerType != null)
788                 return eventInfo.EventHandlerType;
789
790             return TypeProvider.GetEventHandlerType(eventInfo);
791         }
792
793         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
794         internal static void AddTypeProviderAssembliesFromRegistry(TypeProvider typeProvider, IServiceProvider serviceProvider)
795         {
796             if (typeProvider == null)
797                 throw new ArgumentNullException("typeProvider");
798             if (serviceProvider == null)
799                 throw new ArgumentNullException("serviceProvider");
800
801             RegistryKey referenceKey = Registry.CurrentUser.OpenSubKey(TypeProviderRegistryKeyPath);
802             if (referenceKey != null)
803             {
804                 ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator;
805                 foreach (string assemblyName in ((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName)))
806                 {
807                     try
808                     {
809                         if (typeProviderCreator != null)
810                         {
811                             bool addAssembly = true;
812                             Assembly assembly = typeProviderCreator.GetTransientAssembly(AssemblyName.GetAssemblyName(assemblyName));
813                             // Check to see if a copy of the assembly is already added.
814                             if (assembly != null)
815                             {
816                                 foreach (Type type in assembly.GetTypes())
817                                 {
818                                     if (typeProvider.GetType(type.AssemblyQualifiedName) != null)
819                                         addAssembly = false;
820                                     break;
821                                 }
822                                 if (addAssembly)
823                                     typeProvider.AddAssembly(assembly);
824                             }
825                         }
826                         else
827                             // AddAssemblyReference should take care of duplicates.
828                             typeProvider.AddAssemblyReference(assemblyName);
829
830                     }
831                     catch
832                     {
833                         // Continue loading.
834                     }
835                 }
836
837                 referenceKey.Close();
838             }
839         }
840
841         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
842         internal static void UpdateTypeProviderAssembliesRegistry(string assemblyName)
843         {
844             RegistryKey referenceKey = Registry.CurrentUser.CreateSubKey(TypeProviderRegistryKeyPath);
845             if (referenceKey != null)
846             {
847                 try
848                 {
849                     ArrayList references = null;
850                     if (referenceKey.ValueCount > 0)
851                         references = new ArrayList((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName));
852                     else
853                         references = new ArrayList();
854
855                     if (!references.Contains(assemblyName))
856                     {
857                         references.Add(assemblyName);
858                         referenceKey.SetValue(TypeProviderAssemblyRegValueName, ((string[])references.ToArray(typeof(string))));
859                     }
860                 }
861                 catch
862                 {
863                     //We eat the exception
864                 }
865                 finally
866                 {
867                     referenceKey.Close();
868                 }
869             }
870         }
871
872         internal static CompositeActivity GetDeclaringActivity(Activity activity)
873         {
874             if (activity == null)
875                 throw new ArgumentNullException("activity");
876
877             CompositeActivity parent = activity.Parent;
878             while (parent != null)
879             {
880                 // This will be the root
881                 if (parent.Parent == null)
882                     return parent;
883
884                 // Any custom activity found is the declaring activity
885                 if (IsCustomActivity(parent))
886                     return parent;
887
888                 parent = parent.Parent;
889             }
890             return null;
891         }
892
893         internal static bool IsActivityLocked(Activity activity)
894         {
895             if (activity == null)
896                 throw new ArgumentNullException("activity");
897
898             CompositeActivity parent = activity.Parent;
899             while (parent != null)
900             {
901                 // If root, not locked
902                 if (parent.Parent == null)
903                     return false;
904
905                 // Any custom activity found, then locked
906                 if (IsCustomActivity(parent))
907                     return true;
908
909                 parent = parent.Parent;
910             }
911
912             return false;
913         }
914
915         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
916         internal static Activity GetEnclosingActivity(Activity activity)
917         {
918             Activity enclosingActivity;
919
920             if (IsActivityLocked(activity))
921                 enclosingActivity = Helpers.GetDeclaringActivity(activity);
922             else
923                 enclosingActivity = GetRootActivity(activity);
924
925             return enclosingActivity;
926         }
927
928         // This function returns all the executable activities including secondary flow activities.
929         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
930         public static IList<Activity> GetAllEnabledActivities(CompositeActivity compositeActivity)
931         {
932             if (compositeActivity == null)
933                 throw new ArgumentNullException("compositeActivity");
934
935             List<Activity> allActivities = new List<Activity>(compositeActivity.EnabledActivities);
936             foreach (Activity childActivity in compositeActivity.Activities)
937             {
938                 if (childActivity.Enabled &&
939                         IsFrameworkActivity(childActivity))
940                     allActivities.Add(childActivity);
941             }
942             return allActivities;
943         }
944         public static bool IsFrameworkActivity(Activity activity)
945         {
946             return (activity is CancellationHandlerActivity ||
947                         activity is CompensationHandlerActivity ||
948                         activity is FaultHandlersActivity);
949         }
950
951         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
952         internal static MethodInfo GetInterfaceMethod(Type interfaceType, string methodName)
953         {
954             MethodInfo methodInfo = null;
955             string interfaceName = String.Empty;
956             string method = String.Empty;
957
958             if (methodName.LastIndexOf('.') > 0)
959             {
960                 interfaceName = methodName.Substring(0, methodName.LastIndexOf('.'));
961                 method = methodName.Substring(methodName.LastIndexOf('.') + 1);
962             }
963
964             if (!String.IsNullOrEmpty(interfaceName))
965             {
966                 foreach (Type inheritedInterface in interfaceType.GetInterfaces())
967                 {
968                     if (String.Compare(inheritedInterface.FullName, interfaceName, StringComparison.Ordinal) == 0)
969                     {
970                         methodInfo = inheritedInterface.GetMethod(method);
971                         break;
972                     }
973                 }
974             }
975             else
976             {
977                 methodInfo = interfaceType.GetMethod(methodName);
978             }
979
980             return methodInfo;
981         }
982
983         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
984         internal static XmlWriter CreateXmlWriter(object output)
985         {
986             XmlWriterSettings settings = new XmlWriterSettings();
987             settings.Indent = true;
988             settings.IndentChars = ("\t");
989             settings.OmitXmlDeclaration = true;
990             settings.CloseOutput = true;
991
992             if (output is string)
993                 return XmlWriter.Create(output as string, settings);
994             else if (output is TextWriter)
995                 return XmlWriter.Create(output as TextWriter, settings);
996             else
997             {
998                 Debug.Assert(false, "Invalid argument type.  'output' must either be string or TextWriter.");
999                 return null;
1000             }
1001         }
1002
1003         #region DesignTimeType Support
1004         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1005         internal static string GetDesignTimeTypeName(object owner, object key)
1006         {
1007             string typeName = null;
1008             DependencyObject dependencyObject = owner as DependencyObject;
1009             if (dependencyObject != null && key != null)
1010             {
1011                 if (dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1012                 {
1013                     Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1014                     if (typeNames != null && typeNames.ContainsKey(key))
1015                         typeName = typeNames[key] as string;
1016                 }
1017             }
1018             return typeName;
1019         }
1020
1021         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1022         internal static void SetDesignTimeTypeName(object owner, object key, string value)
1023         {
1024             DependencyObject dependencyObject = owner as DependencyObject;
1025             if (dependencyObject != null && key != null)
1026             {
1027                 if (!dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1028                     dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] = new Hashtable();
1029
1030                 Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1031                 typeNames[key] = value;
1032             }
1033         }
1034         #endregion
1035
1036         #region Helpers from ExecutableCompModHelpers
1037         // This only works for composite activity.
1038         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1039         internal static bool IsCustomActivity(CompositeActivity compositeActivity)
1040         {
1041             if (compositeActivity == null)
1042                 throw new ArgumentNullException("compositeActivity");
1043
1044             if (compositeActivity.UserData.Contains(UserDataKeys.CustomActivity))
1045             {
1046                 return (bool)(compositeActivity.UserData[UserDataKeys.CustomActivity]);
1047             }
1048             else
1049             {
1050                 try
1051                 {
1052                     CompositeActivity activity = Activator.CreateInstance(compositeActivity.GetType()) as CompositeActivity;
1053                     if (activity != null && activity.Activities.Count > 0)
1054                     {
1055                         compositeActivity.UserData[UserDataKeys.CustomActivityDefaultName] = activity.Name;
1056                         compositeActivity.UserData[UserDataKeys.CustomActivity] = true; //
1057                         return true;
1058                     }
1059                 }
1060                 catch
1061                 {
1062                     // 
1063                 }
1064             }
1065
1066             compositeActivity.UserData[UserDataKeys.CustomActivity] = false; //
1067             return false;
1068         }
1069
1070         [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1071         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1072         internal static Activity ParseActivity(Activity parsingContext, string activityName)
1073         {
1074             if (parsingContext == null)
1075                 throw new ArgumentNullException("parsingContext");
1076             if (activityName == null)
1077                 throw new ArgumentNullException("activityName");
1078
1079             string currentAtivityName = activityName;
1080             string nextActivityName = string.Empty;
1081             int indexOfDot = activityName.IndexOf(".");
1082             if (indexOfDot != -1)
1083             {
1084                 currentAtivityName = activityName.Substring(0, indexOfDot);
1085                 nextActivityName = activityName.Substring(indexOfDot + 1);
1086                 if (nextActivityName.Length == 0)
1087                     return null;
1088             }
1089
1090             Activity currentActivity = GetActivity(parsingContext, currentAtivityName);
1091             if (currentActivity != null)
1092             {
1093                 if (nextActivityName.Length > 0)
1094                 {
1095                     if (!(currentActivity is CompositeActivity) || !IsCustomActivity(currentActivity as CompositeActivity))
1096                         // current activity must be a custom activity, otherwise there should be no dots in the name.
1097                         return null;
1098
1099                     string[] names = nextActivityName.Split('.');
1100                     for (int i = 0; i < names.Length; i++)
1101                     {
1102                         Activity nextActivity = GetActivity(currentActivity, names[i]);
1103                         if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1104                             return null;
1105
1106                         CompositeActivity declaringActivity = GetDeclaringActivity(nextActivity);
1107                         if (currentActivity != declaringActivity)
1108                             return null;
1109
1110                         currentActivity = nextActivity;
1111                     }
1112
1113                     return currentActivity;
1114                 }
1115                 else
1116                 {
1117                     // This activity should always be unlocked, unless if GetChildActivity() is called from
1118                     // within the custom activity's companion class, then we don't have the full qualified ID available
1119                     // at that time.  We allow this to succeed only if the declaring activity is the same as the declaring
1120                     // activity of the context activity passed in.
1121                     if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1122                     {
1123                         if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1124                             return null;
1125                     }
1126
1127                     return currentActivity;
1128                 }
1129             }
1130
1131             return null;
1132         }
1133
1134         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1135         internal static Activity ParseActivityForBind(Activity context, string activityName)
1136         {
1137             if (context == null)
1138                 throw new ArgumentNullException("context");
1139             if (activityName == null)
1140                 throw new ArgumentNullException("activityName");
1141
1142             if (string.Equals(activityName, "/Self", StringComparison.Ordinal))
1143             {
1144                 return context;
1145             }
1146             else if (activityName.StartsWith("/Parent", StringComparison.OrdinalIgnoreCase))
1147             {
1148                 Activity activity = context;
1149                 string[] paths = activityName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
1150                 for (int i = 0; i < paths.Length && activity != null; i++)
1151                 {
1152                     string parent = paths[i].Trim();
1153                     activity = (string.Equals(parent, "Parent", StringComparison.OrdinalIgnoreCase)) ? activity.Parent : null;
1154                 }
1155                 return activity;
1156             }
1157             else if (Helpers.IsActivityLocked(context))
1158             {
1159                 // Look for the matching activity inside the custom activity context first.  This is because if a bind
1160                 // is coming from a custom activity, it's activity ref ID may not match the qualified ID of the
1161                 // the activity.
1162                 Activity activity = null;
1163                 Activity declaringActivity = Helpers.GetDeclaringActivity(context);
1164                 Guid currentContextGuid = GetRuntimeContextGuid(context);
1165                 Guid declaringContextGuid = GetRuntimeContextGuid(declaringActivity);
1166
1167                 Activity currentContextActivity = context;
1168                 Activity parentContextActivity = context.Parent;
1169                 Guid parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1170                 while (activity == null && declaringContextGuid != currentContextGuid)
1171                 {
1172                     // WinOE 
1173
1174
1175
1176                     while (parentContextActivity != null && parentContextGuid == currentContextGuid)
1177                     {
1178                         currentContextActivity = parentContextActivity;
1179                         parentContextActivity = parentContextActivity.Parent;
1180                         parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1181                     }
1182
1183                     activity = Helpers.ParseActivity(currentContextActivity, activityName);
1184                     currentContextGuid = parentContextGuid;
1185                 }
1186
1187                 if (activity == null)
1188                 {
1189                     // Check the declaring activity
1190                     activity = Helpers.ParseActivity(declaringActivity, activityName);
1191                 }
1192
1193                 // Nothing found, let's see if this is bind to the custom activity itself.
1194                 if (activity == null)
1195                 {
1196                     if (!declaringActivity.UserData.Contains(UserDataKeys.CustomActivityDefaultName))
1197                     {
1198                         //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
1199                         Activity newCustomActivity = Activator.CreateInstance(declaringActivity.GetType()) as Activity;
1200                         declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName] = newCustomActivity.Name;
1201                     }
1202
1203                     if (((string)declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName]) == activityName)
1204                         activity = declaringActivity;
1205                 }
1206
1207                 // if this is a locked activity, its bind reference must be within its declaring activity. We should not try
1208                 // to resolve it beyond that scope.
1209                 return activity;
1210             }
1211
1212             Activity targetActivity = null;
1213             Activity parentActivity = context;
1214
1215             //if it's a custom activity and it has parent, start looking for the target activity at the parent level
1216             //otherwise we'll get children of the custom activity
1217             bool mayLookInside = false; //we may look inside the custom activity if the target is not found outside
1218             CompositeActivity compositeParentActivity = parentActivity as CompositeActivity;
1219             if (compositeParentActivity != null && parentActivity.Parent != null && IsCustomActivity(compositeParentActivity))
1220             {
1221                 mayLookInside = true;
1222                 parentActivity = parentActivity.Parent;
1223             }
1224
1225             while (targetActivity == null && parentActivity != null)
1226             {
1227                 targetActivity = parentActivity.GetActivityByName(activityName, true);
1228                 parentActivity = parentActivity.Parent;
1229             }
1230
1231             if (mayLookInside && targetActivity == null)
1232             {
1233                 //if we have not found an appropriate activity at the parent level, try looking inside
1234                 //we dont need to look outside (loop while parent is not null) - it has already been done above
1235                 parentActivity = context;
1236                 targetActivity = parentActivity.GetActivityByName(activityName, true);
1237             }
1238
1239
1240             return (targetActivity == null) ? Helpers.ParseActivity(Helpers.GetRootActivity(context), activityName) : targetActivity;
1241         }
1242
1243         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1244         private static Guid GetRuntimeContextGuid(Activity currentActivity)
1245         {
1246             Activity contextActivity = currentActivity;
1247             Guid contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1248             while (contextGuid == Guid.Empty && contextActivity.Parent != null)
1249             {
1250                 contextActivity = contextActivity.Parent;
1251                 contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1252             }
1253             return contextGuid;
1254         }
1255
1256         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1257         private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1258         {
1259             CompositeActivity declaringContext = context as CompositeActivity;
1260
1261             CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1262
1263             // If the context activity is locked and it is a primitive activity
1264             // or NOT a custom activity then we need to find its enclosing 
1265             // custom activity.
1266             if (Helpers.IsActivityLocked(context) &&
1267                     (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1268                 )
1269                 declaringContext = Helpers.GetDeclaringActivity(context);
1270
1271             if (declaringContext == declaringActivityOfCurrent)
1272                 return true;
1273             else
1274                 return false;
1275         }
1276
1277         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1278         internal static bool IsAlternateFlowActivity(Activity activity)
1279         {
1280             if (activity == null)
1281                 return false;
1282
1283             bool isAlternateFlowActivityAttribute = false;
1284             //dont want to use reflection to check for the alternate flow attribute
1285             //this is a fix for a perf issue - use of reflection in a ui loop
1286             if (!activity.UserData.Contains(typeof(AlternateFlowActivityAttribute)))
1287             {
1288                 isAlternateFlowActivityAttribute = activity.GetType().GetCustomAttributes(typeof(AlternateFlowActivityAttribute), true).Length != 0;
1289                 activity.UserData[typeof(AlternateFlowActivityAttribute)] = isAlternateFlowActivityAttribute;
1290             }
1291             else
1292             {
1293                 isAlternateFlowActivityAttribute = (bool)activity.UserData[typeof(AlternateFlowActivityAttribute)];
1294             }
1295
1296             return isAlternateFlowActivityAttribute;
1297         }
1298
1299         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1300         private static Activity GetActivity(Activity containerActivity, string id)
1301         {
1302             if (containerActivity != null)
1303             {
1304                 Queue activities = new Queue();
1305                 activities.Enqueue(containerActivity);
1306                 while (activities.Count > 0)
1307                 {
1308                     Activity activity = (Activity)activities.Dequeue();
1309                     if (activity.Enabled)
1310                     {
1311                         if (activity.Name == id)
1312                             return activity;
1313
1314                         if (activity is CompositeActivity)
1315                         {
1316                             foreach (Activity child in ((CompositeActivity)activity).Activities)
1317                                 activities.Enqueue(child);
1318                         }
1319                     }
1320                 }
1321             }
1322             return null;
1323         }
1324         #endregion
1325     }
1326     #endregion
1327
1328     #region Class TypeDescriptorContext (SHARED WITH ACTIVITIES, ORCHESTRATIONDESIGNER)
1329     [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
1330         Justification = "Not all assemblies that include this file instantiate the class.")]
1331     internal sealed class TypeDescriptorContext : ITypeDescriptorContext
1332     {
1333         private IServiceProvider serviceProvider;
1334         private PropertyDescriptor propDesc;
1335         private object instance;
1336
1337         public TypeDescriptorContext(IServiceProvider serviceProvider, PropertyDescriptor propDesc, object instance)
1338         {
1339             this.serviceProvider = serviceProvider;
1340             this.propDesc = propDesc;
1341             this.instance = instance;
1342         }
1343
1344         public IContainer Container
1345         {
1346             get
1347             {
1348                 return (IContainer)this.serviceProvider.GetService(typeof(IContainer));
1349             }
1350         }
1351         public object Instance
1352         {
1353             get
1354             {
1355                 return this.instance;
1356             }
1357         }
1358         public PropertyDescriptor PropertyDescriptor
1359         {
1360             get
1361             {
1362                 return this.propDesc;
1363             }
1364         }
1365         public object GetService(Type serviceType)
1366         {
1367             return this.serviceProvider.GetService(serviceType);
1368         }
1369
1370         public bool OnComponentChanging()
1371         {
1372             IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1373             if (componentChangeService != null)
1374             {
1375                 try
1376                 {
1377                     componentChangeService.OnComponentChanging(this.instance, this.propDesc);
1378                 }
1379                 catch (CheckoutException ce)
1380                 {
1381                     if (ce == CheckoutException.Canceled)
1382                         return false;
1383                     throw ce;
1384                 }
1385             }
1386
1387             return true;
1388         }
1389         public void OnComponentChanged()
1390         {
1391             IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1392             if (componentChangeService != null)
1393                 componentChangeService.OnComponentChanged(this.instance, this.propDesc, null, null);
1394         }
1395     }
1396     #endregion
1397
1398     // This class has been added as a fix for 
1399
1400
1401
1402     internal static class DebuggerHelpers
1403     {
1404         [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1405         internal static Activity ParseActivity(Activity parsingContext, string activityName)
1406         {
1407             if (parsingContext == null)
1408                 throw new ArgumentNullException("parsingContext");
1409             if (activityName == null)
1410                 throw new ArgumentNullException("activityName");
1411
1412             string currentAtivityName = activityName;
1413             string nextActivityName = string.Empty;
1414             int indexOfDot = activityName.IndexOf(".");
1415             if (indexOfDot != -1)
1416             {
1417                 currentAtivityName = activityName.Substring(0, indexOfDot);
1418                 nextActivityName = activityName.Substring(indexOfDot + 1);
1419                 if (nextActivityName.Length == 0)
1420                     return null;
1421             }
1422
1423             Activity currentActivity = null;
1424             currentActivity = GetActivity(parsingContext, currentAtivityName);
1425
1426             // The check for parsingContext.Parent != null is added here because IsCustomActivity returns true for root activities.
1427             if (currentActivity == null && (parsingContext is CompositeActivity) && parsingContext.Parent != null && Helpers.IsCustomActivity(parsingContext as CompositeActivity))
1428                 currentActivity = GetActivity(parsingContext, parsingContext.QualifiedName + "." + currentAtivityName);
1429
1430             if (currentActivity != null)
1431             {
1432                 if (nextActivityName.Length > 0)
1433                 {
1434                     if (!(currentActivity is CompositeActivity) || !Helpers.IsCustomActivity(currentActivity as CompositeActivity))
1435                         // current activity must be a custom activity, otherwise there should be no dots in the name.
1436                         return null;
1437
1438                     string[] names = nextActivityName.Split('.');
1439                     for (int i = 0; i < names.Length; i++)
1440                     {
1441                         Activity nextActivity = GetActivity(currentActivity, currentActivity.QualifiedName + "." + names[i]);
1442                         if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1443                             return null;
1444
1445                         CompositeActivity declaringActivity = Helpers.GetDeclaringActivity(nextActivity);
1446                         if (currentActivity != declaringActivity)
1447                             return null;
1448
1449                         currentActivity = nextActivity;
1450                     }
1451
1452                     return currentActivity;
1453                 }
1454                 else
1455                 {
1456                     // This activity should always be unlocked, unless if GetChildActivity() is called from
1457                     // within the custom activity's companion class, then we don't have the full qualified ID available
1458                     // at that time.  We allow this to succeed only if the declaring activity is the same as the declaring
1459                     // activity of the context activity passed in.
1460                     if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1461                     {
1462                         if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1463                             return null;
1464                     }
1465
1466                     return currentActivity;
1467                 }
1468             }
1469
1470             return null;
1471         }
1472
1473         private static Activity GetActivity(Activity containerActivity, string id)
1474         {
1475             if (containerActivity != null)
1476             {
1477                 Queue activities = new Queue();
1478                 activities.Enqueue(containerActivity);
1479                 while (activities.Count > 0)
1480                 {
1481                     Activity activity = (Activity)activities.Dequeue();
1482                     if (activity.Enabled)
1483                     {
1484                         if (activity.QualifiedName == id)
1485                             return activity;
1486
1487                         if (activity is CompositeActivity)
1488                         {
1489                             foreach (Activity child in ((CompositeActivity)activity).Activities)
1490                                 activities.Enqueue(child);
1491                         }
1492                     }
1493                 }
1494             }
1495             return null;
1496         }
1497
1498         private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1499         {
1500             CompositeActivity declaringContext = context as CompositeActivity;
1501
1502             CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1503
1504             // If the context activity is locked and it is a primitive activity
1505             // or NOT a custom activity then we need to find its enclosing 
1506             // custom activity.
1507             if (Helpers.IsActivityLocked(context) &&
1508                     (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1509                 )
1510                 declaringContext = Helpers.GetDeclaringActivity(context);
1511
1512             if (declaringContext == declaringActivityOfCurrent)
1513                 return true;
1514             else
1515                 return false;
1516         }
1517     }
1518 }