internal static List <RowPropertyWrapper> GetWrappers(string[] columns, Type instanceType, bool ignoreWritable, Encoding hardwordEncoding)
        {
            var result = instanceType.GetProperties().Aggregate(new
            {
                List    = new List <RowPropertyWrapper>(),
                Columns = columns
            },
                                                                (seed, property) =>
            {
                if (ignoreWritable || property.CanWrite) // property must can be written
                {
                    var columnName = columns.FirstOrDefault(r => string.Equals(r, property.Name, StringComparison.OrdinalIgnoreCase));
                    if (columnName != null) // must find in columns
                    {
                        var wrapper = new RowPropertyWrapper
                        {
                            Name         = columnName,
                            PropertyInfo = property,
                        };
                        var attribute = HardWordManager.Get(property);
                        if (attribute != null)
                        {
                            wrapper.Encoding = hardwordEncoding ?? attribute.Encoding;
                        }
                        seed.List.Add(wrapper);
                    }
                }
                return(seed);
            },
                                                                seed => seed.List);

            return(result);
        }
        internal static IList InternalResultList(IAncestorResult result, Type[] dataTypes, Delegate objectFactory, bool firstOnly, ResultListMode mode, Encoding hardwordEncoding)
        {
            var   baseTupleType = Type.GetType("System.Tuple`" + dataTypes.Length);
            var   tupleType     = baseTupleType.MakeGenericType(dataTypes);
            IList list          = Activator.CreateInstance(typeof(List <>).MakeGenericType(tupleType)) as IList;

            switch (result.DataType)
            {
            case AncestorResultDataType.List:
                if (result.DataList.Count > 0)     // if has item than find anonymouse creation info
                {
                    var hdMap = new Dictionary <Type, IDictionary <PropertyInfo, HardWordAttribute> >();
                    foreach (var dataType in dataTypes)
                    {
                        var hds = HardWordManager.Get(dataType);
                        hdMap.Add(dataType, hds);
                    }
                    var map      = new Dictionary <Type, Dictionary <PropertyInfo, Tuple <PropertyInfo, Func <object, object> > > >();
                    var itemList = CastToItem(result.DataList,
                                              o =>
                    {
                        var args = new object[dataTypes.Length];
                        for (var i = 0; i < dataTypes.Length; i++)
                        {
                            Dictionary <PropertyInfo, Tuple <PropertyInfo, Func <object, object> > > propertyMap;
                            map.TryGetValue(dataTypes[i], out propertyMap);
                            var flgPropertyMapEmpty = propertyMap == null;
                            IDictionary <PropertyInfo, HardWordAttribute> hds;
                            hdMap.TryGetValue(dataTypes[i], out hds);
                            var ins = Activator.CreateInstance(dataTypes[i]);
                            DeepCloneItem(o, ins, ref propertyMap, hds, mode, hardwordEncoding);
                            if (flgPropertyMapEmpty)
                            {
                                map.Add(dataTypes[i], propertyMap);
                            }
                            args[i] = ins;
                        }
                        return(Activator.CreateInstance(tupleType, args));
                    });
                    foreach (var item in itemList)
                    {
                        list.Add(item);
                        if (firstOnly)
                        {
                            break;
                        }
                    }
                }
                break;

            case AncestorResultDataType.DataTable:
                var rowObjectFactory = objectFactory as Func <DataRow, object>;
                var listArray        = new IEnumerable[dataTypes.Length];
                for (var i = 0; i < dataTypes.Length; i++)
                {
                    listArray[i] = TableToCollection(result.ReturnDataTable, dataTypes[i], rowObjectFactory, firstOnly, mode, hardwordEncoding);
                }
                var enumerators = listArray.Select(r => r.GetEnumerator()).ToArray();

                while (enumerators.All(r => r.MoveNext()))
                {
                    var listItem = Activator.CreateInstance(tupleType, enumerators.Select(r => r.Current).ToArray());
                    list.Add(listItem);
                }
                break;
            }
            return(list);
        }
        internal static IList InternalResultList(IAncestorResult result, Type dataType, Delegate objectFactory, bool firstOnly, ResultListMode mode, Encoding hardwordEncoding)
        {
            IList list    = Activator.CreateInstance(typeof(List <>).MakeGenericType(dataType)) as IList;
            var   hds     = HardWordManager.Get(dataType);
            var   factory = objectFactory as Func <object>;

            switch (result.DataType)
            {
            case AncestorResultDataType.List:
                if (InternalHelper.IsAnonymousType(dataType) && factory != null)
                {
                    if (result.DataList.Count > 0)     // if has item than find anonymouse creation info
                    {
                        var targetProperties = dataType.GetProperties();
                        var sourceProperties = result.DataList[0].GetType().GetProperties();
                        var resolvers        = new List <Func <object, object> >();
                        foreach (var targetProperty in targetProperties)
                        {
                            var property = sourceProperties.FirstOrDefault(p => p.Name == targetProperty.Name && p.PropertyType == targetProperty.PropertyType);
                            if (property != null)
                            {
                                resolvers.Add(o => property.GetValue(o, null));
                            }
                            else if (targetProperty.PropertyType.IsValueType)
                            {
                                resolvers.Add(o => Activator.CreateInstance(targetProperty.PropertyType));
                            }
                            else
                            {
                                resolvers.Add(o => null);
                            }
                        }
                        foreach (var item in CloneByCunstructure(result.DataList, dataType, resolvers))
                        {
                            list.Add(item);
                            if (firstOnly)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    Dictionary <PropertyInfo, Tuple <PropertyInfo, Func <object, object> > > propertyMap = null;
                    if (factory == null)
                    {
                        factory = () => Activator.CreateInstance(dataType);
                    }
                    foreach (var item in CastToItem(result.DataList, o => DeepCloneItem(o, factory(), ref propertyMap, hds, mode, hardwordEncoding)))
                    {
                        list.Add(item);
                        if (firstOnly)
                        {
                            break;
                        }
                    }
                }
                break;

            case AncestorResultDataType.DataTable:
                var rowObjectFactory = objectFactory as Func <DataRow, object>;
                if (rowObjectFactory == null && factory != null)
                {
                    rowObjectFactory = row => factory();
                }
                foreach (var item in TableToCollection(result.ReturnDataTable, dataType, rowObjectFactory, firstOnly, mode, hardwordEncoding))
                {
                    list.Add(item);
                }
                break;
            }
            return(list);
        }