Type.cs :  » Aspect-Oriented-Frameworks » Runtime-Assembly-Instrumentation-Library » rail » Reflect » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Aspect Oriented Frameworks » Runtime Assembly Instrumentation Library 
Runtime Assembly Instrumentation Library » rail » Reflect » Type.cs
/*
  The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); 
  you may not use this file except in compliance with the License. You may obtain a copy of the License at 
  http://www.mozilla.org/MPL/ 
  Software distributed under the License is distributed on an "AS IS" basis, 
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language 
  governing rights and limitations under the License. 

  The Original Code is RAIL(Runtime Assembly Instrumentation Library) Alpha Version.
  The Initial Developer of the Original Code is University of Coimbra,
  Computer Science Department, Dependable Systems Group. Copyright (C) University of Coimbra. 
  All Rights Reserved.  
*/
using System;
using System.Reflection;
using Mono.PEToolkit;
using Mono.PEToolkit.Metadata;
using System.Collections;
using Rail.MSIL;
using Rail.Transformation;

namespace Rail.Reflect{

  /// <summary>
  /// 
  /// </summary>
  public abstract class RType : RMember 
  {    
    #region Fields
    /// <summary>
    /// 
    /// </summary>
    protected TypeAttributes attributes;
    /// <summary>
    /// 
    /// </summary>
    protected RAssembly assembly;
    /// <summary>
    /// 
    /// </summary>
    protected RModule module;
    /// <summary>
    /// 
    /// </summary>
    protected RType baseType;
    /// <summary>
    /// 
    /// </summary>
    protected RType elementType;
    /// <summary>
    /// 
    /// </summary>
    protected string nameSpace;
    /// <summary>
    /// 
    /// </summary>
    protected int arrayRank;
    /// <summary>
    /// 
    /// </summary>
    protected ARRAY.ArrayShape arrayShape;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList interfaces;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList methods;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList constructors;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList properties;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList events;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList fields;
    /// <summary>
    /// 
    /// </summary>
    protected System.Reflection.Emit.PackingSize packingSize;
    /// <summary>
    /// 
    /// </summary>
    protected int typeSize;

    #endregion


    #region Type information. Assembly, module, name   
    /// <summary>
    /// 
    /// </summary>
    public virtual System.Reflection.Emit.PackingSize PackingSize
    {
      get
      {
        return this.packingSize;
      }
      set
      {
        throw new NotSupportedException();
      }
    }
    
    /// <summary>
    /// 
    /// </summary>
    public virtual int TypeSize
    {
      get
      {
        return this.typeSize;
      }
      set
      {
        throw new NotSupportedException();
      }
    }
    
