public void BuildFields(TypeDef typeDef, TypeInfo typeInfo)
    {
      if (typeInfo.IsInterface) {
        var sourceFields = typeInfo.GetInterfaces()
          .SelectMany(i => i.Fields)
          .Where(f => !f.IsPrimaryKey && f.Parent == null);
        foreach (var srcField in sourceFields) {
          if (!typeInfo.Fields.Contains(srcField.Name))
            BuildInheritedField(typeInfo, srcField);
        }
      }
      else {
        var ancestor = typeInfo.GetAncestor();
        if (ancestor != null) {
          foreach (var srcField in ancestor.Fields.Where(f => !f.IsPrimaryKey && f.Parent == null)) {
            FieldDef fieldDef;
            if (typeDef.Fields.TryGetValue(srcField.Name, out fieldDef)) {
              if (fieldDef.UnderlyingProperty == null)
                throw new DomainBuilderException(
                  String.Format(Strings.ExFieldXIsAlreadyDefinedInTypeXOrItsAncestor, fieldDef.Name, typeInfo.Name));
              var getMethod = fieldDef.UnderlyingProperty.GetGetMethod()
                ?? fieldDef.UnderlyingProperty.GetGetMethod(true);
              if ((getMethod.Attributes & MethodAttributes.NewSlot) == MethodAttributes.NewSlot)
                BuildDeclaredField(typeInfo, fieldDef);
              else
                BuildInheritedField(typeInfo, srcField);
            }
            else
              BuildInheritedField(typeInfo, srcField);
          }
          foreach (var pair in ancestor.FieldMap)
            typeInfo.FieldMap.Add(pair.Key, typeInfo.Fields[pair.Value.Name]);
        }
      }

      foreach (var fieldDef in typeDef.Fields) {
        FieldInfo field;
        if (typeInfo.Fields.TryGetValue(fieldDef.Name, out field)) {
          if (field.ValueType!=fieldDef.ValueType)
            throw new DomainBuilderException(
              String.Format(Strings.ExFieldXIsAlreadyDefinedInTypeXOrItsAncestor, fieldDef.Name, typeInfo.Name));
        }
        else
          BuildDeclaredField(typeInfo, fieldDef);
      }
      typeInfo.Columns.AddRange(typeInfo.Fields.Where(f => f.Column!=null).Select(f => f.Column));

      if (typeInfo.IsEntity && !IsAuxiliaryType(typeInfo)) {
        foreach (var @interface in typeInfo.GetInterfaces())
          BuildFieldMap(@interface, typeInfo);
      }
    }
        /// <summary>
        /// Finds the associations for the specified <see cref="TypeInfo"/>.
        /// </summary>
        /// <param name="type"><see cref="TypeInfo"/> to find associations for.</param>
        /// <returns></returns>
        public IEnumerable <AssociationInfo> Find(TypeInfo type)
        {
            var candidates = new HashSet <TypeInfo>(type.GetAncestors());

            candidates.UnionWith(type.GetInterfaces(true));
            candidates.Add(type);
            return(this.Where(a => (candidates.Contains(a.TargetType) || candidates.Contains(a.OwnerType))));
        }
        /// <summary>
        /// Finds the associations for the specified <see cref="TypeInfo"/>.
        /// </summary>
        /// <param name="type"><see cref="TypeInfo"/> to find outgoing associations for.</param>
        /// <param name="target">if set to <see langword="true"/> then only target associations will be returned; otherwise only owner associations.</param>
        /// <returns></returns>
        public IEnumerable <AssociationInfo> Find(TypeInfo type, bool target)
        {
            var candidates = new HashSet <TypeInfo>(type.GetAncestors());

            candidates.UnionWith(type.GetInterfaces(true));
            candidates.Add(type);

            var filter = target ? (Func <AssociationInfo, TypeInfo>)(a => a.TargetType) : (a => a.OwnerType);

            return(this.Where(a => candidates.Contains(filter(a))));
        }