Dictionary<int, Action<XamlContext, XElement>> ExtractConnectionId(XamlContext ctx, MethodDef method) {
			var context = new DecompilerContext(method.Module) {
				CurrentType = method.DeclaringType,
				CurrentMethod = method,
				CancellationToken = ctx.CancellationToken
			};
			var body = new ILBlock(new ILAstBuilder().Build(method, true, context));
			new ILAstOptimizer().Optimize(context, body);

			var sw = body.GetSelfAndChildrenRecursive<ILSwitch>().FirstOrDefault();
			if (sw == null)
				return null;

			var connIds = new Dictionary<int, Action<XamlContext, XElement>>();
			foreach (var cas in sw.CaseBlocks) {
				if (cas.Values == null)
					continue;

				Action<XamlContext, XElement> cb = null;
				foreach (var node in cas.Body) {
					var expr = node as ILExpression;
					if (expr == null)
						continue;

					switch (expr.Code) {
						case ILCode.Stfld:
							cb += new FieldAssignment { FieldName = ((IField)expr.Operand).Name }.Callback;
							break;

						case ILCode.Call:
						case ILCode.Callvirt:
							var operand = (IMethod)expr.Operand;
							if (operand.Name == "AddHandler" && operand.DeclaringType.FullName == "System.Windows.UIElement") {
								// Attached event
								var re = expr.Arguments[1];
								var ctor = expr.Arguments[2];
								var reField = re.Operand as IField;

								if (re.Code != ILCode.Ldsfld || ctor.Code != ILCode.Newobj ||
								    ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn) {
									cb += new Error { Msg = "Attached event '" + reField.Name + "'." }.Callback;
									break;
								}
								var handler = (IMethod)ctor.Arguments[1].Operand;
								string evName = reField.Name;
								if (evName.EndsWith("Event"))
									evName = evName.Substring(0, evName.Length - 5);

								cb += new EventAttachment {
									AttachedType = reField.DeclaringType.ResolveTypeDefThrow(),
									EventName = evName,
									MethodName = handler.Name
								}.Callback;
							}
							else {
								// CLR event
								var add = operand.ResolveMethodDefThrow();
								var ev = add.DeclaringType.Events.FirstOrDefault(e => e.AddMethod == add);

								var ctor = expr.Arguments[1];
								if (ev == null || ctor.Code != ILCode.Newobj ||
								    ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn) {
									cb += new Error { Msg = "Attached event '" + add.Name + "'." }.Callback;
									break;
								}
								var handler = (IMethod)ctor.Arguments[1].Operand;

								cb += new EventAttachment {
									EventName = ev.Name,
									MethodName = handler.Name
								}.Callback;
							}
							break;
					}
				}

				if (cb != null) {
					foreach (var id in cas.Values)
						connIds[id] = cb;
				}
			}

			return connIds.Count == 0 ? null : connIds;
		}
        Dictionary <int, Action <XamlContext, XElement> > ExtractConnectionId(XamlContext ctx, MethodDef method)
        {
            var context = new DecompilerContext(method.Module)
            {
                CurrentType       = method.DeclaringType,
                CurrentMethod     = method,
                CancellationToken = ctx.CancellationToken
            };
            var body = new ILBlock(new ILAstBuilder().Build(method, true, context));

            new ILAstOptimizer().Optimize(context, body);

            var sw = body.GetSelfAndChildrenRecursive <ILSwitch>().FirstOrDefault();

            if (sw == null)
            {
                return(null);
            }

            var connIds = new Dictionary <int, Action <XamlContext, XElement> >();

            foreach (var cas in sw.CaseBlocks)
            {
                if (cas.Values == null)
                {
                    continue;
                }

                Action <XamlContext, XElement> cb = null;
                foreach (var node in cas.Body)
                {
                    var expr = node as ILExpression;
                    if (expr == null)
                    {
                        continue;
                    }

                    switch (expr.Code)
                    {
                    case ILCode.Stfld:
                        cb += new FieldAssignment {
                            FieldName = ((IField)expr.Operand).Name
                        }.Callback;
                        break;

                    case ILCode.Call:
                    case ILCode.Callvirt:
                        var operand = (IMethod)expr.Operand;
                        if (operand.Name == "AddHandler" && operand.DeclaringType.FullName == "System.Windows.UIElement")
                        {
                            // Attached event
                            var re      = expr.Arguments[1];
                            var ctor    = expr.Arguments[2];
                            var reField = re.Operand as IField;

                            if (re.Code != ILCode.Ldsfld || ctor.Code != ILCode.Newobj ||
                                ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn)
                            {
                                cb += new Error {
                                    Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, reField.Name)
                                }.Callback;
                                break;
                            }
                            var    handler = (IMethod)ctor.Arguments[1].Operand;
                            string evName  = reField.Name;
                            if (evName.EndsWith("Event"))
                            {
                                evName = evName.Substring(0, evName.Length - 5);
                            }

                            cb += new EventAttachment {
                                AttachedType = reField.DeclaringType.ResolveTypeDefThrow(),
                                EventName    = evName,
                                MethodName   = handler.Name
                            }.Callback;
                        }
                        else
                        {
                            // CLR event
                            var add = operand.ResolveMethodDefThrow();
                            var ev  = add.DeclaringType.Events.FirstOrDefault(e => e.AddMethod == add);

                            var ctor = expr.Arguments[1];
                            if (ev == null || ctor.Code != ILCode.Newobj ||
                                ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn)
                            {
                                cb += new Error {
                                    Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, add.Name)
                                }.Callback;
                                break;
                            }
                            var handler = (IMethod)ctor.Arguments[1].Operand;

                            cb += new EventAttachment {
                                EventName  = ev.Name,
                                MethodName = handler.Name
                            }.Callback;
                        }
                        break;
                    }
                }

                if (cb != null)
                {
                    foreach (var id in cas.Values)
                    {
                        connIds[id] = cb;
                    }
                }
            }

            return(connIds.Count == 0 ? null : connIds);
        }