    /// <summary>
    /// Gets the attributes of this type
    /// </summary>
    public virtual TypeAttributes Attributes 
    {
      get 
      {
        // KIRK: We're not allowed to use reserved bits
        return this.attributes ^ (this.attributes & TypeAttributes.ReservedMask);
      }
      set 
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// Gets the assembly where this type is contained.
    /// </summary>
    public virtual RAssembly Assembly 
    {
      get 
      {
        return this.assembly;
      }
      set
      {
        throw new NotSupportedException();
      }
    }
    
    /// <summary>
    /// Gets the module where this type is contained.
    /// </summary>
    public virtual RModule Module 
    {
      get 
      {
        return this.module;
      }
      set
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// Gets the full name of the type. The full name is composed of the
    /// namespace"."type name
    /// TODO: What to do if it is a nested type? - SOLVED
    /// </summary>
    public virtual String FullName 
    {
      get 
      {
        string fullName = "";
        if (this.declaringType==null) 
          if (this.nameSpace!=null)
            if (this.nameSpace.Length>0)
              fullName = this.nameSpace + "." + this.name;
            else
              fullName = this.name;
          else 
            fullName = this.name;        
        else
          fullName = this.declaringType.NameWithNameSpace + "+" + this.name;
        if (this.assembly!=null)
          fullName += ", " + this.assembly.Name.FullName;
        if (fullName.Length>2 && fullName.IndexOf(", ")>0)
          if (fullName.LastIndexOf("[]")==fullName.Length-2)
            fullName = fullName.Substring(0,fullName.Length-2);
        return fullName;
      }
      set 
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// 
    /// </summary>
    internal virtual String NameWithNameSpace 
    {
      get 
      {
        string fullName = "";
        if (this.declaringType==null) 
          if (this.nameSpace!=null)
            if (this.nameSpace.Length>0)
              fullName = this.nameSpace + "." + this.name;
            else
              fullName = this.name;
          else 
            fullName = this.name;        
        else
          fullName = this.declaringType.NameWithNameSpace + "+" + this.name;
        if (fullName.IndexOf(", ")>0)
          fullName = fullName.Substring(0,fullName.IndexOf(", "));
        return fullName;
      }
      set 
      {
        throw new NotSupportedException();
      }
    }
    /// <summary>
    /// Gets or sets the base class of this type.
    /// </summary>
    public virtual RType BaseType 
    {
      get 
      {
        return this.baseType;
      }
      set 
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// When overridden in a derived class, returns the RType of the object 
    /// encompassed or referred to by the current array.
    /// </summary>
    /// <exception cref="NotSupportedException">This type is not an array.</exception>
    public virtual RType ElementType 
    {
      get
      {
        return this.elementType;
      }
      set
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// The namespace of the type, should be null if it is nested
    /// </summary>
    public virtual string NameSpace
    {
      get
      {
        return this.nameSpace;
      }
      set
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// If this object represents an array, this method returns the number of
    /// dimensions. 
    /// </summary>
    /// <exception cref="NotSupportedException"> This type is not an array. </exception>
    public virtual int GetArrayRank() 
    {
      return this.arrayRank;
    }

    /// <summary>
    /// If this object represents an array this property gets or sets it's shape
    /// </summary>
    /// <exception cref="NotSupportedException"> This type is not an array. </exception>
    public virtual ARRAY.ArrayShape RArrayShape
    {
      get
      {
        return this.arrayShape;
      }
      set
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// Whether this <code>RType</code> instance represents an array.
    /// </summary>    
    public virtual bool IsArray 
    {
      get 
      {
        if (this.arrayShape!=null && this.elementType!=null)
          return true;
        else 
          return false;
      }
    }
    /// <summary>
    /// Whether this <code>RType</code> instance is a nested type.
    /// </summary>    
    public virtual bool IsNested
    {
      get 
      {
        //TODO: Check this verification is suficient
        TypeAttributes tNested = TypeAttributes.NestedAssembly |
          TypeAttributes.NestedFamANDAssem |
          TypeAttributes.NestedFamily |
          TypeAttributes.NestedFamORAssem |
          TypeAttributes.NestedPrivate |
          TypeAttributes.NestedPublic;
        if ((this.attributes & tNested) != 0)
          return true;
        else 
          return false;
      }
    }

    /// <summary>
    /// Whether this <code>RType</code> instance represents a primitive type.
    /// </summary>
    /// <remarks>All primitive types are value types, but not all value 
    /// types are primitives -- e.g. user defined value types are not primitives.
    /// </remarks>    
    public virtual bool IsPrimitive {
      get {
        // KIRK: Preliminary support for primitives
        switch (this.NameWithNameSpace) {
          case "System.SByte":
          case "System.Byte":
          case "System.Int16":
          case "System.UInt16":
          case "System.Int32":
          case "System.UInt32":
          case "System.Int64":
          case "System.UInt64":
          case "System.Char":
          case "System.Single":
          case "System.Double":
          case "System.Boolean":
          case "System.Decimal":
            return true;
        }
        return false;
      }
    }

    /// <summary>
    /// Whether this <code>RType</code> instance represents a Value type.
    /// </summary>    
    /// <remarks>
    /// A type is a value type only if it derives from <code>System.ValueType</code>
    /// </remarks>
    public virtual bool IsValueType 
    {
      get 
      {
        // First, check weather this is directly in the valueType hierachy 
        RType type = this;
        while (type != null)
          if (type.NameWithNameSpace == "System.ValueType")
            return true;
          else if (type.baseType!=null)
            type = type.baseType;
          else if (type is RTypeRef && ((RTypeRef)type).reflectionType.BaseType!=null)
          {
            Type tBase = ((RTypeRef)type).reflectionType.BaseType;
            type = new RTypeRef(((RTypeRef)type).reflectionType.BaseType.Name,
              ((RTypeRef)type).reflectionType.BaseType.Namespace,
              null);
            ((RTypeRef)type).reflectionType = tBase; 
          }
          else type = null;
        RType [] intefcs = GetInterfaces(); 
        for (int i = 0; i < intefcs.Length ; i++) 
          if (intefcs[i].IsValueType)
            return true;
        return false;
      }
    }

    // Non essential functionality.
    //    /// <summary>
    //    /// Determines whether the current type derives from the specified type.
    //    /// </summary>
    //    /// <param name="t"></param>
    //    /// <returns>true if the Type represented by the c parameter and the current 
    //    /// Type represent classes, and the class represented by the current Type 
    //    /// derives from the class represented by c; otherwise, false. This method 
    //    /// also returns false if c and the current Type represent the same class.
    //    /// </returns>
    //    public bool IsSubclassOf(RType t) {
    
    //    }
    #endregion

    #region Implemented interfaces
    /// <summary>
    /// Returns all interfaces implemented by this type.
    /// </summary>    
    /// <returns>An array with the interfaces implemented by this type.</returns>
    public virtual RType[] GetInterfaces() 
    {
      if (this.interfaces==null) return new RType[0];
      if (this.interfaces.Count==0) return new RType[0];
      IEnumerator ienum = this.interfaces.GetEnumerator();
      RType [] rts = new RType[this.interfaces.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        rts[i] = (RType)ienum.Current;
        i++;
      }
      return rts;
    }

    /// <summary>
    /// Searches for the interface with the given name.
    /// </summary>
    /// <param name="name">The fully qualified name of the interface to search for.</param>
    /// <returns>The interface if it is found, null otherwise.</returns>
    public virtual RType GetInterface(String name) 
    {
      if (this.interfaces==null) return null;
      if (this.interfaces.Count==0) return null;
      IEnumerator ienum = this.interfaces.GetEnumerator();
      RType rt = null;
      while (ienum.MoveNext())
      {
        rt = (RType)ienum.Current;
        if (rt.FullName.Equals(name)) return rt;
      }
      return null;
    }
    #endregion
    
    #region Methods management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="returnValue"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public virtual RMethod GetMethod(String name, RType returnValue, RParameter[] args) 
    {
      if (this.methods == null) return null;
      if (this.methods.Count==0) return null;
      IEnumerator ienum = this.methods.GetEnumerator();
      RMethod rm = null;
      while (ienum.MoveNext())
      {
        rm = (RMethod)ienum.Current;
        if (rm.Name.Equals(name))
          //TODO: Does the method equals needs to be implemented in RType
          if (rm.ReturnType.ReturnType.FullName.Equals(returnValue.FullName))
          {
            RParameter [] rpms = rm.GetParameters();
            bool goodReturn = false;
            if (args==null && rpms==null)
              return rm;
            if (rpms!=null)
              if (args == null && rpms.Length==0)
                return rm;
            if (args!=null)
              if (args.Length==0 && rpms==null)
                return rm;
            if (args.Length == 0 && rpms.Length==0)
              return rm;
            if (args.Length == rpms.Length)
              for (int i = 0; i < rpms.Length;i++)
              {
                if (!(args[i].ParameterType.NameWithNameSpace == rpms[i].ParameterType.NameWithNameSpace))
                {
                  goodReturn = false;
                  break;
                }else
                  goodReturn = true;
              }
            if (goodReturn)
              return rm;
          }
      }
      return null;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual RMethod[] GetMethods() 
    {
      if (this.methods==null) return new RMethod[0];
      if (this.methods.Count==0) return new RMethod[0];
      RMethod [] rms = new RMethod[this.methods.Count];
      for (int i = 0; i< this.methods.Count;i++)
      {
        rms[i] = (RMethod)this.methods[i];
      }
      return rms;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <returns></returns>
    public virtual RMethod[] GetMethods(BindingFlags bf) 
    {
      if (this.methods==null) return new RMethod[0];
      if (this.methods.Count==0) return new RMethod[0];
      IEnumerator ienum = this.methods.GetEnumerator();
      RMethod [] rms = new RMethod[this.methods.Count];
      RMethod temp = null;
      int i = 0;
      while (ienum.MoveNext())
      {
        temp = (RMethod)ienum.Current;
        if ((temp.BindingFlags & bf)==bf)
        {
          rms[i] = temp;
          i++;
        }
      }
      if (i<this.methods.Count)
      {
        RMethod [] tempRms = new RMethod[i];
        for (int j = 0; j < i; j++)
          tempRms[j] = rms[j];
        rms = tempRms;
      }
      return rms;
    }
    #endregion

    #region Constructors
    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public virtual RConstructor GetConstructor(RParameter[] args) 
    {
      if (this.constructors == null) 
        return null;
      if (this.constructors.Count==0) 
        return null;
      RConstructor rc = null;
      RParameter [] paramS = null;
      for (int i = 0; i < this.constructors.Count; i++)
      {
        rc = (RConstructor)this.constructors[i];
        if (args==null && rc.ParametersCount == 0 && rc!=null)
          return rc;
        if (args!=null)
        {
          if (args.Length == 0 && rc.ParametersCount == 0 && rc!=null)
            return rc;
          if (args.Length == rc.ParametersCount)
          {
            bool okToReturn = true;
            paramS = rc.GetParameters();
            if (paramS!=null)
              for (int j=0;j<paramS.Length;j++)
              {
                if (args[j].ParameterType.FullName != paramS[j].ParameterType.FullName)
                  okToReturn = false;
              }
            if (okToReturn && rc!=null)
              return rc;
          }
        }

      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
//    public virtual RConstructor GetConstructor(RType[] args) 
//    {
//      if (this.constructors == null) return null;
//      if (this.constructors.Count==0) return null;
//      RConstructor rc = null;
//      for (int i = 0; i < this.constructors.Count; i++)
//      {
//        rc = (RConstructor)this.constructors[i];
//        if (args==null && rc.ParametersCount == 0)
//          return rc;
//        if (args!=null)
//        {
//          if (args.Length == 0 && rc.ParametersCount == 0)
//            return rc;
//          if (args.Length == rc.ParametersCount)
//          {
//            bool okToReturn = true;
//            RParameter [] paramS = rc.GetParameters();
//            if (paramS!=null)
//              for (int j=0;j<paramS.Length;j++)
//              {
//                if (args[j]!=null)
//                {
//                  if (args[j].NameWithNameSpace != paramS[j].ParameterType.NameWithNameSpace)
//                    okToReturn = false;
//                }
//                else if (paramS[j].ParameterType!=null)
//                  okToReturn = false;
//              }
//            if (okToReturn)
//              return rc;
//          }
//        }
//
//      }
//      return null;
//    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public virtual RConstructor GetConstructor(System.Reflection.BindingFlags bf, RParameter[] args) 
    {
      if (this.constructors == null) return null;
      if (this.constructors.Count==0) return null;
      RConstructor rc = null;
      for (int i = 0; i<this.constructors.Count;i++)
      {
        rc = (RConstructor)this.constructors[i];
        if ((rc.BindingFlags & bf)==bf)
        {
          RParameter [] paramss = rc.GetParameters();
          bool isMatch = true;
          int index = 0;
          if (paramss!=null &&
            args != null &&
            paramss.Length == args.Length)
          {
            while(index < paramss.Length)    
            {
              if (paramss[index].ParameterType.NameWithNameSpace!=
                args[index].ParameterType.NameWithNameSpace)
              {
                isMatch = false;
                break;
              }
              ++index;
            }
          }
          else if (paramss==null && args==null)
            return rc;
          if (isMatch)
            return rc;
        }
      }
      return null;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual RConstructor[] GetConstructors() 
    {
      if (this.constructors == null) return new RConstructor[0];
      if (this.constructors.Count==0) return new RConstructor[0];
      RConstructor [] rc = new RConstructor[this.constructors.Count];
      for (int i = 0; i < this.constructors.Count; i++)
      {
        rc[i] = (RConstructor)this.constructors[i];
      }
      return rc;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <returns></returns>
    public virtual RConstructor[] GetConstructors(BindingFlags bf) 
    {
      if (this.constructors==null) return new RConstructor[0];
      if (this.constructors.Count==0) return new RConstructor[0];
      IEnumerator ienum = this.constructors.GetEnumerator();
      RConstructor [] rms = new RConstructor[this.constructors.Count];
      RConstructor temp = null;
      int i = 0;
      while (ienum.MoveNext())
      {
        temp = (RConstructor)ienum.Current;
        if ((temp.BindingFlags & bf)==bf)
        {
          rms[i] = temp;
          i++;
        }
      }
      if (i<this.constructors.Count)
      {
        RConstructor [] tempRms = new RConstructor[i];
        for (int j = 0; j < i; j++)
          tempRms[j] = rms[j];
        rms = tempRms;
      }
      return rms;
    }
    #endregion
  
    #region Properties management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public virtual RProperty GetProperty(String name) 
    {
      if (this.properties == null) return null;
      if (this.properties.Count==0) return null;
      IEnumerator ienum = this.properties.GetEnumerator();
      RProperty rp = null;
      while (ienum.MoveNext())
      {
        rp = (RProperty)ienum.Current;
        if (rp.Name.Equals(name))
          return rp;
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual RProperty[] GetProperties() 
    {
      if (this.properties == null) return new RProperty[0];
      if (this.properties.Count==0) return new RProperty[0];
      IEnumerator ienum = this.properties.GetEnumerator();
      RProperty [] rps = new RProperty[this.properties.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        rps[i] = (RProperty)ienum.Current;
        i++;
      }
      return rps;
    }
    #endregion
    
    #region Events management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="eventName"></param>
    /// <returns></returns>
    public virtual REvent GetEvent(String eventName) 
    {
      if (this.events == null) return null;
      if (this.events.Count==0) return null;
      IEnumerator ienum = this.events.GetEnumerator();
      REvent re = null;
      while (ienum.MoveNext())
      {
        re = (REvent)ienum.Current;
        if (re.Name.Equals(eventName))
          return re;
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual REvent[] GetEvents() 
    {
      if (this.events == null) return new REvent[0];
      if (this.events.Count==0) return new REvent[0];
      IEnumerator ienum = this.events.GetEnumerator();
      REvent [] res = new REvent[this.events.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        res[i] = (REvent)ienum.Current;
        i++;
      }
      return res;
    }
    #endregion
      
    #region Fields management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public virtual RField GetField(String name) 
    {
      if (this.fields == null) return null;
      if (this.fields.Count==0) return null;
      IEnumerator ienum = this.fields.GetEnumerator();
      RField rf = null;
      while (ienum.MoveNext())
      {
        rf = (RField)ienum.Current;
        if (rf.Name.Equals(name))
          return rf;
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="bf"></param>
    /// <returns></returns>
    public virtual RField GetField(String name,BindingFlags bf) 
    {
      if (this.fields == null) return null;
      if (this.fields.Count==0) return null;
      IEnumerator ienum = this.fields.GetEnumerator();
      RField rf = null;
      while (ienum.MoveNext())
      {
        rf = (RField)ienum.Current;
        if (rf.Name.Equals(name))
          if ((rf.BindingFlags & bf)==bf)
            return rf;
      }
      return null;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual RField[] GetFields() 
    {
      if (this.fields == null) return new RField[0];
      if (this.fields.Count==0) return new RField[0];
      IEnumerator ienum = this.fields.GetEnumerator();
      RField [] rfs = new RField[this.fields.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        rfs[i] = (RField)ienum.Current;
        i++;
      }
      return rfs;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <returns></returns>
    public virtual RField[] GetFields(BindingFlags bf) 
    {
      if (this.fields == null) return new RField[0];
      if (this.fields.Count==0) return new RField[0];
      IEnumerator ienum = this.fields.GetEnumerator();
      RField [] rfs = new RField[this.fields.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        if ((((RField)ienum.Current).BindingFlags & bf)==bf)
        {
          rfs[i] = (RField)ienum.Current;
          i++;
        }
      }
      if (i<this.fields.Count)
      {
        RField [] tempRfs = new RField[i];
        for (int j = 0; j < i; j++)
          tempRfs[j] = rfs[j];
        rfs = tempRfs;
      }
      return rfs;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public virtual int FieldsCount
    {
      get 
      {
        if (this.fields == null) return 0;
        return this.fields.Count;
      }
    }
    #endregion  

    #region RType utils
    /// <summary>
    /// Get the RType associated with the SigType in the signature
    /// </summary>
    /// <param name="s">The sigtype</param>
    /// <returns>The RType associated</returns>
    internal static RType GetRType(SigType s, RAssemblyDef assemblyDef)
    {
      RType sigRType = null;
      switch (s.ElementType) 
      {

        case Mono.PEToolkit.Metadata.ElementType.ValueType: 
          ValueType v = s as ValueType;
          if (v==null)
            throw new NullReferenceException("SigType was not a ValueType");
          switch(v.TypeTable)
          {
            case TokenType.TypeDef : //TypeDef
              sigRType = assemblyDef.RModuleDef.GetTypeByToken(v.Index);
              break;
            case TokenType.TypeRef : //TypeRef
              sigRType = assemblyDef.GetTypeByToken(v.Index);
              break;
            case TokenType.TypeSpec : //TypeSpec
              //TODO : TypeSpec ref in FieldSig
              throw new NotImplementedException("TypeSpec FieldSig type");
              
          }
          break;
        case Mono.PEToolkit.Metadata.ElementType.Class: 
          CLASS v2 = s as CLASS;
          if (v2==null)
            throw new NullReferenceException("SigType was not a CLASS");
          switch(v2.TypeTable)
          {
            case TokenType.TypeDef : //TypeDef
              sigRType = assemblyDef.RModuleDef.GetTypeByToken(v2.Index);
              break;
            case TokenType.TypeRef : //TypeRef
              sigRType = assemblyDef.GetTypeByToken(v2.Index);
              break;
            case TokenType.TypeSpec : //TypeSpec
              //TODO : TypeSpec ref in FieldSig
              throw new NotImplementedException("TypeSpec FieldSig type");
          }
          break;
        case Mono.PEToolkit.Metadata.ElementType.Ptr: 
          PTR v3 = s as PTR;
          if (v3==null)
            throw new NullReferenceException("SigType was not a PTR");
          // KIRK: If PTR, create a type*
          sigRType = RType.GetRType(v3.ptrType,assemblyDef);
          if (sigRType is RTypeRef) {
            RTypeRef temp = new RTypeRef(sigRType.Name + "*", sigRType.NameSpace, null);  
            temp.Assembly = sigRType.Assembly;
            sigRType = temp;
          } else {
            throw new NotImplementedException("Didn't think of this case!");
          }
          break;
        case Mono.PEToolkit.Metadata.ElementType.FnPtr: 
          throw new NotImplementedException("ELEMENT_TYPE_FNPTR");
        case Mono.PEToolkit.Metadata.ElementType.Array: 
          ARRAY v4 = s as ARRAY;
          if (v4==null)
            throw new NullReferenceException("SigType was not a ARRAY");
          
          RType elementRType = RType.GetRType(v4.Type,assemblyDef);
          string ArrayTypeName = elementRType.NameWithNameSpace;
          ArrayTypeName += "[";
          for (int i = 0; i < v4.arrayShape.Rank; i++)
          {
            if (i!=v4.arrayShape.Rank-1)
              ArrayTypeName += ",";
          }
          ArrayTypeName += "]";
          RType arr = null;
          if (elementRType is RTypeDef)
          {
            arr = new RTypeDef(ArrayTypeName);
            arr.ElementType = elementRType;
            arr.RArrayShape = v4.arrayShape;
          }
          else if (elementRType is RTypeRef)
          {
            Type t = Type.GetType(ArrayTypeName);
            if (t==null)
            {
              //TODO: this is only a workaround
              RAssembly a = elementRType.Assembly;
              Assembly asm = System.Reflection.Assembly.LoadWithPartialName(a.Name.Name);
              if (asm!=null)
                t = asm.GetType(ArrayTypeName);
            }
            arr = assemblyDef.GetRTypeRef(t);
          }
          sigRType = arr;
          break;
        case Mono.PEToolkit.Metadata.ElementType.SzArray: 
          SZARRAY v5 = s as SZARRAY;
          if (v5==null)
            throw new NullReferenceException("SigType was not a SZARRAY");
          RType elementRType2 = RType.GetRType(v5.Type,assemblyDef);
          string arrayTypeName  = elementRType2.NameWithNameSpace + "[]";
          RType arr2 = null;
          if (elementRType2 is RTypeDef)
          {
            arr2 = new RTypeDef(arrayTypeName);
            arr2.ElementType = elementRType2;
            //TODO: Check this please
            arr2.RArrayShape = new ARRAY.ArrayShape();
            arr2.RArrayShape.Rank = 1;
          }
          else if (elementRType2 is RTypeRef)
          {
            arr2 = assemblyDef.GetRTypeRef(arrayTypeName);
            if (arr2!=null)
            {
              sigRType = arr2;
              break;
            }
            Type t = Type.GetType(arrayTypeName);
            if (t==null)
            {
              //TODO: this is only a workaround
              RAssembly a = elementRType2.Assembly;
              Assembly asm = System.Reflection.Assembly.LoadWithPartialName(a.Name.Name);
              if (asm!=null)
                t = asm.GetType(arrayTypeName);
            }
            arr2 = assemblyDef.GetRTypeRef(t);
          }
          sigRType = arr2;
          break;
        case Mono.PEToolkit.Metadata.ElementType.String: 
          sigRType = assemblyDef.GetRTypeRef(typeof(System.String));
          break;
        case Mono.PEToolkit.Metadata.ElementType.Object:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Object));
          break;
        case Mono.PEToolkit.Metadata.ElementType.Void :
          sigRType = assemblyDef.GetRTypeRef(typeof(void));
          break;
        case Mono.PEToolkit.Metadata.ElementType.Boolean:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Boolean));
          break;
        case Mono.PEToolkit.Metadata.ElementType.Char: 
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Char));
          break;
        case Mono.PEToolkit.Metadata.ElementType.I1: 
          sigRType = assemblyDef.GetRTypeRef(typeof(System.SByte));
          break;
        case Mono.PEToolkit.Metadata.ElementType.U1:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Byte));
          break;
        case Mono.PEToolkit.Metadata.ElementType.I2:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Int16));
          break;
        case Mono.PEToolkit.Metadata.ElementType.U2:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.UInt16));
          break;
        case Mono.PEToolkit.Metadata.ElementType.I4: 
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Int32));
          break;
        case Mono.PEToolkit.Metadata.ElementType.U4:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.UInt32));
          break;
        case Mono.PEToolkit.Metadata.ElementType.I8: 
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Int64));
          break;
        case Mono.PEToolkit.Metadata.ElementType.U8:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.UInt64));
          break;
        case Mono.PEToolkit.Metadata.ElementType.R4:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Single));
          break;
        case Mono.PEToolkit.Metadata.ElementType.R8:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.Double));
          break;
        case Mono.PEToolkit.Metadata.ElementType.I:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.IntPtr));
          break;
        case Mono.PEToolkit.Metadata.ElementType.U:
          sigRType = assemblyDef.GetRTypeRef(typeof(System.UIntPtr));
          break;
        case Mono.PEToolkit.Metadata.ElementType.End:
        default:
          throw new Exception("ERROR in SigType to RType");
          
      }
      return sigRType;
    }


    #endregion



  }

  /// <summary>
  /// 
  /// </summary>
  public sealed class RTypeRef : RType 
  {
    #region fields
    /// <summary>
    /// Holds the original token
    /// </summary>
    private int resolutionScope;
    /// <summary>
    /// 
    /// </summary>
    private RAssemblyDef rad;
    /// <summary>
    /// 
    /// </summary>
    internal Type reflectionType;
    #endregion

    #region properties

    internal Type ReflectionType
    {
      get
      {
        SetReflectionType();
        return this.reflectionType;
      }
      set
      {
        this.reflectionType = value;
      }
    }
    /// <summary>
    /// 
    /// </summary>
    internal int ResolutionScope
    {
      get
      {  
        return this.resolutionScope;
      }
      set
      {
        this.resolutionScope = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override RAssembly Assembly 
    {
      get 
      {
        if (this.assembly!=null)
          return this.assembly;
        RAssemblyName [] rans = null;
        if (this.rad!=null)
          rans = this.rad.GetReferencedAssemblies();
        if (rans!=null && this.ResolutionScope > 0)
        {      
          this.assembly = new RAssemblyRef(rans[(this.ResolutionScope>>2)-1]);
          return this.assembly;
        }
        return null;
      }

      #region SOLO-HOT-FIX: ValueTypes and Array resolve
      set
      {
        base.assembly = value;
      }
      #endregion SOLO-HOT-FIX: ValueTypes and Array resolve

    }

    /// <summary>
    /// 
    /// </summary>
    internal new ARRAY.ArrayShape RArrayShape
    {
      set
      {
        this.arrayShape = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override String FullName 
    {
      get 
      {
        string fullName = "";
        if (this.declaringType==null) 
          if (this.nameSpace!=null)
            if (this.nameSpace.Length>0)
              fullName = this.nameSpace + "." + this.name;
            else
              fullName = this.name;
          else 
            fullName = this.name;        
        else 
          fullName = this.declaringType.NameWithNameSpace + "+" + this.name;
        int resScope = this.resolutionScope & 0x00000003;
        
        if (resScope==0x02) 
        {
          if (this.assembly!=null)
          {
            fullName += ", " + this.assembly.Name.FullName;
            return fullName;
          }
          RAssemblyName [] rans = this.rad.GetReferencedAssemblies();
          if (rans!=null)
          {      
            fullName += ", " + rans[(this.ResolutionScope>>2)-1].FullName;
            this.assembly = new RAssemblyRef(rans[(this.ResolutionScope>>2)-1]);
            return fullName;
          }
        }
        else if (resScope==0x03) 
        {
          RTypeRef r = this.rad.GetTypeByToken(this.resolutionScope>>2);
          fullName = r.NameWithNameSpace + "." + this.name + ", " + r.Assembly.Name.FullName;
          return fullName;
        }
        else if (this.assembly!=null)
        {
          fullName = fullName + ", " + this.assembly.Name.FullName;
          return fullName;
        }
        return fullName;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="tA"></param>
    internal void SetAttributes(TypeAttributes tA)
    {
      this.attributes = tA;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="a"></param>
    internal void SetAssembly(RAssembly a)
    {
      this.assembly = a;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="a"></param>
    internal void SetBaseType(RType a)
    {
      this.baseType = a;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="a"></param>
    internal void SetDeclaringType(RType a)
    {
      this.declaringType = a;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="a"></param>
    internal void SetElementType(RType a)
    {
      this.elementType = a;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="a"></param>
    internal void SetRArrayShape(ARRAY.ArrayShape a)
    {
      this.RArrayShape = a;
    }
    
    #endregion
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="type"></param>
    /// <param name="rad"></param>
//    internal void CompleteRTypeRef(Type type, RAssemblyDef rad) 
//    {
//      if (type==null) return;
//      this.rad = rad;
//      if (type.IsArray)
//      {
//        this.arrayRank = type.GetArrayRank();
//        //TODO: Check this please
//        this.arrayShape = new ARRAY.ArrayShape();
//        
//        this.elementType = rad.GetRTypeRef(type.GetElementType());
//      }
//      this.constructors = new ArrayList();
//      this.events = new ArrayList();
//      this.fields = new ArrayList();
//      this.interfaces = new ArrayList();
//      this.methods = new ArrayList();
//      this.properties = new ArrayList();
//
//      this.assembly = this.rad.GetReferencedAssembly(type.Assembly);
//      if (this.assembly == null)
//        this.assembly = new RAssemblyRef(type.Assembly);
//      this.attributes = type.Attributes;
//      
//      if (type.BaseType!=null)
//      {
//        this.baseType = rad.GetRTypeRef(type.BaseType);
//      }
//      Type ElemType = type.GetElementType();
//      if (ElemType!=null)
//      {
//        this.elementType = rad.GetRTypeRef(ElemType);
//      }
//      //this.bindingFlags = ??
//      ConstructorInfo [] ctis = type.GetConstructors();
//      if (ctis!=null)
//      {
//        for (int i = 0; i < ctis.Length; i++)
//        {
//          this.constructors.Add(new RConstructorRef(ctis[i],rad));
//        }
//      }
//      if (type.DeclaringType!=null)
//      {
//        
//        this.declaringType = rad.GetRTypeRef(type.DeclaringType);
//      }
//      EventInfo [] eis = type.GetEvents();
//      if (eis!=null)
//      {
//        for (int i = 0;i<eis.Length;i++)
//          this.events.Add(new REventRef(eis[i],rad));
//      }
//      FieldInfo [] fis = type.GetFields();
//      if (fis!=null)
//      {
//        for (int i = 0;i<fis.Length;i++)
//          this.fields.Add(new RFieldRef(fis[i],rad));
//      }
//      Type [] inters = type.GetInterfaces();
//      if (fis!=null)
//      {
//        for (int i = 0;i<inters.Length;i++)
//          this.interfaces.Add(rad.GetRTypeRef(inters[i]));
//      }
//
//      this.memberType = type.MemberType;
//      MethodInfo [] mis = type.GetMethods();
//      if (mis!=null)
//      {
//        for (int i = 0; i < mis.Length; i++)
//          this.methods.Add(new RMethodRef(mis[i],rad));
//      }
//      this.name = type.Name;
//      this.nameSpace = type.Namespace;
//      PropertyInfo [] pis = type.GetProperties();
//      if (pis!=null)
//      {
//        for (int i = 0; i < pis.Length; i++)
//          this.properties.Add(new RPropertyRef(pis[i],rad));
//      }    
//    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="nameSpace"></param>
    /// <param name="rad"></param>
    internal RTypeRef(String name, String nameSpace,RAssemblyDef rad)
    {
      this.name = name;
      this.nameSpace = nameSpace;
      this.constructors = new ArrayList();
      this.events = new ArrayList();
      this.fields = new ArrayList();
      this.interfaces = new ArrayList();
      this.methods = new ArrayList();
      this.properties = new ArrayList();
      this.rad = rad;
      this.attributes = (TypeAttributes)0;
      this.memberType = MemberTypes.TypeInfo;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="nameSpace"></param>
    /// <param name="rad"></param>
    /// <param name="resolScope"></param>
    internal RTypeRef(String name, String nameSpace,RAssemblyDef rad,int resolScope)
    {
      this.name = name;
      this.nameSpace = nameSpace;
      this.constructors = new ArrayList();
      this.events = new ArrayList();
      this.fields = new ArrayList();
      this.interfaces = new ArrayList();
      this.methods = new ArrayList();
      this.properties = new ArrayList();
      this.rad = rad;
      this.resolutionScope = resolScope;
      this.attributes = (TypeAttributes)0;
      this.memberType = MemberTypes.TypeInfo;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="nameSpace"></param>
    /// <param name="rad"></param>
    /// <param name="tk"></param>
    internal RTypeRef(String name, String nameSpace,RAssemblyDef rad,MDToken tk)
    {
      this.name = name;
      this.nameSpace = nameSpace;
      this.constructors = new ArrayList();
      this.events = new ArrayList();
      this.fields = new ArrayList();
      this.interfaces = new ArrayList();
      this.methods = new ArrayList();
      this.properties = new ArrayList();
      this.rad = rad;
      int stype = 0;
      int sRid = tk.RID << 2;
      switch (tk.Type) 
      {

        case TokenType.Module :
          stype = 0;
          break;

        case TokenType.ModuleRef :
          stype = 1;
          break;

        case TokenType.AssemblyRef :
          stype = 2;
          break;

        case TokenType.TypeRef :
          stype = 3;
          break;

        default :
          throw new BadMetaDataException("Invalid coded token for ResolutionScope");
      }
      this.resolutionScope = stype | sRid;
      this.attributes = (TypeAttributes)0;
      this.memberType = MemberTypes.TypeInfo;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rcr"></param>
    internal void AddConstructor(RConstructorRef rcr)
    {
      if (this.constructors==null)
        this.constructors = new ArrayList();
      this.constructors.Add(rcr);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rmr"></param>
    internal void AddMethod(RMethodRef rmr)
    {
      if (this.methods==null)
        this.methods = new ArrayList();
      this.methods.Add(rmr);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rer"></param>
    internal void AddEvent(REventRef rer)
    {
      if (this.events==null)
        this.events = new ArrayList();
      this.events.Add(rer);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rpr"></param>
    internal void AddProperty(RPropertyRef rpr)
    {
      if (this.properties==null)
        this.properties = new ArrayList();
      this.properties.Add(rpr);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="t"></param>
    internal void AddInterface(RType t)
    {
      if (this.interfaces==null)
        this.interfaces = new ArrayList();
      this.interfaces.Add(t);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="rfr"></param>
    internal void AddField(RFieldRef rfr)
    {
      if (this.fields==null)
        this.fields = new ArrayList();
      this.fields.Add(rfr);
    }
  
  
    private void SetReflectionType()
    {
      if (this.reflectionType==null)
      {
        Type t = Type.GetType(this.FullName);

        if (t==null &&  this.rad.rAssemblyRefs!=null)
        {
          string targetDir = System.IO.Path.GetDirectoryName(rad.FileName);
          if
            (AppDomain.CurrentDomain.RelativeSearchPath == null || AppDomain.CurrentDomain.RelativeSearchPath.IndexOf(targetDir) == -1)
  
            AppDomain.CurrentDomain.AppendPrivatePath(System.IO.Path.GetDirectoryName(rad.FileName));
  
          foreach (RAssemblyRef r in this.rad.rAssemblyRefs) // Ensure that all references are loaded
              System.Reflection.Assembly.LoadWithPartialName(r.Name.Name);
          Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies();
          if (asms==null)
            asms = new Assembly[0];
          foreach (Assembly a in asms) 
            if (a.FullName==this.assembly.Name.FullName || a.GetName().Name.Equals(this.assembly.Name.Name))
            {
              t = a.GetType(this.NameWithNameSpace);
              break;
            }
        }
        this.reflectionType = t;
      }
    }

/*
    private void SetReflectionType()
    {
      if (this.reflectionType==null)
      {
        Type t = Type.GetType(this.FullName);
        if (t==null && this.rad.rAssemblyRefs!=null)
        {
          if (this.rad.LoadDomain == null)
          {
            this.rad.LoadDomain = AppDomain.CreateDomain("RAILLoadDomain",AppDomain.CurrentDomain.Evidence);
          }
          Assembly [] asms = this.rad.LoadDomain.GetAssemblies();
          if (asms==null)
            asms = new Assembly[0];
          foreach (RAssemblyRef r in this.rad.rAssemblyRefs)
          {
            Assembly asm = null;
            foreach (Assembly a in asms)
              if (a.FullName==r.Name.FullName ||
                a.GetName().Name.Equals(r.Name.Name))
              {
                asm = a;
                break;
              }
          
            try
            {
              if (asm==null)
                asm = this.rad.LoadDomain.Load(r.Name.FullName);
            }
            catch (System.Exception)
            {
              //asm = this.rad.LoadDomain.Load(r.Name.Name);
              AssemblyLoader objc = (AssemblyLoader) this.rad.LoadDomain.CreateInstanceAndUnwrap(
                "Rail",
                "Rail.Reflect.AssemblyLoader");
              asm = objc.LoadAssemblyByPatialName(r.Name.Name);
            }
            if (asm.FullName.Equals(this.assembly.Name.FullName) ||
              asm.GetName().Name.Equals(this.assembly.Name.Name))
            {
              t = asm.GetType(this.NameWithNameSpace);
              break;
            }
          }
        }
        this.reflectionType = t;
      }
    }


    */
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    
    public override RField[] GetFields() 
    {
      RField [] rfs = new RField[0];
      if (this.ReflectionType!=null)
      {
        FieldInfo [] fis = this.ReflectionType.GetFields(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (fis!=null)
        {
          int i = 0;
          rfs = new RField[fis.Length];
          this.fields = new ArrayList();
          foreach (FieldInfo fi in fis)
          {
            RFieldRef rf = new RFieldRef(fi,this.rad);
            this.AddField((RFieldRef)rf);
            rfs[i++] = rf;
          }
        }
      }
      return rfs;
    }

    public override RField[] GetFields(BindingFlags bf) 
    {
      RField [] rfs = new RField[0];
      if (this.ReflectionType!=null)
      {
        FieldInfo [] fis = this.ReflectionType.GetFields(bf);        
        if (fis!=null)
        {
          int i = 0;
          rfs = new RField[fis.Length];
          foreach (FieldInfo fi in fis)
          {
            RFieldRef rf = new RFieldRef(fi,this.rad);
            rfs[i++] = rf;
          }
        }
        if (this.fields==null ||
          (this.fields!=null && this.fields.Count==0))
          GetFields();
      }
      return rfs;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override RField GetField(String name) 
    {
      RField rf = null;
      if (this.fields != null) 
      {
        IEnumerator ienum = this.fields.GetEnumerator();
        while (ienum.MoveNext())
        {
          rf = (RField)ienum.Current;
          if (rf.Name.Equals(name))
            return rf;
        }
      }
      if (this.ReflectionType!=null)
      {
        FieldInfo fi = this.ReflectionType.GetField(
          name,
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (fi!=null)
        {
          rf = new RFieldRef(fi,this.rad);
          this.AddField((RFieldRef)rf);
          return rf;
        }
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="returnValue"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public override RMethod GetMethod(String name, RType returnValue, RParameter[] args) 
    {
      RMethod rm = null;
      if (this.methods!=null)
      {
        IEnumerator ienum = this.methods.GetEnumerator();
        while (ienum.MoveNext())
        {
          rm = (RMethod)ienum.Current;
          if (rm.Name.Equals(name))
            //TODO: Does the method equals needs to be implemented in RType
            if (rm.ReturnType.ReturnType.FullName.Equals(returnValue.FullName))
            {
              RParameter [] rpms = rm.GetParameters();
              bool goodReturn = false;
              if (args==null && rpms==null)
                return rm;
              if (rpms!=null)
                if (args == null && rpms.Length==0)
                  return rm;
              if (args!=null)
                if (args.Length==0 && rpms==null)
                  return rm;
              if (args.Length == 0 && rpms.Length==0)
                return rm;
              if (args.Length == rpms.Length)
                for (int i = 0; i < rpms.Length;i++)
                {
                  if (!(args[i].ParameterType.NameWithNameSpace == rpms[i].ParameterType.NameWithNameSpace))
                  {
                    goodReturn = false;
                    break;
                  }
                  else
                    goodReturn = true;
                }
              if (goodReturn)
                return rm;
            }
        }
      }
      if (this.ReflectionType!=null)
      {
        Type [] paramz = new Type[args.Length];
        int i = 0;
        foreach (RParameter r in args)
        {
          paramz[i++] = ((RTypeRef)r.ParameterType).ReflectionType;
        }

        MethodInfo mi = this.ReflectionType.GetMethod(
          name,
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static,
          null,
          paramz,
          null);
        if (mi!=null)
        {
          rm = new RMethodRef(mi,this.rad);
          this.AddMethod((RMethodRef)rm);
          return rm;
        }
      }
      return null;
    }

//    /// <summary>
//    /// 
//    /// </summary>
//    /// <param name="name"></param>
//    /// <param name="returnValue"></param>
//    /// <param name="args"></param>
//    /// <returns></returns>
//    internal RMethod GetMethod(String name, RType returnValue, RType[] args) 
//    {
//      RMethod rm = null;
//      if (this.methods!=null)
//      {
//        IEnumerator ienum = this.methods.GetEnumerator();
//        while (ienum.MoveNext())
//        {
//          rm = (RMethod)ienum.Current;
//          if (rm.Name.Equals(name))
//            //TODO: Does the method equals needs to be implemented in RType
//            if (rm.ReturnType.ReturnType.FullName.Equals(returnValue.FullName))
//            {
//              RParameter [] rpms = rm.GetParameters();
//              bool goodReturn = false;
//              if (args==null && rpms==null)
//                return rm;
//              if (rpms!=null)
//                if (args == null && rpms.Length==0)
//                  return rm;
//              if (args!=null)
//                if (args.Length==0 && rpms==null)
//                  return rm;
//              if (args.Length == 0 && rpms.Length==0)
//                return rm;
//              if (args.Length == rpms.Length)
//                for (int i = 0; i < rpms.Length;i++)
//                {
//                  if (!(args[i].NameWithNameSpace == rpms[i].ParameterType.NameWithNameSpace))
//                  {
//                    goodReturn = false;
//                    break;
//                  }
//                  else
//                    goodReturn = true;
//                }
//              if (goodReturn)
//                return rm;
//            }
//        }
//      }
//      if (this.ReflectionType!=null)
//      {
//        Type [] paramz = new Type[args.Length];
//        int i = 0;
//        foreach (RType r in args)
//        {
//          paramz[i++] = ((RTypeRef)r).ReflectionType;
//        }
//
//        MethodInfo mi = this.ReflectionType.GetMethod(
//          name,
//          BindingFlags.Instance |
//          BindingFlags.Public | 
//          BindingFlags.NonPublic |
//          BindingFlags.Static,
//          null,
//          paramz,
//          null);
//        if (mi!=null)
//        {
//          rm = new RMethodRef(mi,this.rad);
//          this.AddMethod((RMethodRef)rm);
//          return rm;
//        }
//      }
//      return null;
//    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <returns></returns>
    public override RMethod[] GetMethods(BindingFlags bf) 
    {
      RMethod [] rms = new RMethod[0];
      if (this.ReflectionType!=null)
      {
        MethodInfo [] mis = this.ReflectionType.GetMethods(bf);        
        if (mis!=null)
        {
          int i = 0;
          rms = new RMethod[mis.Length];
          foreach (MethodInfo mi in mis)
          {
            RMethodRef rm = new RMethodRef(mi,this.rad);
            rms[i++] = rm;
          }
        }
        if (this.methods==null ||
          (this.methods!=null && this.methods.Count==0))
            GetMethods();
      }
      return rms;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override RMethod[] GetMethods() 
    {
      RMethod [] rms = new RMethod[0];
      if (this.ReflectionType!=null)
      {
        MethodInfo [] mis = this.ReflectionType.GetMethods(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (mis!=null)
        {
          int i = 0;
          rms = new RMethod[mis.Length];
          this.methods = new ArrayList();
          foreach (MethodInfo mi in mis)
          {
            RMethodRef rm = new RMethodRef(mi,this.rad);
            this.AddMethod((RMethodRef)rm);
            rms[i++] = rm;
          }
        }
      }
      return rms;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
//    public override RConstructor GetConstructor(RType[] args) 
//    {
//      RConstructor rc = null;
//      if (this.constructors!=null)
//      {
//        for (int i = 0; i < this.constructors.Count; i++)
//        {
//          rc = (RConstructor)this.constructors[i];
//          if (args==null && rc.ParametersCount == 0)
//            return rc;
//          if (args!=null)
//          {
//            if (args.Length == 0 && rc.ParametersCount == 0)
//              return rc;
//            if (args.Length == rc.ParametersCount)
//            {
//              bool okToReturn = true;
//              RParameter [] paramS = rc.GetParameters();
//              if (paramS!=null)
//                for (int j=0;j<paramS.Length;j++)
//                {
//                  if (args[j]!=null)
//                  {
//                    if (args[j].NameWithNameSpace != paramS[j].ParameterType.NameWithNameSpace)
//                      okToReturn = false;
//                  }
//                  else if (paramS[j].ParameterType!=null)
//                    okToReturn = false;
//                }
//              if (okToReturn)
//                return rc;
//            }
//          }
//        }
//      }
//      if (this.ReflectionType!=null)
//      {
//        Type [] paramz = new Type[args.Length];
//        int i = 0;
//        foreach (RType r in args)
//        {
//          paramz[i++] = ((RTypeRef)r).ReflectionType;
//        }
//
//        ConstructorInfo ci = this.ReflectionType.GetConstructor(paramz);
//        if (ci!=null)
//        {
//          rc = new RConstructorRef(ci,this.rad);
//          this.AddConstructor((RConstructorRef)rc);
//          return rc;
//        }
//      }
//      return null;
//    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public override RConstructor GetConstructor(RParameter[] args) 
    {
      RConstructor rc = null;
      if (this.constructors!=null)
      {
        for (int i = 0; i < this.constructors.Count; i++)
        {
          rc = (RConstructor)this.constructors[i];
          if (args==null && rc.ParametersCount == 0)
            return rc;
          if (args!=null)
          {
            if (args.Length == 0 && rc.ParametersCount == 0)
              return rc;
            if (args.Length == rc.ParametersCount)
            {
              bool okToReturn = true;
              RParameter [] paramS = rc.GetParameters();
              if (paramS!=null)
                for (int j=0;j<paramS.Length;j++)
                {
                  if (args[j]!=null)
                  {
                    if (args[j].ParameterType.NameWithNameSpace != paramS[j].ParameterType.NameWithNameSpace)
                      okToReturn = false;
                  }
                  else if (paramS[j].ParameterType!=null)
                    okToReturn = false;
                }
              if (okToReturn)
                return rc;
            }
          }
        }
      }
      if (this.ReflectionType!=null)
      {
        Type [] paramz = new Type[args.Length];
        int i = 0;
        foreach (RParameter r in args)
        {
          paramz[i++] = ((RTypeRef)r.ParameterType).ReflectionType;
        }

        ConstructorInfo ci = this.ReflectionType.GetConstructor(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic,
          null,
          paramz,
          null);

        if (null == ci)
          ci = this.ReflectionType.GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,null,paramz,null);
        
        if (ci!=null)
        {
          rc = new RConstructorRef(ci,this.rad);
          this.AddConstructor((RConstructorRef)rc);
          return rc;
        }
      }
      return null;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="bf"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public override RConstructor GetConstructor(System.Reflection.BindingFlags bf, RParameter[] args) 
    {
      RConstructor rc = null;
      if (this.constructors!=null)
      {
        for (int i = 0; i<this.constructors.Count;i++)
        {
          rc = (RConstructor)this.constructors[i];
          if ((rc.BindingFlags & bf)==bf)
          {
            RParameter [] paramss = rc.GetParameters();
            bool isMatch = true;
            int index = 0;
            if (paramss!=null &&
              args != null &&
              paramss.Length == args.Length)
            {
              while(index < paramss.Length)    
              {
                if (paramss[index].ParameterType.NameWithNameSpace!=
                  args[index].ParameterType.NameWithNameSpace)
                {
                  isMatch = false;
                  break;
                }
                ++index;
              }
            }
            else if (paramss==null && args==null)
              return rc;
            if (isMatch)
              return rc;
          }
        }
      }
      if (this.ReflectionType!=null)
      {
        Type [] paramz = new Type[args.Length];
        int i = 0;
        foreach (RParameter r in args)
        {
          paramz[i++] = ((RTypeRef)r.ParameterType).ReflectionType;
        }

        ConstructorInfo ci = this.ReflectionType.GetConstructor(bf,null,paramz,null);
        if (ci!=null)
        {
          rc = new RConstructorRef(ci,this.rad);
          this.AddConstructor((RConstructorRef)rc);
          return rc;
        }
      }
      return null;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override RConstructor[] GetConstructors() 
    {
      RConstructor [] rcs = new RConstructor[0];
      if (this.ReflectionType!=null)
      {
        ConstructorInfo [] cis = this.ReflectionType.GetConstructors(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (cis!=null)
        {
          int i = 0;
          rcs = new RConstructor[cis.Length];
          this.constructors = new ArrayList();
          foreach (ConstructorInfo ci in cis)
          {
            RConstructorRef rc = new RConstructorRef(ci,this.rad);
            this.AddConstructor((RConstructorRef)rc);
            rcs[i++] = rc;
          }
        }
      }
      return rcs;
    }

    public override RConstructor[] GetConstructors(BindingFlags bf) 
    {
      RConstructor [] rcs = new RConstructor[0];
      if (this.ReflectionType!=null)
      {
        ConstructorInfo [] cis = this.ReflectionType.GetConstructors(bf);        
        if (cis!=null)
        {
          int i = 0;
          rcs = new RConstructor[cis.Length];
          foreach (ConstructorInfo ci in cis)
          {
            RConstructorRef rc = new RConstructorRef(ci,this.rad);
            rcs[i++] = rc;
          }
        }
        if (this.constructors==null ||
          (this.constructors!=null && this.constructors.Count==0))
          GetConstructors();
      }
      return rcs;
    }


    public override REvent GetEvent(String eventName) 
    {
      REvent re = null;
      if (this.events!=null)
      {
        IEnumerator ienum = this.events.GetEnumerator();
        while (ienum.MoveNext())
        {
          re = (REvent)ienum.Current;
          if (re.Name.Equals(eventName))
            return re;
        }
      }
      if (this.ReflectionType!=null)
      {
        EventInfo ei = this.ReflectionType.GetEvent(eventName,
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);
        if (ei!=null)
        {
          re = new REventRef(ei,this.rad);
          this.AddEvent((REventRef)re);
          return re;
        }
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override REvent[] GetEvents() 
    {
      REvent [] res = new REvent[0];
      if (this.ReflectionType!=null)
      {
        EventInfo [] eis = this.ReflectionType.GetEvents(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (eis!=null)
        {
          int i = 0;
          res = new REvent[eis.Length];
          this.events = new ArrayList();
          foreach (EventInfo ei in eis)
          {
            REventRef re = new REventRef(ei,this.rad);
            this.AddEvent((REventRef)re);
            res[i++] = re;
          }
        }
      }
      return res;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override RProperty GetProperty(String name) 
    {
      RProperty rp = null;
      if (this.properties!=null)
      {
        IEnumerator ienum = this.properties.GetEnumerator();
        while (ienum.MoveNext())
        {
          rp = (RProperty)ienum.Current;
          if (rp.Name.Equals(name))
            return rp;
        }
      }
      if (this.ReflectionType!=null)
      {
        PropertyInfo pi = this.ReflectionType.GetProperty(name,
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);
        if (pi!=null)
        {
          rp = new RPropertyRef(pi,this.rad);
          this.AddProperty((RPropertyRef)rp);
          return rp;
        }
      }
      return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override RProperty[] GetProperties() 
    {
      RProperty [] rps = new RProperty[0];
      if (this.ReflectionType!=null)
      {
        PropertyInfo [] pis = this.ReflectionType.GetProperties(
          BindingFlags.Instance |
          BindingFlags.Public | 
          BindingFlags.NonPublic |
          BindingFlags.Static);        
        if (pis!=null)
        {
          int i = 0;
          rps = new RProperty[pis.Length];
          this.properties = new ArrayList();
          foreach (PropertyInfo pi in pis)
          {
            RPropertyRef rp = new RPropertyRef(pi,this.rad);
            this.AddProperty((RPropertyRef)rp);
            rps[i++] = rp;
          }
        }
      }
      return rps;
    }

    /// <summary>
    /// Returns all interfaces implemented by this type.
    /// </summary>    
    /// <returns>An array with the interfaces implemented by this type.</returns>
    public override RType[] GetInterfaces() 
    {
      RType [] rts = new RType[0];
      if (this.ReflectionType!=null)
      {
        Type [] ts = this.ReflectionType.GetInterfaces();        
        if (ts!=null)
        {
          int i = 0;
          rts = new RType[ts.Length];
          this.interfaces = new ArrayList();
          foreach (Type t in ts)
          {
            RTypeRef rt = this.rad.GetRTypeRef(t);
            this.AddInterface((RType)rt);
            rts[i++] = rt;
          }
        }
      }
      return rts;
    }

    /// <summary>
    /// Searches for the interface with the given name.
    /// </summary>
    /// <param name="name">The fully qualified name of the interface to search for.</param>
    /// <returns>The interface if it is found, null otherwise.</returns>
    public override RType GetInterface(String name) 
    {
      RType rt = null;
      if (this.interfaces!=null)
      {
        IEnumerator ienum = this.interfaces.GetEnumerator();
        while (ienum.MoveNext())
        {
          rt = (RType)ienum.Current;
          if (rt.FullName.Equals(name) ||
            rt.NameWithNameSpace.Equals(name))
            return rt;
        }
      }
      if (this.ReflectionType!=null)
      {
        Type t = this.ReflectionType.GetInterface(name);
        if (t!=null)
        {
          rt = this.rad.GetRTypeRef(t);
          this.AddInterface(rt);
          return rt;
        }
      }
      return null;
    }
  }


  /* List: GetXXX
   * Create new: DefineXXX(name) DefineXXX(original)
   * Remove: RemoveXXX(name)
   */
  /// <summary>
  /// 
  /// </summary>
  public sealed class RTypeDef : RType, IVisitable, ICustomAttributeOwnerDef 
  {
    #region RType constructors
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    internal RTypeDef(String name) 
    {
      this.name = name;
      this.constructors = new ArrayList();
      this.events = new ArrayList();
      this.fields = new ArrayList();
      this.interfaces = new ArrayList();
      this.methods = new ArrayList();
      this.properties = new ArrayList();
      this.attributes = (TypeAttributes)0;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="original"></param>
    internal RTypeDef(RType original) 
    {
      if (original.IsArray)
      {
        this.arrayRank = original.GetArrayRank();
        this.arrayShape = original.RArrayShape;
        this.elementType = original.ElementType;
      }
      this.constructors = new ArrayList();
      this.events = new ArrayList();
      this.fields = new ArrayList();
      this.interfaces = new ArrayList();
      this.methods = new ArrayList();
      this.properties = new ArrayList();
      this.attributes = original.Attributes;
      this.baseType = original.BaseType;
      this.bindingFlags = original.BindingFlags;
      RConstructor [] rcs = original.GetConstructors();
      if (rcs!=null)
        if (rcs.Length>0) 
        {
          for (int i = 0; i< rcs.Length;i++)
            this.constructors.Add((RConstructorDef)rcs[i]);
        }
      this.declaringType = original.DeclaringType;
      REvent [] res = original.GetEvents();
      if (res!=null)
        if (res.Length>0)
        {
          for (int i = 0; i< res.Length;i++)
            this.events.Add((REventDef)res[i]);
        }
      RField [] rfs = original.GetFields();
      if (rfs!=null)
        if (rfs.Length>0)
        {
          for (int i = 0; i< rfs.Length;i++)
            this.fields.Add((RFieldDef)rfs[i]);
        }
      RType[] rts = original.GetInterfaces();
      if (rts!=null)
        if (rts.Length>0)
        {
          for (int i = 0; i< rts.Length;i++)
            this.interfaces.Add((RType)rts[i]);
        }
      this.memberType = original.MemberType;
      RMethod [] rms = original.GetMethods();
      if (rms!=null)
        if (rms.Length>0)
        {
          for (int i = 0; i< rms.Length;i++)
            this.methods.Add((RMethodDef)rms[i]);
        }
      this.module = original.Module;
      this.name = original.Name;
      this.nameSpace = original.NameSpace;
      RProperty [] rps = original.GetProperties();
      if (rps!=null)
        if (rps.Length>0)
        {
          for (int i = 0; i< rps.Length;i++)
            this.properties.Add((RPropertyDef)rps[i]);
        }
    }
    #endregion

    #region Type information. Assembly, module, name   

    /// <summary>
    /// 
    /// </summary>
    public override System.Reflection.Emit.PackingSize PackingSize
    {
      set
      {
        this.packingSize = value;
      }
    }
    
    /// <summary>
    /// 
    /// </summary>
    public override int TypeSize
    {
      set
      {
        this.typeSize = value;
      }
    }
    /// <summary>
    /// Gets or sets the attributes of this type
    /// </summary>
    public override TypeAttributes Attributes 
    {
      set 
      {
        this.attributes = value;
      }
    }
    

    /// <summary>
    /// Gets or sets the base class of this type.
    /// </summary>
    public override RType BaseType 
    {      
      set 
      {
        this.baseType = value;
      }
    }
    /// <summary>
    /// 
    /// </summary>
    public override RAssembly Assembly 
    {
      set
      {
        this.assembly = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override RModule Module 
    {
      set
      {
        this.module = value;
      }
    }

    /// <summary>
    /// The namespace of the type, should be null if it is nested
    /// </summary>
    public override string NameSpace
    {
      set
      {
        this.nameSpace = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override RType ElementType 
    {
      set
      {
        this.elementType = value;
      }
    }
    /// <summary>
    /// 
    /// </summary>
    public override ARRAY.ArrayShape RArrayShape
    {

      set
      {
        this.arrayShape = value;
      }
    }


    /// <summary>
    /// Removes the given interface from the list of implemented interfaces
    /// </summary>
    /// <param name="interfaceType">The type of the interface</param>    
    /// <remarks>
    /// This method returns silently if the given interface is not found in the
    /// list of implemented interfaces.
    /// </remarks>
    public void RemoveInterface(RType interfaceType) 
    {
      if (this.interfaces.Contains(interfaceType))
        this.interfaces.Remove(interfaceType);
    }

    /// <summary>
    /// Adds a new interface to the ones implemented by this type.
    /// </summary>
    /// <param name="interfaceType">The type of interface to implement</param>
    /// <remarks>
    /// This method does nothing if the interface is alredy implemented.
    /// </remarks>
    public void AddInterface(RType interfaceType) 
    {
      this.interfaces.Add(interfaceType);
    }

    #endregion
    
    #region Methods management    
    
//    internal RMethod GetMethod(String name, RType returnValue, RType[] args) 
//    {
//      if (this.methods == null) return null;
//      if (this.methods.Count==0) return null;
//      IEnumerator ienum = this.methods.GetEnumerator();
//      RMethod rm = null;
//      while (ienum.MoveNext())
//      {
//        rm = (RMethod)ienum.Current;
//        if (rm.Name.Equals(name))
//          //TODO: Does the method equals needs to be implemented in RType
//          if (rm.ReturnType.ReturnType.FullName.Equals(returnValue.FullName))
//          {
//            RParameter [] rpms = rm.GetParameters();
//            bool goodReturn = false;
//            if (args==null && rpms==null)
//              return rm;
//            if (rpms!=null)
//              if (args == null && rpms.Length==0)
//                return rm;
//            if (args!=null)
//              if (args.Length==0 && rpms==null)
//                return rm;
//            if (args.Length == 0 && rpms.Length==0)
//              return rm;
//            if (args.Length == rpms.Length)
//              for (int i = 0; i < rpms.Length;i++)
//              {
//                if (!(args[i].NameWithNameSpace == rpms[i].ParameterType.NameWithNameSpace))
//                {
//                  goodReturn = false;
//                  break;
//                }
//                else
//                  goodReturn = true;
//              }
//            if (goodReturn)
//              return rm;
//          }
//      }
//      return null;
//    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="returnValue"></param>
    /// <param name="args"></param>
    /// <param name="me"></param>
    /// <returns></returns>
    public RMethodDef DefineMethod(String name, RType returnValue, RParameter[] args, MethodAttributes me) 
    {
      RMethodDef rmd =  new RMethodDef();
      rmd.Attributes = me;
      rmd.Name = name;
      rmd.ReturnType = new RReturnType(returnValue);
      if (args!=null)
        for (int i = 0; i < args.Length; i++)
        {
          rmd.AddParameter(args[i]);
        }
      rmd.DeclaringType = this;
      this.methods.Add(rmd);
      return rmd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="returnValue"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public RMethodDef DefineMethod(String name, RType returnValue, RParameter[] args) 
    {
      RMethodDef rmd =  new RMethodDef();
      rmd.Name = name;
      rmd.ReturnType = new RReturnType(returnValue);
      if (args!=null)
        for (int i = 0; i < args.Length; i++)
        {
          rmd.AddParameter(args[i]);
        }
      rmd.DeclaringType = this;
      this.methods.Add(rmd);
      return rmd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <param name="newName"></param>
    /// <returns></returns>
    public RMethodDef CopyMethod(RMethodDef source, String newName ) 
    {
    
      RMethodDef rmd = new RMethodDef();
      rmd.Attributes = source.Attributes;
      rmd.BindingFlags = source.BindingFlags;
      rmd.CallingConventions = source.CallingConventions;
      rmd.DeclaringType = this;
      rmd.MemberType = MemberTypes.Method;
      rmd.MethodImplementationFlags = source.MethodImplementationFlags;
      //rmd.ReturnType = new RReturnType(GetRType(source.ReturnType.ReturnType,this));
      rmd.ReturnType = new RReturnType(GetCorrectRType(source.ReturnType.ReturnType));
      if (source.ParametersCount > 0) 
      {
        RParameter [] rps = source.GetParameters();
        for (int i = 0; i < source.ParametersCount; i++)
        {
          //RParameter rParam = new RParameter(rps[i].Sequence,(int)rps[i].Attributes,rps[i].Name,GetRType(rps[i].ParameterType,this));
          RParameter rParam = new RParameter(rps[i].Sequence,(int)rps[i].Attributes,rps[i].Name,GetCorrectRType(rps[i].ParameterType));
          ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo(rParam,rps[i]);
          rmd.AddParameter(rParam);
        }
      }
      rmd.Name = newName;
      if (source.IsOverrideBody)
        foreach (RMethod iMeth in source.OverridedMethod)
        {
          RMethod rm;
//          RAssembly declarAssembly = iMeth.DeclaringType.Assembly;
//          if (((RAssemblyDef)this.Assembly).GetReferencedAssembly(iMeth.DeclaringType.Assembly.Name.FullName)==null)
//            ((RAssemblyDef)this.Assembly).AddReferencedAssembly(iMeth.DeclaringType.Assembly.Name.FullName);
//          RType declareType = 
//            ((RAssemblyDef)this.Assembly).RModuleDef.GetType(iMeth.DeclaringType.NameWithNameSpace);
//          if (declareType==null)
//            declareType =
//              ((RAssemblyDef)this.Assembly).GetRTypeRef(iMeth.DeclaringType.NameWithNameSpace);
          RType declareType = GetCorrectRType(iMeth.DeclaringType);
          rm = declareType.GetMethod(iMeth.Name,((RMethod)iMeth).ReturnType.ReturnType,iMeth.GetParameters());
          rmd.AddOverride(rm);          
        }
      ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo((RMember)rmd,source);
      this.methods.Add(rmd);
      return rmd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="iType"></param>
    /// <returns></returns>
    internal RType GetCorrectRType(RType iType)
    {
      RType rT = null;
      if (iType.FullName.Equals(this.FullName))
        rT = this;
      else
      {
        RAssemblyDef asmDef = (RAssemblyDef)this.Assembly;
        rT = asmDef.RModuleDef.GetType(iType.NameWithNameSpace);
        if (rT==null)
        {
          if (asmDef.GetReferencedAssembly(iType.Assembly.Name.FullName)==null)
            asmDef.AddReferencedAssembly(iType.Assembly.Name.FullName);
          rT =
            asmDef.GetRTypeRef(iType.NameWithNameSpace);            
        }
      }
      return rT;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <param name="target"></param>
    public void CopyMethodBody(RMethodDef source, RMethodDef target) 
    {
      target.MethodBody = source.MethodBody.Clone((RMethodBase)target);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="method"></param>
    public void RemoveMethod(RMethod method) 
    {
      if (this.methods.Contains(method))
        this.methods.Remove(method);
    }
    #endregion

    #region Constructors
    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <returns></returns>
    public RConstructorDef CopyConstructor(RConstructorDef source) 
    {
      RConstructorDef rcd = new RConstructorDef();
      rcd.DeclaringType = this;
      rcd.MemberType = MemberTypes.Constructor;
      rcd.MethodImplementationFlags = source.MethodImplementationFlags;
      if (source.ParametersCount > 0) 
      {
        RParameter [] rps = source.GetParameters();
        for (int i = 0; i < source.ParametersCount; i++)
        {
          //RParameter rParam = new RParameter(rps[i].Sequence,(int)rps[i].Attributes,rps[i].Name,GetRType(rps[i].ParameterType,this));
          RParameter rParam = new RParameter(rps[i].Sequence,(int)rps[i].Attributes,rps[i].Name,GetCorrectRType(rps[i].ParameterType));
          ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo(rParam,rps[i]);
          rcd.AddParameter(rParam);
        }
        
      }
      rcd.Name = source.Name;
      rcd.Attributes = source.Attributes;
      rcd.BindingFlags = source.BindingFlags;
      rcd.CallingConventions = source.CallingConventions;
      //rcd.MethodBody = source.MethodBody.Clone((RMethodBase)rcd);
      ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo((RMember)rcd,source);
      this.constructors.Add(rcd);
      return rcd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <param name="target"></param>
    public void CopyMethodBody(RConstructorDef source, RConstructorDef target) 
    {
      target.MethodBody = source.MethodBody.Clone((RMethodBase)target);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public RConstructorDef DefineConstructor(RParameter[] args) 
    {
      return DefineConstructor(args,false);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <param name="isStatic"></param>
    /// <returns></returns>
    public RConstructorDef DefineConstructor(RParameter[] args, bool isStatic) 
    {
      RConstructorDef rcd = new RConstructorDef();
      rcd.DeclaringType = this;
      if (isStatic)
      {
        rcd.Name = ".cctor";
        rcd.Attributes |= MethodAttributes.Static; 
      }
      else
      {
        rcd.Name = ".ctor";
      }
      if (args!=null)
        for (int i = 0; i < args.Length ; i++)
          rcd.AddParameter(args[i]);
      this.constructors.Add(rcd);
      return rcd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public RConstructorDef DefineConstructor(RParameter[] args, string name) 
    {
      if (name.Equals(".cctor"))
        return DefineConstructor(args,true);
      else
        return DefineConstructor(args,false);
    }

    /// <summary>
    /// Remove a Constructor
    /// 
    /// TODO: What if the constructor is used in the Assembly
    /// </summary>
    /// <param name="args"></param>
    public void RemoveConstructor(RType[] args) 
    {
      IEnumerator ienum = this.constructors.GetEnumerator();
      RConstructorDef rcd = null;
      bool test = false;
      int pIndex = 0;
      while (ienum.MoveNext())
      {
        test = true;
        rcd = (RConstructorDef)ienum.Current;
        RParameter [] rps = rcd.GetParameters();
        if (rps!=null)
          for (int i = 0; i < rps.Length; i++)
          {
            if (!args[i].Equals(rps[i].ParameterType))
            {
              test = false;
              break;
            }
          }
        if (test && args!=null && rps!=null)
          if (args.Length==rps.Length)
            break;
        if (test && args==null && rps==null)
          break;
        if (test && args!=null && rps==null)
          if (args.Length==0)
            break;
        test = false;
        pIndex++;
      }
      if (test)
        this.constructors.RemoveAt(pIndex);
    }
    #endregion
  
    #region Properties management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="propertyType"></param>
    /// <returns></returns>
    public RPropertyDef DefineProperty(String name, RType propertyType) 
    {
      RPropertyDef rpd = new RPropertyDef();
      rpd.DeclaringType = this;
      rpd.Name = name;
      rpd.PropertyType = propertyType;
      this.properties.Add(rpd);
      return rpd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <param name="newName"></param>
    /// <returns></returns>
    public RPropertyDef CopyProperty(RProperty source, String newName) 
    {
      RPropertyDef rpd = new RPropertyDef();
      rpd.DeclaringType = this;
      rpd.Attributes = source.Attributes;
      rpd.BindingFlags = source.BindingFlags;
      
      if (source.GetMethod!=null)
      {
        //rpd.GetMethod = CopyMethod((RMethodDef)source.GetMethod,source.GetMethod.Name);
        RParameter [] paramz = new RParameter[source.GetMethod.ParametersCount];
        int i = 0;
        foreach (RParameter p in source.GetMethod.GetParameters())
        {
          paramz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        rpd.GetMethod = this.GetMethod(source.GetMethod.Name,GetCorrectRType(source.GetMethod.ReturnType.ReturnType),paramz);
      }
      rpd.MemberType = MemberTypes.Property;
      if (source.SetMethod!=null)
      {
        //  rpd.SetMethod = CopyMethod((RMethodDef)source.SetMethod,source.SetMethod.Name);
        RParameter [] paramz = new RParameter[source.SetMethod.ParametersCount];
        int i = 0;
        foreach (RParameter p in source.SetMethod.GetParameters())
        {
          paramz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        rpd.SetMethod = this.GetMethod(source.SetMethod.Name,GetCorrectRType(source.SetMethod.ReturnType.ReturnType),paramz);
      }
      
      rpd.Name = newName;
      //rpd.PropertyType = GetRType(source.PropertyType,this);
      rpd.PropertyType = GetCorrectRType(source.PropertyType);
      ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo((RMember)rpd,source);
      this.properties.Add(rpd);
      return rpd;
    }

    /// <summary>
    /// 
    /// TODO: What if there's a reference to this property in the code
    /// </summary>
    /// <param name="name"></param>
    public void RemoveProperty(String name) 
    {
      if (this.properties!=null)
      {
        IEnumerator ienum = this.properties.GetEnumerator();
        RPropertyDef rpd = null;
        int pIndex = 0;
        bool found = false;
        while (ienum.MoveNext())
        {
          rpd = (RPropertyDef)ienum.Current;
          if (rpd.Name.Equals(name))
          {
            found = true;
            break;
          }
          pIndex++;
        }
        if (found)
          this.properties.RemoveAt(pIndex);
      }
    }
    #endregion
    
    #region Events management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="eventType"></param>
    /// <returns></returns>
    public REventDef DefineEvent(String name, RType eventType) 
    {
      REventDef red = new REventDef();
      red.DeclaringType = this;
      red.Name = name;
      red.EventType = eventType;
      this.events.Add(red);
      return red;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="original"></param>
    /// <param name="newName"></param>
    /// <returns></returns>
    public REventDef CopyEvent(REvent original, String newName) 
    {
      REventDef red = new REventDef();
      red.DeclaringType = this;
      red.Name = newName;
      //red.EventType = GetRType(original.EventType,this);
      red.EventType = GetCorrectRType(original.EventType);
      
      if (original.AddOnMethod!=null)
      {
        //red.AddOnMethod = CopyMethod((RMethodDef)red.AddOnMethod,red.AddOnMethod.Name);
        RParameter [] paramz = new RParameter[original.AddOnMethod.ParametersCount];
        int i = 0;
        foreach (RParameter p in original.AddOnMethod.GetParameters())
        {
          paramz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        red.AddOnMethod = this.GetMethod(original.AddOnMethod.Name,GetCorrectRType(original.AddOnMethod.ReturnType.ReturnType),paramz);
      }
      
      red.Attributes = original.Attributes;
      red.BindingFlags = original.BindingFlags;
      //red.EventArgsType = GetRType(original.EventArgsType,this);
      red.EventArgsType = GetCorrectRType(original.EventArgsType);
      //red.EventHandlerType = GetRType(original.EventHandlerType,this);
      red.EventHandlerType = GetCorrectRType(original.EventHandlerType);
      //red.EventType = GetRType(original.EventType,this);
      red.EventType = GetCorrectRType(original.EventType);
      red.MemberType = MemberTypes.Event;
      
      if (original.RaiseMethod!=null)
      {
      //    red.RaiseMethod = CopyMethod((RMethodDef)red.RaiseMethod,red.RaiseMethod.Name);
        RParameter [] paramz = new RParameter[original.RaiseMethod.ParametersCount];
        int i = 0;
        foreach (RParameter p in original.RaiseMethod.GetParameters())
        {
          paramz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        red.RaiseMethod = this.GetMethod(original.RaiseMethod.Name,GetCorrectRType(original.RaiseMethod.ReturnType.ReturnType),paramz);
      }
      if (original.RemoveOnMethod!=null)
      {
      //  red.RemoveOnMethod = CopyMethod((RMethodDef)red.RemoveOnMethod,red.RemoveOnMethod.Name);
        RParameter [] paramz = new RParameter[original.RemoveOnMethod.ParametersCount];
        int i = 0;
        foreach (RParameter p in original.RemoveOnMethod.GetParameters())
        {
          paramz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        red.RemoveOnMethod = this.GetMethod(original.RemoveOnMethod.Name,GetCorrectRType(original.RemoveOnMethod.ReturnType.ReturnType),paramz);
      }
      ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo((RMember)red,original);
      this.events.Add(red);
      return red;
    }

    /// <summary>
    /// 
    /// TODO: What if there's a reference in the code to this event??
    /// </summary>
    /// <param name="eventName"></param>
    public void RemoveEvent(String eventName) 
    {
      if (this.events!=null)
      {
        IEnumerator ienum = this.events.GetEnumerator();
        REventDef red = null;
        int eIndex = 0;
        bool found = false;
        while (ienum.MoveNext())
        {
          red = (REventDef)ienum.Current;
          if (red.Name.Equals(eventName))
          {
            found = true;
            break;
          }
          eIndex++;
        }
        if (found)
          this.events.RemoveAt(eIndex);
      }
    }
    #endregion
      
    #region Fields management
    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public RFieldDef DefineField(String name, RType type) 
    {
      RFieldDef rfd = new RFieldDef();
      rfd.DeclaringType = this;
      rfd.Name = name;
      rfd.FieldType = type;
      rfd.MemberType = MemberTypes.Field;
      this.fields.Add(rfd);
      return rfd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="original"></param>
    /// <param name="declaringType"></param>
    /// <returns></returns>
    internal RType GetRType(RType original,RTypeDef declaringType)
    {
      if (original==null)
        return null;
      RType rtr;
      if (original.NameWithNameSpace==declaringType.NameWithNameSpace)
        rtr = declaringType;
      else if (original is RTypeDef)
      {
        rtr = ((RAssemblyDef)declaringType.Assembly).GetType(original.NameWithNameSpace);
        if (rtr==null)
        {
          rtr = new RTypeRef(original.Name,original.NameSpace,(RAssemblyDef)declaringType.Assembly);
          ((RAssemblyDef)declaringType.assembly).AddTypeRef((RTypeRef)rtr);
          ((RTypeRef)rtr).SetAttributes(original.Attributes);
          ((RTypeRef)rtr).SetBaseType(GetRType(original.BaseType,declaringType));
          ((RTypeRef)rtr).SetDeclaringType(GetRType(original.DeclaringType,declaringType));
          ((RTypeRef)rtr).SetAssembly(original.Assembly);
          if (original.IsArray)
          {
            ((RTypeRef)rtr).SetElementType(GetRType(original.ElementType,declaringType));
            ARRAY.ArrayShape arrayShape = new ARRAY.ArrayShape(); 
            arrayShape.LoBounds = original.RArrayShape.LoBounds;
            arrayShape.NumLoBounds = original.RArrayShape.NumLoBounds;
            arrayShape.NumSizes = original.RArrayShape.NumSizes;
            arrayShape.Rank = original.RArrayShape.Rank;
            arrayShape.Sizes = original.RArrayShape.Sizes;
            ((RTypeRef)rtr).SetRArrayShape(arrayShape);
          }
        }
      }
      else
      {
        rtr = ((RAssemblyDef)declaringType.Assembly).GetType(original.NameWithNameSpace);
        if (rtr==null)
        {
          rtr = ((RAssemblyDef)declaringType.Assembly).RModuleDef.GetType(original.NameWithNameSpace);
          if (rtr == null)
          {
            rtr = new RTypeRef(original.Name,original.NameSpace,(RAssemblyDef)declaringType.Assembly);
            ((RAssemblyDef)declaringType.assembly).AddTypeRef((RTypeRef)rtr);
            ((RTypeRef)rtr).SetAttributes(original.Attributes);
            ((RTypeRef)rtr).SetBaseType(GetRType(original.BaseType,declaringType));
            ((RTypeRef)rtr).SetDeclaringType(GetRType(original.DeclaringType,declaringType));
            ((RTypeRef)rtr).SetAssembly(original.Assembly);
            if (original.IsArray)
            {
              ((RTypeRef)rtr).SetElementType(GetRType(original.ElementType,declaringType));
              ARRAY.ArrayShape arrayShape = new ARRAY.ArrayShape(); 
              arrayShape.LoBounds = original.RArrayShape.LoBounds;
              arrayShape.NumLoBounds = original.RArrayShape.NumLoBounds;
              arrayShape.NumSizes = original.RArrayShape.NumSizes;
              arrayShape.Rank = original.RArrayShape.Rank;
              arrayShape.Sizes = original.RArrayShape.Sizes;
              ((RTypeRef)rtr).SetRArrayShape(arrayShape);
            }
          }
        }
      }
      return rtr;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="original"></param>
    /// <param name="newName"></param>
    /// <returns></returns>
    public RFieldDef CopyField(RField original, String newName) 
    {
      RFieldDef rfd = new RFieldDef();
      rfd.DeclaringType = this;
      rfd.Name = newName;
      //rfd.FieldType = GetRType(original.FieldType,this);
      rfd.FieldType = GetCorrectRType(original.FieldType);
      rfd.MemberType = MemberTypes.Field;
      rfd.Attributes = original.Attributes;
      rfd.BindingFlags = original.BindingFlags;
      rfd.Value = original.Value;
      ((RAssemblyDef)this.assembly).RModuleDef.AddCustomAttribsTo((RMember)rfd,original);
      this.fields.Add(rfd);
      return rfd;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    public void RemoveField(String name) 
    {
      if (this.fields!=null)
      {
        IEnumerator ienum = this.fields.GetEnumerator();
        RFieldDef rfd = null;
        int fIndex = 0;
        bool found = false;
        while (ienum.MoveNext())
        {
          rfd = (RFieldDef)ienum.Current;
          if (rfd.Name.Equals(name))
          {
            found = true;
            break;
          }
          fIndex++;
        }
        if (found)
          this.fields.RemoveAt(fIndex);
      }
    }
    #endregion  


    #region Custom Attributes
    /// <summary>
    /// 
    /// </summary>
    /// <param name="attribute"></param>
    public void AddCustomAttributtes(RCustomAttrib attribute) 
    {
      InternalAddCustomAttributtes(attribute);
    }

    /// <summary>
    /// TODO: How should the attribute be specified?
    /// </summary>
    /// <param name="attribute"></param>
    public void RemoveCustomAttribute(RCustomAttrib attribute) 
    {
      InternalRemoveCustomAttribute(attribute);
    }

    #endregion

    /// <summary>
    /// Visits this type.
    /// </summary>
    /// <remarks>
    /// A type has the following subelements: fields, methods, constructors, 
    /// properties and events. The order in which they are visited depends on
    /// the Walker.
    /// </remarks>
    /// <param name="v">The visitor to be used.</param>
    public void Accept(Visitor v) 
    {      
      v.GetWalker().WalkType(this);
    }
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.