context: /* This file is part of the db4o object database http://www.db4o.com
  
  Copyright (C) 2004 - 2011  Versant Corporation http://www.versant.com
  
  db4o is free software; you can redistribute it and/or modify it under
  the terms of version 3 of the GNU General Public License as published
  by the Free Software Foundation.
  
  db4o is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
  You should have received a copy of the GNU General Public License along
  with this program.  If not, see http://www.gnu.org/licenses/. */
  
  using Db4objects.Db4o.Foundation;
  
  namespace Db4objects.Db4o.Reflect.Generic
  {
      /// <exclude></exclude>
      public class GenericClass : IReflectClass, IDeepClone
      {
          private static readonly GenericField[] NoFields = new GenericField[0];
          private readonly IReflectClass _delegate;
          private readonly int _hashCode;
          private readonly string _name;
          private readonly GenericReflector _reflector;
          private GenericClass _array;
          protected IGenericConverter _converter;
          private int _declaredFieldCount = -1;
          private int _fieldCount = -1;
          private GenericField[] _fields = NoFields;
          private int _isCollection;
          private bool _isPrimitive;
          private GenericClass _superclass;
  
          public GenericClass(GenericReflector reflector, IReflectClass delegateClass, string
              name, GenericClass superclass)
          {
              _reflector = reflector;
              _delegate = delegateClass;
              _name = name;
              _superclass = superclass;
              _hashCode = _name.GetHashCode();
          }
  
          public virtual object DeepClone(object obj)
          {
              var reflector = (GenericReflector) obj;
              GenericClass superClass = null;
              if (_superclass != null)
              {
                  _superclass = (GenericClass) reflector.ForName(_superclass
                      .GetName());
              }
              var ret = new GenericClass
                  (reflector, _delegate, _name, superClass);
              var fields = new GenericField[_fields.Length];
              for (var i = 0; i < fields.Length; i++)
              {
                  fields[i] = (GenericField) _fields[i].DeepClone(reflector);
              }
              ret.InitFields(fields);
              return ret;
          }
  
          public virtual IReflectClass GetComponentType()
          {
              if (_delegate != null)
              {
                  return _delegate.GetComponentType();
              }
              return null;
          }
  
          // TODO: consider that classes may have two fields of
          // the same name after refactoring.
          public virtual IReflectField GetDeclaredField(string name)
          {
              if (_delegate != null)
              {
                  return _delegate.GetDeclaredField(name);
              }
              for (var i = 0; i < _fields.Length; i++)
              {
                  if (_fields[i].GetName().Equals(name))
                  {
                      return _fields[i];
                  }
              }
              return null;
          }
  
          public virtual IReflectField[] GetDeclaredFields()
          {
              if (_delegate != null)
              {
                  return _delegate.GetDeclaredFields();
              }
              return _fields;
          }
  
          public virtual IReflectClass GetDelegate()
          {
              if (_delegate != null)
              {
                  return _delegate;
              }
              return this;
          }
  
          public virtual IReflectMethod GetMethod(string methodName, IReflectClass[] paramClasses
              )
          {
              if (_delegate != null)
              {
                  return _delegate.GetMethod(methodName, paramClasses);
              }
              return null;
          }
  
          public virtual string GetName()
          {
              return _name;
          }
  
          public virtual IReflectClass GetSuperclass()
          {
              if (_superclass != null)
              {
                  return _superclass;
              }
              if (_delegate == null)
              {
                  return _reflector.ForClass(typeof (object));
              }
              var delegateSuperclass = _delegate.GetSuperclass();
              if (delegateSuperclass != null)
              {
                  _superclass = _reflector.EnsureDelegate(delegateSuperclass);
              }
              return _superclass;
          }
  
          // TODO: Consider: Will this method still be necessary 
          // once constructor logic is pushed into the reflectors?
          public virtual bool IsAbstract()
          {
              if (_delegate != null)
              {
                  return _delegate.IsAbstract();
              }
              return false;
          }
  
          public virtual bool IsArray()
          {
              if (_delegate != null)
              {
                  return _delegate.IsArray();
              }
              return false;
          }
  
          public virtual bool IsAssignableFrom(IReflectClass subclassCandidate)
          {
              if (subclassCandidate == null)
              {
                  return false;
              }
              if (Equals(subclassCandidate))
              {
                  return true;
              }
              if (_delegate != null)
              {
                  if (subclassCandidate is GenericClass)
                  {
                      subclassCandidate = ((GenericClass) subclassCandidate
                          ).GetDelegate();
                  }
                  return _delegate.IsAssignableFrom(subclassCandidate);
              }
              if (!(subclassCandidate is GenericClass))
              {
                  return false;
              }
              return IsAssignableFrom(subclassCandidate.GetSuperclass());
          }
  
          public virtual bool IsCollection()
          {
              if (_isCollection == 1)
              {
                  return true;
              }
              if (_isCollection == -1)
              {
                  return false;
              }
              _isCollection = _reflector.IsCollection(this) ? 1 : -1;
              return IsCollection();
          }
  
          public virtual bool IsInstance(object candidate)
          {
              if (_delegate != null)
              {
                  return _delegate.IsInstance(candidate);
              }
              if (!(candidate is GenericObject))
              {
                  return false;
              }
              return IsAssignableFrom(((GenericObject) candidate)._class);
          }
  
          public virtual bool IsInterface()
          {
              if (_delegate != null)
              {
                  return _delegate.IsInterface();
              }
              return false;
          }
  
          public virtual bool IsPrimitive()
          {
              if (_delegate != null)
              {
                  return _delegate.IsPrimitive();
              }
              return _isPrimitive;
          }
  
          public virtual object NewInstance()
          {
              if (_delegate != null)
              {
                  return _delegate.NewInstance();
              }
              return new GenericObject(this);
          }
  
          public virtual IReflector Reflector()
          {
              if (_delegate != null)
              {
                  return _delegate.Reflector();
              }
              return _reflector;
          }
  
          public virtual bool EnsureCanBeInstantiated()
          {
              if (_delegate != null)
              {
                  return _delegate.EnsureCanBeInstantiated();
              }
              return true;
          }
  
          public virtual object NullValue()
          {
              if (_delegate == null)
              {
                  return null;
              }
              return _delegate.NullValue();
          }
  
          public virtual bool IsImmutable()
          {
              if (_delegate != null)
              {
                  return _delegate.IsImmutable();
              }
              return IsPrimitive();
          }
  
          public virtual GenericClass ArrayClass()
          {
              if (_array != null)
              {
                  return _array;
              }
              _array = new GenericArrayClass(_reflector, this, _name, _superclass);
              return _array;
          }
  
          public override bool Equals(object obj)
          {
  
gt:             if (this == obj)