static bool _IsDelegate(CodeExpression target, CodeDomResolver res)
        {
            var v = target as CodeVariableReferenceExpression;

            if (null != v && v.UserData.Contains("slang:unresolved"))
            {
                var scope = res.GetScope(target);
                if (scope.MemberNames.Contains(v.VariableName))
                {
                    return(true);
                }
            }
            return(false);
        }
        static CodeDelegateCreateExpression _GetDelegateFromFields(CodeObjectCreateExpression oc, CodeExpression target, CodeDomResolver res)
        {
            var v = target as CodeVariableReferenceExpression;

            if (null != v)
            {
                var scope = res.GetScope(v);
                if (scope.MemberNames.Contains(v.VariableName))
                {
                    return(new CodeDelegateCreateExpression(oc.CreateType, new CodeThisReferenceExpression(), v.VariableName));
                }
            }
            throw new NotImplementedException();
        }
 static void _Patch(CodeTypeReference tr, CodeDomVisitContext ctx, CodeDomResolver res)
 {
     if (null != tr)
     {
         if (res.IsValidType(tr, res.GetScope(tr)))
         {
             tr.UserData.Remove("slang:unresolved");
             return;
         }
         // this is probably a nested type but with . instead of +
         // so now we need to crack it apart and hunt it down
         throw new NotImplementedException();
     }
 }
        static void _Patch(CodeVariableDeclarationStatement vd, CodeDomVisitContext ctx, CodeDomResolver resolver)
        {
            if (null != vd)
            {
                if (CodeDomResolver.IsNullOrVoidType(vd.Type))
                {
                    if (null == vd.InitExpression)
                    {
                        throw new ArgumentException("The code contains an incomplete variable declaration.", "resolver");
                    }
                    if (!_HasUnresolved(vd.InitExpression))
                    {
                        var t = resolver.GetTypeOfExpression(vd.InitExpression, resolver.GetScope(vd.InitExpression));

                        vd.Type = t;
                        if (!CodeDomResolver.IsNullOrVoidType(t))
                        {
                            vd.UserData.Remove("slang:unresolved");
                        }
                    }
                }
            }
        }
        static void _Patch(CodeFieldReferenceExpression fr, CodeDomVisitContext ctx, CodeDomResolver resolver)
        {
            if (null != fr)
            {
                var path = _GetUnresRootPathOfExpression(fr);
                if (null != path)
                {
                    // now we have something to work with.
                    var scope = resolver.GetScope(fr);
                    var sa    = path.Split('.');
                    if (1 == sa.Length)
                    {
                        System.Diagnostics.Debugger.Break();
                        throw new NotImplementedException();
                    }
                    else
                    {
                        object            t   = null;
                        string            tn  = null;
                        CodeExpression    tf  = fr;
                        CodeExpression    ptf = null;
                        CodeTypeReference ctr = null;
                        for (var i = sa.Length - 1; i >= 1; --i)
                        {
                            tn  = string.Join(".", sa, 0, i);
                            ptf = tf;
                            tf  = _GetTargetOfExpression(tf);
                            ctr = new CodeTypeReference(tn);
                            t   = resolver.TryResolveType(ctr, scope);
                            if (null != t)
                            {
                                break;
                            }
                        }
                        if (null != t)
                        {
                            var tt = t as Type;
                            if (null != tt)
                            {
                                ctr = new CodeTypeReference(tt);
                            }
                            else
                            {
                                ctr = resolver.GetQualifiedType(ctr, scope);
                            }
                            // we found a type reference
                            _SetTargetOfExpression(ptf, new CodeTypeReferenceExpression(ctr));
                            return;
                            //args.Cancel = true;
                        }
                    }
                }

                // this probably means part of our field has been resolved, or at the very least
                // it does not come from a rooted var ref.
                if (!fr.TargetObject.UserData.Contains("slang:unresolved"))
                {
                    var scope    = resolver.GetScope(fr);
                    var binder   = new CodeDomBinder(scope);
                    var t        = resolver.GetTypeOfExpression(fr.TargetObject);
                    var isStatic = false;
                    var tre      = fr.TargetObject as CodeTypeReferenceExpression;
                    if (null != tre)
                    {
                        isStatic = true;
                    }
                    var tt = resolver.TryResolveType(isStatic ? tre.Type: t, scope);
                    if (null == tt)
                    {
                        throw new InvalidOperationException(string.Format("The type {0} could not be resolved.", t.BaseType));
                    }

                    var td = tt as CodeTypeDeclaration;
                    // TODO: This code could be a lot faster if we added some functionality to the binder
                    // we're just checking to see if the method, property or field exists
                    var m = binder.GetField(tt, fr.FieldName, _BindFlags);
                    if (null != m)
                    {
                        fr.UserData.Remove("slang:unresolved");
                        return;
                    }
                    m = binder.GetEvent(tt, fr.FieldName, _BindFlags);
                    if (null != m)
                    {
                        var er = new CodeEventReferenceExpression(fr.TargetObject, fr.FieldName);
                        CodeDomVisitor.ReplaceTarget(ctx, er);
                        return;
                    }
                    var ml = binder.GetMethodGroup(tt, fr.FieldName, _BindFlags);
                    if (0 < ml.Length)
                    {
                        var mr = new CodeMethodReferenceExpression(fr.TargetObject, fr.FieldName);
                        CodeDomVisitor.ReplaceTarget(ctx, mr);
                        return;
                    }
                    ml = binder.GetPropertyGroup(tt, fr.FieldName, _BindFlags);
                    if (0 < ml.Length)
                    {
                        var pr = new CodePropertyReferenceExpression(fr.TargetObject, fr.FieldName);
                        CodeDomVisitor.ReplaceTarget(ctx, pr);
                        return;
                    }
                    throw new InvalidProgramException(string.Format("Cannot deterimine the target reference {0}", fr.FieldName));
                }
            }
        }
        static void _Patch(CodeVariableReferenceExpression vr, CodeDomVisitContext ctx, CodeDomResolver resolver)
        {
            if (null != vr)
            {
                if ("NodeFlags" == vr.VariableName)
                {
                    System.Diagnostics.Debugger.Break();
                }
                var scope = resolver.GetScope(vr);
                if (scope.VariableTypes.ContainsKey(vr.VariableName))
                {
                    vr.UserData.Remove("slang:unresolved");
                    return;
                }
                // we need to replace it.
                if (scope.ArgumentTypes.ContainsKey(vr.VariableName))
                {
                    var a = new CodeArgumentReferenceExpression(vr.VariableName);
                    CodeDomVisitor.ReplaceTarget(ctx, a);
                    return;
                    //args.Cancel = true;
                }
                else if (scope.FieldNames.Contains(vr.VariableName))
                {
                    CodeTypeReference tref;
                    // find out where it belongs.
                    if (scope.ThisTargets.Contains(vr.VariableName))
                    {
                        var f = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, f);
                        //return;
                    }
                    else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref))
                    {
                        var f = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, f);
                        //return;
                    }

                    return;
                }
                else if (scope.MethodNames.Contains(vr.VariableName))
                {
                    CodeTypeReference tref;
                    // find out where it belongs.
                    if (scope.ThisTargets.Contains(vr.VariableName))
                    {
                        var m = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, m);
                        return;
                        //args.Cancel = true;
                    }
                    if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref))
                    {
                        var m = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, m);
                        return;
                        //args.Cancel = true;
                    }
                }
                else if (scope.PropertyNames.Contains(vr.VariableName))
                {
                    CodeTypeReference tref;
                    // find out where it belongs.
                    if (scope.ThisTargets.Contains(vr.VariableName))
                    {
                        var p = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, p);
                        return;
                        //args.Cancel = true;
                    }
                    else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref))
                    {
                        var p = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, p);
                        return;
                        //args.Cancel = true;
                    }
                }
                else if (scope.EventNames.Contains(vr.VariableName))
                {
                    CodeTypeReference tref;
                    // find out where it belongs.
                    if (scope.ThisTargets.Contains(vr.VariableName))
                    {
                        var e = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, e);
                        return;
                        //args.Cancel = true;
                    }
                    else if (scope.TypeTargets.TryGetValue(vr.VariableName, out tref))
                    {
                        var e = new CodeEventReferenceExpression(new CodeTypeReferenceExpression(tref), vr.VariableName);
                        CodeDomVisitor.ReplaceTarget(ctx, e);
                        return;
                        //args.Cancel = true;
                    }
                }
                return;
            }
            return;
        }