internal void Execute(params object[] args)
        {
            string @class;
            if (!InstanceTable.ContainsKey((@class = this.ValidateArgs(args))))
            {
                lock (InstanceTable.SyncRoot)
                {
                    if (!InstanceTable.ContainsKey(@class))
                    {
                        using (var writer = new StringWriter(CultureInfo.InvariantCulture))
                        using (var reader = this.DataProvider.ExecuteReader(this.CommandBehavior))
                        {
                            var builder = new ClassBuilder(Namespace, @class, MemberAttributes.Static);

                            AddExternalAssemblyReferences(builder, args);

                            builder.AddImport("System");
                            builder.AddImport("System.Collections");
                            builder.AddImport("System.Data");
                            builder.AddImport("System.Globalization");

                            var method = builder.CreateMethod(MethodName, typeof(bool), MemberAttributes.Static);
                            builder.AddParameter(method, typeof(DbDataReader), "reader");
                            builder.AddParameter(method, typeof(object[]), "args");

                            var counter = 0;
                            writer.WriteLine("// reads data from \"{0}\" procedure.", this.DataProvider.CommandText);
                            writer.WriteLine();
                            do
                            {
                                if ((args.Length - 1) < counter) continue;

                                var schemaTable = reader.GetSchemaTable();
                                var argType = args[counter].GetType();
                                string instanceName = null;

                                if (args[counter] is IEnumerable)
                                {
                                    var genericType = argType.GetGenericArguments()[0];

                                    writer.WriteLine("IList list{0} = args[{1}] as IList;", counter, counter);
                                    writer.WriteLine("");
                                    writer.WriteLine("while (reader.Read())");
                                    writer.WriteLine("{");

                                    if (IsNativeType(genericType))
                                    {
                                        WriteNativeDataTypeReaderLogic(writer, schemaTable, genericType);
                                    }
                                    else
                                    {
                                        instanceName = ValidateInstanceName(genericType);
                                        writer.WriteLine("{0} {1} = new {2}();", instanceName, ItemName, instanceName);
                                        WriteCommonDataReaderLogic(writer, schemaTable, genericType, null, null, ItemName);
                                    }
                                    writer.WriteLine("list{0}.Add(item);", counter);
                                    writer.WriteLine("}");
                                }
                                else
                                {
                                    instanceName = ValidateInstanceName(argType);

                                    writer.WriteLine("if (reader.Read())");
                                    writer.WriteLine("{");
                                    writer.WriteLine("{0} {1} = ({2})args[{3}];", instanceName, ItemName, instanceName, counter);

                                    WriteCommonDataReaderLogic(writer, schemaTable, argType, null, null, ItemName);

                                    writer.WriteLine("}");
                                }
                                if ((counter + 1) != args.Length)
                                {
                                    writer.WriteLine("if (!reader.NextResult())");
                                    writer.WriteLine("{");
                                    writer.WriteLine("return true;");
                                    writer.WriteLine("}");
                                }
                                counter++;
                            }
                            while (reader.NextResult());

                            writer.WriteLine("return true;");

                            builder.AddMethodBody(method, writer.ToString());

#if DEBUG
                            using (var writer2 = new StringWriter(CultureInfo.InvariantCulture))
                            {
                                builder.Write(writer2);
                                System.Diagnostics.Debug.WriteLine(writer2.ToString());
                            }
#endif
                            object instance;
                            if ((instance = builder.GetInstance()) == null)
                            {
                                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "ClassBuilder failed to create the instance for a stored procedure {0}.", this.DataProvider.CommandText));
                            }
                            InstanceTable.Add(@class, instance);
                        }
                    }
                }
            }
            this.Execute(@class, args);
        }
 private static void AddExternalAssemblyReferences(ClassBuilder builder, object[] args)
 {
     builder.AddReference(Assembly.GetExecutingAssembly());
     foreach (var item in args)
     {
         var type = item.GetType();
         if (IsNativeType(type)) continue;
         if (item is IEnumerable)
         {
             type = type.GetGenericArguments()[0];
         }
         builder.AddReference(Assembly.GetAssembly(type));
     }
 }