Re-enable 'crlf' attributes on *.cs
[mono.git] / mcs / mcs / namespace.cs
index 1694cf577afbba0cdd6ea19e9a2e639ecc730e9c..a7442ae87c0ff83da9f0ceaa4c3d3f9e686b3960 100644 (file)
@@ -9,69 +9,55 @@
 // Copyright 2003-2008 Novell, Inc.
 //
 using System;
-using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 using System.Reflection;
+using System.Linq;
 
 namespace Mono.CSharp {
 
        public class RootNamespace : Namespace {
-               static MethodInfo get_namespaces_method;
 
-               string alias_name;
-               Assembly referenced_assembly;
+               protected readonly string alias_name;
+               protected Assembly [] referenced_assemblies;
 
-               Hashtable all_namespaces;
+               Dictionary<string, Namespace> all_namespaces;
 
-               static Hashtable root_namespaces;
-               public static GlobalRootNamespace Global;
-               
-               static RootNamespace ()
-               {
-                       get_namespaces_method = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance | BindingFlags.NonPublic);
-
-                       Reset ();
-               }
-
-               public static void Reset ()
-               {
-                       root_namespaces = new Hashtable ();
-                       Global = new GlobalRootNamespace ();
-                       root_namespaces ["global"] = Global;
-               }
-
-               protected RootNamespace (string alias_name, Assembly assembly)
+               public RootNamespace (string alias_name)
                        : base (null, String.Empty)
                {
                        this.alias_name = alias_name;
-                       referenced_assembly = assembly;
+                       referenced_assemblies = new Assembly [0];
 
-                       all_namespaces = new Hashtable ();
+                       all_namespaces = new Dictionary<string, Namespace> ();
                        all_namespaces.Add ("", this);
-
-                       if (referenced_assembly != null)
-                               ComputeNamespaces (this.referenced_assembly);
                }
 
-               public static void DefineRootNamespace (string name, Assembly assembly)
+               public void AddAssemblyReference (Assembly a)
                {
-                       if (name == "global") {
-                               NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null);
-                               return;
+                       foreach (Assembly assembly in referenced_assemblies) {
+                               if (a == assembly)
+                                       return;
                        }
-                       RootNamespace retval = GetRootNamespace (name);
-                       if (retval == null || retval.referenced_assembly != assembly)
-                               root_namespaces [name] = new RootNamespace (name, assembly);
-               }
 
-               public static RootNamespace GetRootNamespace (string name)
-               {
-                       return (RootNamespace) root_namespaces [name];
+                       int top = referenced_assemblies.Length;
+                       Assembly [] n = new Assembly [top + 1];
+                       referenced_assemblies.CopyTo (n, 0);
+                       n [top] = a;
+                       referenced_assemblies = n;
                }
 
-               public virtual Type LookupTypeReflection (string name, Location loc)
+               public void ImportTypes (CompilerContext ctx)
                {
-                       return GetTypeInAssembly (referenced_assembly, name);
+                       foreach (Assembly a in referenced_assemblies) {
+                               try {
+                                       ImportAssembly (a);
+                               } catch (TypeLoadException e) {
+                                       ctx.Report.Error (11, Location.Null, e.Message);
+                               } catch (System.IO.FileNotFoundException) {
+                                       ctx.Report.Error (12, Location.Null, "An assembly `{0}' is used without being referenced",
+                                               a.FullName);
+                               }
+                       }
                }
 
                public void RegisterNamespace (Namespace child)
@@ -82,7 +68,7 @@ namespace Mono.CSharp {
 
                public bool IsNamespace (string name)
                {
-                       return all_namespaces.Contains (name);
+                       return all_namespaces.ContainsKey (name);
                }
 
                protected void RegisterNamespace (string dotted_name)
@@ -91,74 +77,56 @@ namespace Mono.CSharp {
                                GetNamespace (dotted_name, true);
                }
 
-               void RegisterExtensionMethodClass (Type t)
-               {
-                       string n = t.Namespace;
-                       Namespace ns = n == null ? Global : (Namespace)all_namespaces [n];
-                       if (ns == null)
-                               ns = GetNamespace (n, true);
-                       ns.RegisterExternalExtensionMethodClass (t);
-               }
-
-               protected void ComputeNamespaces (Assembly assembly)
+               public void ImportAssembly (Assembly assembly)
                {
-                       // How to test whether attribute exists without loading the assembly :-(
-#if NET_2_1
-                       const string SystemCore = "System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"; 
-#else
-                       const string SystemCore = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 
-#endif
-                       if (TypeManager.extension_attribute_type == null &&
-                               assembly.FullName == SystemCore) {
-                               TypeManager.extension_attribute_type = assembly.GetType("System.Runtime.CompilerServices.ExtensionAttribute");
-                       }
-                       bool contains_extension_methods = TypeManager.extension_attribute_type != null &&
-                                       assembly.IsDefined(TypeManager.extension_attribute_type, false);
-                       if (get_namespaces_method != null && !contains_extension_methods) {
-                               string [] namespaces = (string []) get_namespaces_method.Invoke (assembly, null);
-                               foreach (string ns in namespaces)
-                                       RegisterNamespace (ns);
-                               return;
-                       }
-  
-                       foreach (Type t in assembly.GetExportedTypes ()) {
-                               if ((t.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
-                                       contains_extension_methods && t.IsDefined (TypeManager.extension_attribute_type, false))
-                                       RegisterExtensionMethodClass (t);
-                               else
-                                       RegisterNamespace (t.Namespace);
-                       }
-               }
+                       Type extension_type = null;
+                       var all_attributes = CustomAttributeData.GetCustomAttributes (assembly);
+                       foreach (var attr in all_attributes) {
+                               var dt = attr.Constructor.DeclaringType;
+                               if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
+                                       extension_type = dt;
+                                       break;
+                               }
+                       }
 
-               protected static Type GetTypeInAssembly (Assembly assembly, string name)
-               {
-                       Type t = assembly.GetType (name);
-                       if (t == null)
-                               return null;
+                       //
+                       // This part tries to simulate loading of top-level
+                       // types only, any missing dependencies are ignores here.
+                       // Full error report is reported later when the type is
+                       // actually used
+                       //
+                       Type[] all_types;
+                       try {
+                               all_types = assembly.GetTypes ();
+                       } catch (ReflectionTypeLoadException e) {
+                               all_types = e.Types;
+                       }
 
-                       if (t.IsPointer)
-                               throw new InternalErrorException ("Use GetPointerType() to get a pointer");
+                       Namespace ns = this;
+                       string prev_namespace = null;
+                       foreach (var t in all_types) {
+                               if (t == null || t.IsNested)
+                                       continue;
 
-                       TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
-                       if (ta == TypeAttributes.NestedPrivate)
-                               return null;
+                               if (t.Name[0] == '<')
+                                       continue;
 
-                       if ((ta == TypeAttributes.NotPublic ||
-                            ta == TypeAttributes.NestedAssembly ||
-                            ta == TypeAttributes.NestedFamANDAssem) &&
-                           !TypeManager.IsThisOrFriendAssembly (t.Assembly))
-                               return null;
+                               var it = Import.CreateType (t, null);
+                               if (it == null)
+                                       continue;
 
-                       return t;
-               }
+                               if (prev_namespace != t.Namespace) {
+                                       ns = t.Namespace == null ? this : GetNamespace (t.Namespace, true);
+                                       prev_namespace = t.Namespace;
+                               }
 
-               public override string ToString ()
-               {
-                       return String.Format ("RootNamespace ({0}::)", alias_name);
-               }
+                               ns.AddType (it);
+
+                               if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
+                                       it.SetExtensionMethodContainer ();
+                               }
+                       }
+               }
 
                public override string GetSignatureForError ()
                {
@@ -167,39 +135,31 @@ namespace Mono.CSharp {
        }
 
        public class GlobalRootNamespace : RootNamespace {
-               Assembly [] assemblies;
                Module [] modules;
+               Dictionary<string, RootNamespace> root_namespaces;
 
-               public GlobalRootNamespace ()
-                       : base ("global", null)
+               public static GlobalRootNamespace Instance = new GlobalRootNamespace ();
+
+               GlobalRootNamespace ()
+                       : base ("global")
+               {
+                       root_namespaces = new Dictionary<string, RootNamespace> ();
+                       root_namespaces.Add (alias_name, this);
+               }
+
+               public static void Reset ()
                {
-                       assemblies = new Assembly [0];
+                       Instance = new GlobalRootNamespace ();
                }
 
                public Assembly [] Assemblies {
-                       get { return assemblies; }
+                   get { return referenced_assemblies; }
                }
 
                public Module [] Modules {
                        get { return modules; }
                }
 
-               public void AddAssemblyReference (Assembly a)
-               {
-                       foreach (Assembly assembly in assemblies) {
-                               if (a == assembly)
-                                       return;
-                       }
-
-                       int top = assemblies.Length;
-                       Assembly [] n = new Assembly [top + 1];
-                       assemblies.CopyTo (n, 0);
-                       n [top] = a;
-                       assemblies = n;
-
-                       ComputeNamespaces (a);
-               }
-
                public void AddModuleReference (Module m)
                {
                        int top = modules != null ? modules.Length : 0;
@@ -209,66 +169,50 @@ namespace Mono.CSharp {
                        n [top] = m;
                        modules = n;
 
-                       if (m == CodeGen.Module.Builder)
+                       if (m == RootContext.ToplevelTypes.Builder)
                                return;
 
-                       foreach (Type t in m.GetTypes ())
+                       foreach (var t in m.GetTypes ())
                                RegisterNamespace (t.Namespace);
                }
 
-               public override void Error_NamespaceDoesNotExist(DeclSpace ds, Location loc, string name)
+               public void ComputeNamespaces (CompilerContext ctx)
                {
-                       Report.Error (400, loc, "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
-                               name);
+                       foreach (RootNamespace rn in root_namespaces.Values) {
+                               rn.ImportTypes (ctx);
+                       }
                }
 
-               public override Type LookupTypeReflection (string name, Location loc)
+               public void DefineRootNamespace (string alias, Assembly assembly, CompilerContext ctx)
                {
-                       Type found_type = null;
-               
-                       foreach (Assembly a in assemblies) {
-                               Type t = GetTypeInAssembly (a, name);
-                               if (t == null)
-                                       continue;
-                                       
-                               if (found_type == null) {
-                                       found_type = t;
-                                       continue;
-                               }
+                       if (alias == alias_name) {
+                               NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null, ctx.Report);
+                               return;
+                       }
 
-                               Report.SymbolRelatedToPreviousError (found_type);
-                               Report.SymbolRelatedToPreviousError (t);
-                               Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
-                                       
-                               return found_type;
+                       RootNamespace retval = GetRootNamespace (alias);
+                       if (retval == null) {
+                               retval = new RootNamespace (alias);
+                               root_namespaces.Add (alias, retval);
                        }
 
-                       if (modules != null) {
-                               foreach (Module module in modules) {
-                                       Type t = module.GetType (name);
-                                       if (t == null)
-                                               continue;
+                       retval.AddAssemblyReference (assembly);
+               }
 
-                                       if (found_type == null) {
-                                               found_type = t;
-                                               continue;
-                                       }
+               public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
+               {
+                       ctx.Compiler.Report.Error (400, loc,
+                               "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
+                               name);
+               }
 
-                                       Report.SymbolRelatedToPreviousError (found_type);
-                                       if (loc.IsNull) {
-                                               DeclSpace ds = TypeManager.LookupDeclSpace (t);
-                                               Report.Warning (1685, 1, ds.Location, "The type `{0}' conflicts with the predefined type `{1}' and will be ignored",
-                                                       ds.GetSignatureForError (), TypeManager.CSharpName (found_type));
-                                               return found_type;
-                                       }
-                                       Report.SymbolRelatedToPreviousError (t);
-                                       Report.Warning (436, 2, loc, "The type `{0}' conflicts with the imported type `{1}'. Ignoring the imported type definition",
-                                               TypeManager.CSharpName (t), TypeManager.CSharpName (found_type));
-                                       return t;
-                               }
-                       }
+               public RootNamespace GetRootNamespace (string name)
+               {
+                       RootNamespace rn;
+                       if (!root_namespaces.TryGetValue (name, out rn))
+                               return null;
 
-                       return found_type;
+                       return rn;
                }
        }
 
@@ -282,11 +226,11 @@ namespace Mono.CSharp {
                
                Namespace parent;
                string fullname;
-               IDictionary namespaces;
-               IDictionary declspaces;
-               Hashtable cached_types;
+               protected Dictionary<string, Namespace> namespaces;
+               protected Dictionary<string, IList<TypeSpec>> types;
+               Dictionary<string, TypeExpr> cached_types;
                RootNamespace root;
-               ArrayList external_exmethod_classes;
+               bool cls_checked;
 
                public readonly MemberName MemberName;
 
@@ -299,7 +243,7 @@ namespace Mono.CSharp {
                {
                        // Expression members.
                        this.eclass = ExprClass.Namespace;
-                       this.Type = typeof (Namespace);
+                       this.Type = InternalType.FakeInternalType;
                        this.loc = Location.Null;
 
                        this.parent = parent;
@@ -329,60 +273,53 @@ namespace Mono.CSharp {
                        else
                                MemberName = new MemberName (name);
 
-                       namespaces = new HybridDictionary ();
-                       cached_types = new Hashtable ();
+                       namespaces = new Dictionary<string, Namespace> ();
+                       cached_types = new Dictionary<string, TypeExpr> ();
 
                        root.RegisterNamespace (this);
                }
 
-               public override Expression DoResolve (EmitContext ec)
-               {
-                       return this;
-               }
-
-               public virtual void Error_NamespaceDoesNotExist (DeclSpace ds, Location loc, string name)
-               {
-                       if (name.IndexOf ('`') > 0) {
-                               FullNamedExpression retval = Lookup (ds, SimpleName.RemoveGenericArity (name), loc);
-                               if (retval != null) {
-                                       Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
-                                       return;
-                               }
-                       } else {
-                               Type t = LookForAnyGenericType (name);
-                               if (t != null) {
-                                       Error_InvalidNumberOfTypeArguments (t, loc);
-                                       return;
-                               }
-                       }
+               #region Properties
 
-                       Report.Error (234, loc, "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
-                               name, GetSignatureForError ());
+               /// <summary>
+               ///   The qualified name of the current namespace
+               /// </summary>
+               public string Name {
+                       get { return fullname; }
                }
 
-               public static void Error_InvalidNumberOfTypeArguments (Type t, Location loc)
-               {
-                       Report.SymbolRelatedToPreviousError (t);
-                       Report.Error (305, loc, "Using the generic type `{0}' requires `{1}' type argument(s)",
-                               TypeManager.CSharpName(t), TypeManager.GetNumberOfTypeArguments(t).ToString());
+               /// <summary>
+               ///   The parent of this namespace, used by the parser to "Pop"
+               ///   the current namespace declaration
+               /// </summary>
+               public Namespace Parent {
+                       get { return parent; }
                }
 
-               public static void Error_TypeArgumentsCannotBeUsed (Type t, Location loc)
-               {
-                       Report.SymbolRelatedToPreviousError (t);
-                       Error_TypeArgumentsCannotBeUsed (loc, "type", TypeManager.CSharpName (t));
-               }
+               #endregion
 
-               public static void Error_TypeArgumentsCannotBeUsed (MethodBase mi, Location loc)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       Report.SymbolRelatedToPreviousError (mi);
-                       Error_TypeArgumentsCannotBeUsed (loc, "method", TypeManager.CSharpSignature (mi));
+                       return this;
                }
 
-               static void Error_TypeArgumentsCannotBeUsed (Location loc, string type, string name)
+               public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
                {
-                       Report.Error(308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
-                               type, name);
+                       FullNamedExpression retval = Lookup (ctx.Compiler, name, -System.Math.Max (1, arity), loc);
+                       if (retval != null) {
+                               Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+                               return;
+                       }
+
+                       Namespace ns;
+                       if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
+                               ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+                               return;
+                       }
+
+                       ctx.Compiler.Report.Error (234, loc,
+                               "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
+                               name, GetSignatureForError ());
                }
 
                public override string GetSignatureForError ()
@@ -401,8 +338,7 @@ namespace Mono.CSharp {
                        else
                                first = name;
 
-                       ns = (Namespace) namespaces [first];
-                       if (ns == null) {
+                       if (!namespaces.TryGetValue (first, out ns)) {
                                if (!create)
                                        return null;
 
@@ -416,151 +352,339 @@ namespace Mono.CSharp {
                        return ns;
                }
 
-               TypeExpr LookupType (string name, Location loc)
+               public TypeExpr LookupType (CompilerContext ctx, string name, int arity, bool silent, Location loc)
                {
-                       if (cached_types.Contains (name))
-                               return cached_types [name] as TypeExpr;
+                       if (types == null)
+                               return null;
 
-                       Type t = null;
-                       if (declspaces != null) {
-                               DeclSpace tdecl = declspaces [name] as DeclSpace;
-                               if (tdecl != null) {
-                                       //
-                                       // Note that this is not:
-                                       //
-                                       //   t = tdecl.DefineType ()
-                                       //
-                                       // This is to make it somewhat more useful when a DefineType
-                                       // fails due to problems in nested types (more useful in the sense
-                                       // of fewer misleading error messages)
-                                       //
-                                       tdecl.DefineType ();
-                                       t = tdecl.TypeBuilder;
+                       TypeExpr te;
+                       if (arity == 0 && cached_types.TryGetValue (name, out te))
+                               return te;
+
+                       IList<TypeSpec> found;
+                       if (!types.TryGetValue (name, out found))
+                               return null;
+
+                       TypeSpec best = null;
+                       foreach (var ts in found) {
+                               if (ts.Arity == arity) {
+                                       if (best == null) {
+                                               best = ts;
+                                               continue;
+                                       }
+
+                                       var pts = best as PredefinedTypeSpec;
+                                       if (pts == null)
+                                               pts = ts as PredefinedTypeSpec;
+
+                                       if (pts != null) {
+                                               ctx.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+
+                                               // TODO: This should use different warning number but we want to be csc compatible
+                                               ctx.Report.Warning (1685, 1, loc,
+                                                       "The predefined type `{0}.{1}' is redefined in the source code. Ignoring the local type definition",
+                                                       pts.Namespace, pts.Name);
+                                               best = pts;
+                                               continue;
+                                       }
+
+                                       if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
+                                               ctx.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               if (silent) {
+                                                       ctx.Report.Warning (1685, 1, loc,
+                                                               "The predefined type `{0}' is defined in multiple assemblies. Using definition from `{1}'",
+                                                               ts.GetSignatureForError (), best.Assembly.GetName ().Name);
+                                               } else {
+                                                       ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+                                               }
+
+                                               break;
+                                       }
+
+                                       if (best.MemberDefinition.IsImported)
+                                               best = ts;
+
+                                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, best.MemberDefinition.Assembly))
+                                               continue;
+
+                                       if (silent)
+                                               continue;
+
+                                       if (ts.MemberDefinition.IsImported)
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+
+                                       ctx.Report.Warning (436, 2, loc,
+                                               "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
+                                               best.GetSignatureForError ());
+                               }
+
+                               //
+                               // Lookup for the best candidate with closest arity match
+                               //
+                               if (arity < 0) {
+                                       if (best == null) {
+                                               best = ts;
+                                       } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+                                               best = ts;
+                                       }
                                }
                        }
-                       string lookup = t != null ? t.FullName : (fullname.Length == 0 ? name : fullname + "." + name);
-                       Type rt = root.LookupTypeReflection (lookup, loc);
 
-                       // HACK: loc.IsNull when the type is core type
-                       if (t == null || (rt != null && loc.IsNull))
-                               t = rt;
+                       if (best == null)
+                               return null;
+
+                       te = new TypeExpression (best, Location.Null);
+
+                       // TODO MemberCache: Cache more
+                       if (arity == 0 && !silent)
+                               cached_types.Add (name, te);
 
-                       TypeExpr te = t == null ? null : new TypeExpression (t, Location.Null);
-                       cached_types [name] = te;
                        return te;
                }
 
-               ///
-               /// Used for better error reporting only
-               /// 
-               public Type LookForAnyGenericType (string typeName)
+               TypeSpec LookupType (string name, int arity)
                {
-                       if (declspaces == null)
+                       if (types == null)
                                return null;
 
-                       typeName = SimpleName.RemoveGenericArity (typeName);
+                       IList<TypeSpec> found;
+                       if (types.TryGetValue (name, out found)) {
+                               TypeSpec best = null;
+
+                               foreach (var ts in found) {
+                                       if (ts.Arity == arity)
+                                               return ts;
 
-                       foreach (DictionaryEntry de in declspaces) {
-                               string type_item = (string) de.Key;
-                               int pos = type_item.LastIndexOf ('`');
-                               if (pos == typeName.Length && String.Compare (typeName, 0, type_item, 0, pos) == 0)
-                                       return ((DeclSpace) de.Value).TypeBuilder;
+                                       //
+                                       // Lookup for the best candidate with closest arity match
+                                       //
+                                       if (arity < 0) {
+                                               if (best == null) {
+                                                       best = ts;
+                                               } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+                                                       best = ts;
+                                               }
+                                       }
+                               }
+                               
+                               return best;
                        }
+
                        return null;
                }
 
-               public FullNamedExpression Lookup (DeclSpace ds, string name, Location loc)
+               public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
                {
-                       if (namespaces.Contains (name))
-                               return (Namespace) namespaces [name];
+                       if (arity == 0 && namespaces.ContainsKey (name))
+                               return namespaces [name];
 
-                       return LookupType (name, loc);
+                       return LookupType (ctx, name, arity, false, loc);
                }
 
-               public void RegisterExternalExtensionMethodClass (Type type)
+               //
+               // Completes types with the given `prefix'
+               //
+               public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
                {
-                       if (external_exmethod_classes == null)
-                               external_exmethod_classes = new ArrayList ();
+                       if (types == null)
+                               return Enumerable.Empty<string> ();
+
+                       var res = from item in types
+                                         where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
+                                         select item.Key;
+
+                       if (namespaces != null)
+                               res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
 
-                       external_exmethod_classes.Add (type);
+                       return res;
                }
 
                /// 
                /// Looks for extension method in this namespace
                /// 
-               public ArrayList LookupExtensionMethod (Type extensionType, ClassOrStruct currentClass, string name)
+               public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, ClassOrStruct currentClass, string name, int arity)
                {
-                       ArrayList found = null;
-
-                       if (declspaces != null) {
-                               IEnumerator e = declspaces.Values.GetEnumerator ();
-                               e.Reset ();
-                               while (e.MoveNext ()) {
-                                       Class c = e.Current as Class;
-                                       if (c == null)
-                                               continue;
+                       if (types == null)
+                               return null;
 
-                                       if (!c.IsStaticClass)
+                       List<MethodSpec> found = null;
+
+                       var invocation_type = currentClass == null ? InternalType.FakeInternalType : currentClass.CurrentType;
+
+                       // TODO: Add per namespace flag when at least 1 type has extension
+
+                       foreach (var tgroup in types.Values) {
+                               foreach (var ts in tgroup) {
+                                       if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
                                                continue;
 
-                                       ArrayList res = c.MemberCache.FindExtensionMethods (extensionType, name, c != currentClass);
+                                       var res = ts.MemberCache.FindExtensionMethods (invocation_type, extensionType, name, arity);
                                        if (res == null)
                                                continue;
 
-                                       if (found == null)
+                                       if (found == null) {
                                                found = res;
-                                       else
+                                       } else {
                                                found.AddRange (res);
+                                       }
                                }
                        }
 
-                       if (external_exmethod_classes == null)
-                               return found;
+                       return found;
+               }
 
-                       foreach (Type t in external_exmethod_classes) {
-                               MemberCache m = TypeHandle.GetMemberCache (t);
-                               ArrayList res = m.FindExtensionMethods (extensionType, name, true);
-                               if (res == null)
-                                       continue;
+               public void AddType (TypeSpec ts)
+               {
+                       if (types == null) {
+                               types = new Dictionary<string, IList<TypeSpec>> (64);
+                       }
 
-                               if (found == null)
-                                       found = res;
-                               else
-                                       found.AddRange (res);
+                       var name = ts.Name;
+                       IList<TypeSpec> existing;
+                       if (types.TryGetValue (name, out existing)) {
+                               TypeSpec better_type;
+                               TypeSpec found;
+                               if (existing.Count == 1) {
+                                       found = existing[0];
+                                       if (ts.Arity == found.Arity) {
+                                               better_type = IsImportedTypeOverride (ts, found);
+                                               if (better_type == found)
+                                                       return;
+
+                                               if (better_type != null) {
+                                                       existing [0] = better_type;
+                                                       return;
+                                               }
+                                       }
+
+                                       existing = new List<TypeSpec> ();
+                                       existing.Add (found);
+                                       types[name] = existing;
+                               } else {
+                                       for (int i = 0; i < existing.Count; ++i) {
+                                               found = existing[i];
+                                               if (ts.Arity != found.Arity)
+                                                       continue;
+
+                                               better_type = IsImportedTypeOverride (ts, found);
+                                               if (better_type == found)
+                                                       return;
+
+                                               if (better_type != null) {
+                                                       existing.RemoveAt (i);
+                                                       --i;
+                                                       continue;
+                                               }
+                                       }
+                               }
+
+                               existing.Add (ts);
+                       } else {
+                               types.Add (name, new TypeSpec[] { ts });
                        }
+               }
 
-                       return found;
+               //
+               // We import any types but in the situation there are same types
+               // but one has better visibility (either public or internal with friend)
+               // the less visible type is removed from the namespace cache
+               //
+               public static TypeSpec IsImportedTypeOverride (TypeSpec ts, TypeSpec found)
+               {
+                       var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ts.MemberDefinition.Assembly);
+                       var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, found.MemberDefinition.Assembly);
+
+                       if (ts_accessible && !found_accessible)
+                               return ts;
+
+                       // found is better always better for accessible or inaccessible ts
+                       if (!ts_accessible)
+                               return found;
+
+                       return null;
                }
 
-               public void AddDeclSpace (string name, DeclSpace ds)
+               public void RemoveDeclSpace (string name)
                {
-                       if (declspaces == null)
-                               declspaces = new HybridDictionary ();
-                       declspaces.Add (name, ds);
+                       types.Remove (name);
                }
 
-               /// <summary>
-               ///   The qualified name of the current namespace
-               /// </summary>
-               public string Name {
-                       get { return fullname; }
+               public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+               {
+                       var found = types [ts.Name];
+                       cached_types.Remove (ts.Name);
+                       if (found.Count == 1) {
+                               types[ts.Name][0] = pts;
+                       } else {
+                               throw new NotImplementedException ();
+                       }
                }
 
-               /// <summary>
-               ///   The parent of this namespace, used by the parser to "Pop"
-               ///   the current namespace declaration
-               /// </summary>
-               public Namespace Parent {
-                       get { return parent; }
+               public void VerifyClsCompliance ()
+               {
+                       if (types == null || cls_checked)
+                               return;
+
+                       cls_checked = true;
+
+                       // TODO: This is quite ugly way to check for CLS compliance at namespace level
+
+                       var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
+                       foreach (var tgroup in types.Values) {
+                               foreach (var tm in tgroup) {
+                                       if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
+                                               continue;
+
+                                       List<TypeSpec> found;
+                                       if (!locase_types.TryGetValue (tm.Name, out found)) {
+                                               found = new List<TypeSpec> ();
+                                               locase_types.Add (tm.Name, found);
+                                       }
+
+                                       found.Add (tm);
+                               }
+                       }
+
+                       foreach (var locase in locase_types.Values) {
+                               if (locase.Count < 2)
+                                       continue;
+
+                               bool all_same = true;
+                               foreach (var notcompliant in locase) {
+                                       all_same = notcompliant.Name == locase[0].Name;
+                                       if (!all_same)
+                                               break;
+                               }
+
+                               if (all_same)
+                                       continue;
+
+                               TypeContainer compiled = null;
+                               foreach (var notcompliant in locase) {
+                                       if (!notcompliant.MemberDefinition.IsImported) {
+                                               if (compiled != null)
+                                                       compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
+
+                                               compiled = notcompliant.MemberDefinition as TypeContainer;
+                                       } else {
+                                               compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
+                                       }
+                               }
+
+                               compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
+                                       "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
+                       }
                }
        }
 
        //
        // Namespace container as created by the parser
        //
-       public class NamespaceEntry : IResolveContext {
+       public class NamespaceEntry : IMemberContext {
 
-               class UsingEntry {
+               public class UsingEntry {
                        readonly MemberName name;
                        Namespace resolved;
                        
@@ -586,7 +710,7 @@ namespace Mono.CSharp {
                                get { return GetSignatureForError (); }
                        }
 
-                       public Namespace Resolve (IResolveContext rc)
+                       public Namespace Resolve (IMemberContext rc)
                        {
                                if (resolved != null)
                                        return resolved;
@@ -597,16 +721,21 @@ namespace Mono.CSharp {
 
                                resolved = fne as Namespace;
                                if (resolved == null) {
-                                       Report.SymbolRelatedToPreviousError (fne.Type);
-                                       Report.Error (138, Location,
+                                       rc.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
+                                       rc.Compiler.Report.Error (138, Location,
                                                "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
                                                GetSignatureForError ());
                                }
                                return resolved;
                        }
+
+                       public override string ToString ()
+                       {
+                               return Name;
+                       }
                }
 
-               class UsingAliasEntry {
+               public class UsingAliasEntry {
                        public readonly string Alias;
                        public Location Location;
 
@@ -616,21 +745,27 @@ namespace Mono.CSharp {
                                this.Location = loc;
                        }
 
-                       public virtual FullNamedExpression Resolve (IResolveContext rc)
+                       public virtual FullNamedExpression Resolve (IMemberContext rc)
                        {
-                               FullNamedExpression fne = RootNamespace.GetRootNamespace (Alias);
+                               FullNamedExpression fne = GlobalRootNamespace.Instance.GetRootNamespace (Alias);
                                if (fne == null) {
-                                       Report.Error (430, Location,
+                                       rc.Compiler.Report.Error (430, Location,
                                                "The extern alias `{0}' was not specified in -reference option",
                                                Alias);
                                }
 
                                return fne;
                        }
+
+                       public override string ToString ()
+                       {
+                               return Alias;
+                       }
+                       
                }
 
                class LocalUsingAliasEntry : UsingAliasEntry {
-                       Expression resolved;
+                       FullNamedExpression resolved;
                        MemberName value;
 
                        public LocalUsingAliasEntry (string alias, MemberName name, Location loc)
@@ -639,27 +774,29 @@ namespace Mono.CSharp {
                                this.value = name;
                        }
 
-                       public override FullNamedExpression Resolve (IResolveContext rc)
+                       public override FullNamedExpression Resolve (IMemberContext rc)
                        {
-                               if (resolved != null)
-                                       return (FullNamedExpression)resolved;
+                               if (resolved != null || value == null)
+                                       return resolved;
 
-                               resolved = value.GetTypeExpression ().ResolveAsTypeStep (rc, false);
-                               if (resolved == null)
+                               if (rc == null)
                                        return null;
 
-                               // FIXME: This is quite wrong, the accessibility is not global
-                               if (resolved.Type != null) {
-                                       TypeAttributes attr = resolved.Type.Attributes & TypeAttributes.VisibilityMask;
-                                       if (attr == TypeAttributes.NestedPrivate || attr == TypeAttributes.NestedFamily ||
-                                               ((attr == TypeAttributes.NestedFamORAssem || attr == TypeAttributes.NestedAssembly) && 
-                                               TypeManager.LookupDeclSpace (resolved.Type) == null)) {
-                                               Expression.ErrorIsInaccesible (resolved.Location, resolved.GetSignatureForError ());
-                                               return null;
-                                       }
+                               resolved = value.GetTypeExpression ().ResolveAsTypeStep (rc, false);
+                               if (resolved == null) {
+                                       value = null;
+                                       return null;
                                }
 
-                               return (FullNamedExpression)resolved;
+                               if (resolved is TypeExpr)
+                                       resolved = resolved.ResolveAsTypeTerminal (rc, false);
+
+                               return resolved;
+                       }
+
+                       public override string ToString ()
+                       {
+                               return String.Format ("{0} = {1}", Alias, value.GetSignatureForError ());
                        }
                }
 
@@ -669,9 +806,9 @@ namespace Mono.CSharp {
                int symfile_id;
 
                // Namespace using import block
-               ArrayList using_aliases;
-               ArrayList using_clauses;
-               public bool DeclarationFound = false;
+               List<UsingAliasEntry> using_aliases;
+               List<UsingEntry> using_clauses;
+               public bool DeclarationFound;
                // End
 
                public readonly bool IsImplicit;
@@ -679,11 +816,11 @@ namespace Mono.CSharp {
                static readonly Namespace [] empty_namespaces = new Namespace [0];
                Namespace [] namespace_using_table;
 
-               static ArrayList entries = new ArrayList ();
+               static List<NamespaceEntry> entries = new List<NamespaceEntry> ();
 
                public static void Reset ()
                {
-                       entries = new ArrayList ();
+                       entries = new List<NamespaceEntry> ();
                }
 
                public NamespaceEntry (NamespaceEntry parent, CompilationUnit file, string name)
@@ -695,9 +832,9 @@ namespace Mono.CSharp {
                        if (parent != null)
                                ns = parent.NS.GetNamespace (name, true);
                        else if (name != null)
-                               ns = RootNamespace.Global.GetNamespace (name, true);
+                               ns = GlobalRootNamespace.Instance.GetNamespace (name, true);
                        else
-                               ns = RootNamespace.Global;
+                               ns = GlobalRootNamespace.Instance;
                        SlaveDeclSpace = new RootDeclSpace (this);
                }
 
@@ -710,6 +847,67 @@ namespace Mono.CSharp {
                        this.SlaveDeclSpace = slave ? new RootDeclSpace (this) : null;
                }
 
+               //
+               // Populates the Namespace with some using declarations, used by the
+               // eval mode. 
+               //
+               public void Populate (List<UsingAliasEntry> source_using_aliases, List<UsingEntry> source_using_clauses)
+               {
+                       foreach (UsingAliasEntry uae in source_using_aliases){
+                               if (using_aliases == null)
+                                       using_aliases = new List<UsingAliasEntry> ();
+                               
+                               using_aliases.Add (uae);
+                       }
+
+                       foreach (UsingEntry ue in source_using_clauses){
+                               if (using_clauses == null)
+                                       using_clauses = new List<UsingEntry> ();
+                               
+                               using_clauses.Add (ue);
+                       }
+               }
+
+               //
+               // Extracts the using alises and using clauses into a couple of
+               // arrays that might already have the same information;  Used by the
+               // C# Eval mode.
+               //
+               public void Extract (List<UsingAliasEntry> out_using_aliases, List<UsingEntry> out_using_clauses)
+               {
+                       if (using_aliases != null){
+                               foreach (UsingAliasEntry uae in using_aliases){
+                                       bool replaced = false;
+                                       
+                                       for (int i = 0; i < out_using_aliases.Count; i++){
+                                               UsingAliasEntry out_uea = (UsingAliasEntry) out_using_aliases [i];
+                                               
+                                               if (out_uea.Alias == uae.Alias){
+                                                       out_using_aliases [i] = uae;
+                                                       replaced = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (!replaced)
+                                               out_using_aliases.Add (uae);
+                               }
+                       }
+
+                       if (using_clauses != null){
+                               foreach (UsingEntry ue in using_clauses){
+                                       bool found = false;
+                                       
+                                       foreach (UsingEntry out_ue in out_using_clauses)
+                                               if (out_ue.Name == ue.Name){
+                                                       found = true;
+                                                       break;
+                                               }
+                                       if (!found)
+                                               out_using_clauses.Add (ue);
+                               }
+                       }
+               }
+               
                //
                // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is
                // resolved as if the immediately containing namespace body has no using-directives.
@@ -758,16 +956,16 @@ namespace Mono.CSharp {
                public void AddUsing (MemberName name, Location loc)
                {
                        if (DeclarationFound){
-                               Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
+                               Compiler.Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
                        }
 
                        if (using_clauses == null) {
-                               using_clauses = new ArrayList ();
+                               using_clauses = new List<UsingEntry> ();
                        } else {
                                foreach (UsingEntry old_entry in using_clauses) {
                                        if (name.Equals (old_entry.MemberName)) {
-                                               Report.SymbolRelatedToPreviousError (old_entry.Location, old_entry.GetSignatureForError ());
-                                               Report.Warning (105, 3, loc, "The using directive for `{0}' appeared previously in this namespace", name.GetSignatureForError ());
+                                               Compiler.Report.SymbolRelatedToPreviousError (old_entry.Location, old_entry.GetSignatureForError ());
+                                               Compiler.Report.Warning (105, 3, loc, "The using directive for `{0}' appeared previously in this namespace", name.GetSignatureForError ());
                                                return;
                                        }
                                }
@@ -780,17 +978,17 @@ namespace Mono.CSharp {
                {
                        // TODO: This is parser bussines
                        if (DeclarationFound){
-                               Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
+                               Compiler.Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
                        }
 
                        if (RootContext.Version != LanguageVersion.ISO_1 && alias == "global")
-                               Report.Warning (440, 2, loc, "An alias named `global' will not be used when resolving 'global::';" +
+                               Compiler.Report.Warning (440, 2, loc, "An alias named `global' will not be used when resolving 'global::';" +
                                        " the global namespace will be used instead");
 
                        AddUsingAlias (new LocalUsingAliasEntry (alias, name, loc));
                }
 
-               public void AddUsingExternalAlias (string alias, Location loc)
+               public void AddUsingExternalAlias (string alias, Location loc, Report Report)
                {
                        // TODO: Do this in parser
                        bool not_first = using_clauses != null || DeclarationFound;
@@ -807,7 +1005,7 @@ namespace Mono.CSharp {
                                Report.Error (439, loc, "An extern alias declaration must precede all other elements");
 
                        if (alias == "global") {
-                               Error_GlobalNamespaceRedefined (loc);
+                               Error_GlobalNamespaceRedefined (loc, Report);
                                return;
                        }
 
@@ -817,12 +1015,12 @@ namespace Mono.CSharp {
                void AddUsingAlias (UsingAliasEntry uae)
                {
                        if (using_aliases == null) {
-                               using_aliases = new ArrayList ();
+                               using_aliases = new List<UsingAliasEntry> ();
                        } else {
                                foreach (UsingAliasEntry entry in using_aliases) {
                                        if (uae.Alias == entry.Alias) {
-                                               Report.SymbolRelatedToPreviousError (uae.Location, uae.Alias);
-                                               Report.Error (1537, entry.Location, "The using alias `{0}' appeared previously in this namespace",
+                                               Compiler.Report.SymbolRelatedToPreviousError (uae.Location, uae.Alias);
+                                               Compiler.Report.Error (1537, entry.Location, "The using alias `{0}' appeared previously in this namespace",
                                                        entry.Alias);
                                                return;
                                        }
@@ -836,17 +1034,11 @@ namespace Mono.CSharp {
                /// Does extension methods look up to find a method which matches name and extensionType.
                /// Search starts from this namespace and continues hierarchically up to top level.
                ///
-               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, ClassOrStruct currentClass, string name, Location loc)
+               public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
                {
-                       ArrayList candidates = null;
-                       if (currentClass != null) {
-                               candidates = ns.LookupExtensionMethod (extensionType, currentClass, name);
-                               if (candidates != null)
-                                       return new ExtensionMethodGroupExpr (candidates, this, extensionType, loc);
-                       }
-
+                       List<MethodSpec> candidates = null;
                        foreach (Namespace n in GetUsingTable ()) {
-                               ArrayList a = n.LookupExtensionMethod (extensionType, null, name);
+                               var a = n.LookupExtensionMethod (extensionType, null, name, arity);
                                if (a == null)
                                        continue;
 
@@ -856,8 +1048,9 @@ namespace Mono.CSharp {
                                        candidates.AddRange (a);
                        }
 
+                       scope = parent;
                        if (candidates != null)
-                               return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
+                               return candidates;
 
                        if (parent == null)
                                return null;
@@ -867,9 +1060,9 @@ namespace Mono.CSharp {
                        //
                        Namespace parent_ns = ns.Parent;
                        do {
-                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name);
+                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
                                if (candidates != null)
-                                       return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
+                                       return candidates;
 
                                parent_ns = parent_ns.Parent;
                        } while (parent_ns != null);
@@ -877,30 +1070,44 @@ namespace Mono.CSharp {
                        //
                        // Continue in parent scope
                        //
-                       return parent.LookupExtensionMethod (extensionType, currentClass, name, loc);
+                       return parent.LookupExtensionMethod (extensionType, name, arity, ref scope);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc, bool ignore_cs0104)
+               public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        // Precondition: Only simple names (no dots) will be looked up with this function.
                        FullNamedExpression resolved = null;
                        for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
-                               if ((resolved = curr_ns.Lookup (ds, name, loc, ignore_cs0104)) != null)
+                               if ((resolved = curr_ns.Lookup (name, arity, loc, ignore_cs0104)) != null)
                                        break;
                        }
+
                        return resolved;
                }
 
-               static void Error_AmbiguousTypeReference (Location loc, string name, FullNamedExpression t1, FullNamedExpression t2)
+               public IList<string> CompletionGetTypesStartingWith (string prefix)
                {
-                       Report.SymbolRelatedToPreviousError (t1.Type);
-                       Report.SymbolRelatedToPreviousError (t2.Type);
-                       Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
-                               name, t1.GetSignatureForError (), t2.GetSignatureForError ());
-               }
+                       IEnumerable<string> all = Enumerable.Empty<string> ();
+                       
+                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
+                               foreach (Namespace using_ns in GetUsingTable ()){
+                                       if (prefix.StartsWith (using_ns.Name)){
+                                               int ld = prefix.LastIndexOf ('.');
+                                               if (ld != -1){
+                                                       string rest = prefix.Substring (ld+1);
+
+                                                       all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
+                                               }
+                                       }
+                                       all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
+                               }
+                       }
 
+                       return all.Distinct ().ToList ();
+               }
+               
                // Looks-up a alias named @name in this and surrounding namespace declarations
-               public FullNamedExpression LookupAlias (string name)
+               public FullNamedExpression LookupNamespaceAlias (string name)
                {
                        for (NamespaceEntry n = this; n != null; n = n.ImplicitParent) {
                                if (n.using_aliases == null)
@@ -915,25 +1122,42 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               private FullNamedExpression Lookup (DeclSpace ds, string name, Location loc, bool ignore_cs0104)
+               private FullNamedExpression Lookup (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        //
                        // Check whether it's in the namespace.
                        //
-                       FullNamedExpression fne = ns.Lookup (ds, name, loc);
-                       if (fne != null)
-                               return fne;
+                       FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
 
                        //
                        // Check aliases. 
                        //
-                       if (using_aliases != null) {
+                       if (using_aliases != null && arity == 0) {
                                foreach (UsingAliasEntry ue in using_aliases) {
-                                       if (ue.Alias == name)
+                                       if (ue.Alias == name) {
+                                               if (fne != null) {
+                                                       if (Doppelganger != null) {
+                                                               // TODO: Namespace has broken location
+                                                               //Report.SymbolRelatedToPreviousError (fne.Location, null);
+                                                               Compiler.Report.SymbolRelatedToPreviousError (ue.Location, null);
+                                                               Compiler.Report.Error (576, loc,
+                                                                       "Namespace `{0}' contains a definition with same name as alias `{1}'",
+                                                                       GetSignatureForError (), name);
+                                                       } else {
+                                                               return fne;
+                                                       }
+                                               }
+
                                                return ue.Resolve (Doppelganger);
+                                       }
                                }
                        }
 
+                       if (fne != null) {
+                               if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, fne.Type.Assembly)))
+                                       return fne;
+                       }
+
                        if (IsImplicit)
                                return null;
 
@@ -942,18 +1166,45 @@ namespace Mono.CSharp {
                        //
                        FullNamedExpression match = null;
                        foreach (Namespace using_ns in GetUsingTable ()) {
-                               match = using_ns.Lookup (ds, name, loc);
-                               if (match == null || !(match is TypeExpr))
+                               // A using directive imports only types contained in the namespace, it
+                               // does not import any nested namespaces
+                               fne = using_ns.LookupType (Compiler, name, arity, false, loc);
+                               if (fne == null)
                                        continue;
-                               if (fne != null) {
-                                       if (!ignore_cs0104)
-                                               Error_AmbiguousTypeReference (loc, name, fne, match);
-                                       return null;
+
+                               if (match == null) {
+                                       match = fne;
+                                       continue;
+                               }
+
+                               // Prefer types over namespaces
+                               var texpr_fne = fne as TypeExpr;
+                               var texpr_match = match as TypeExpr;
+                               if (texpr_fne != null && texpr_match == null) {
+                                       match = fne;
+                                       continue;
+                               } else if (texpr_fne == null) {
+                                       continue;
+                               }
+
+                               if (ignore_cs0104)
+                                       return match;
+
+                               // It can be top level accessibility only
+                               var better = Namespace.IsImportedTypeOverride (texpr_match.Type, texpr_fne.Type);
+                               if (better == null) {
+                                       Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
+                                       Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
+                                       Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
+                                               name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
+                                       return match;
                                }
-                               fne = match;
+
+                               if (better == texpr_fne.Type)
+                                       match = texpr_fne;
                        }
 
-                       return fne;
+                       return match;
                }
 
                Namespace [] GetUsingTable ()
@@ -966,7 +1217,7 @@ namespace Mono.CSharp {
                                return namespace_using_table;
                        }
 
-                       ArrayList list = new ArrayList (using_clauses.Count);
+                       var list = new List<Namespace> (using_clauses.Count);
 
                        foreach (UsingEntry ue in using_clauses) {
                                Namespace using_ns = ue.Resolve (Doppelganger);
@@ -976,7 +1227,7 @@ namespace Mono.CSharp {
                                list.Add (using_ns);
                        }
 
-                       namespace_using_table = (Namespace[])list.ToArray (typeof (Namespace));
+                       namespace_using_table = list.ToArray ();
                        return namespace_using_table;
                }
 
@@ -991,7 +1242,7 @@ namespace Mono.CSharp {
                                        if (using_clauses != null) {
                                                using_list = new string [using_clauses.Count];
                                                for (int i = 0; i < using_clauses.Count; i++)
-                                                       using_list [i] = ((UsingEntry) using_clauses [i]).MemberName.GetTypeName ();
+                                                       using_list [i] = ((UsingEntry) using_clauses [i]).MemberName.GetName ();
                                        }
 
                                        symfile_id = SymbolWriter.DefineNamespace (ns.Name, file.CompileUnitEntry, using_list, parent_id);
@@ -1010,12 +1261,12 @@ namespace Mono.CSharp {
                        Console.WriteLine ("    Try using -pkg:" + s);
                }
 
-               public static void Error_GlobalNamespaceRedefined (Location loc)
+               public static void Error_GlobalNamespaceRedefined (Location loc, Report Report)
                {
                        Report.Error (1681, loc, "You cannot redefine the global extern alias");
                }
 
-               public static void Error_NamespaceNotFound (Location loc, string name)
+               public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
                {
                        Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
                                name);
@@ -1080,22 +1331,39 @@ namespace Mono.CSharp {
                        return ns.ToString ();
                }
 
-               #region IResolveContext Members
+               #region IMemberContext Members
+
+               public CompilerContext Compiler {
+                       get { return RootContext.ToplevelTypes.Compiler; }
+               }
+
+               public TypeSpec CurrentType {
+                       get { return SlaveDeclSpace.CurrentType; }
+               }
+
+               public MemberCore CurrentMemberDefinition {
+                       get { return SlaveDeclSpace.CurrentMemberDefinition; }
+               }
+
+               public TypeParameter[] CurrentTypeParameters {
+                       get { return SlaveDeclSpace.CurrentTypeParameters; }
+               }
 
-               public DeclSpace DeclContainer {
-                       get { return SlaveDeclSpace; }
+               // FIXME: It's false for expression types
+               public bool HasUnresolvedConstraints {
+                       get { return true; }
                }
 
-               public bool IsInObsoleteScope {
-                       get { return SlaveDeclSpace.IsInObsoleteScope; }
+               public bool IsObsolete {
+                       get { return SlaveDeclSpace.IsObsolete; }
                }
 
-               public bool IsInUnsafeScope {
-                       get { return SlaveDeclSpace.IsInUnsafeScope; }
+               public bool IsUnsafe {
+                       get { return SlaveDeclSpace.IsUnsafe; }
                }
 
-               public DeclSpace GenericDeclContainer {
-                       get { return SlaveDeclSpace; }
+               public bool IsStatic {
+                       get { return SlaveDeclSpace.IsStatic; }
                }
 
                #endregion