protected BaseItem GetItem(SQLiteDataReader reader, string itemType)
        {
            BaseItem item = null;
            try
            {
                item = Serializer.Instantiate<BaseItem>(itemType);
            }
            catch (Exception e)
            {
                Logger.ReportException("Error trying to create instance of type: " + itemType, e);
                return null;
            }
            if (item != null)
            {
                SQLInfo itemSQL;
                lock (ItemSQL)
                {
                    if (!ItemSQL.TryGetValue(item.GetType(), out itemSQL))
                    {
                        itemSQL = new SQLInfo(item);
                        ItemSQL.Add(item.GetType(), itemSQL);
                        //make sure our schema matches
                        itemSQL.FixUpSchema(connection);
                    }
                }
                foreach (var col in itemSQL.AtomicColumns)
                {
                    var data = SQLizer.Extract(reader, col);
                    if (data != null)
                        if (col.MemberType == MemberTypes.Property)
                            col.PropertyInfo.SetValue(item, data, null);
                        else
                            col.FieldInfo.SetValue(item, data);

                }
                // and our list columns
                //this is an optimization - we go get all the list values for this item in one statement
                var listCmd = connection.CreateCommand();
                listCmd.CommandText = "select property, value from list_items where guid = @guid and property != 'ActorName' order by property, sort_order";
                listCmd.AddParam("@guid", item.Id);
                string currentProperty = "";
                System.Collections.IList list = null;
                SQLInfo.ColDef column = new SQLInfo.ColDef();
                using (var listReader = listCmd.ExecuteReader())
                {
                    while (listReader.Read())
                    {
                        string property = listReader.GetString(0);
                        if (property != currentProperty)
                        {
                            //new column...
                            if (list != null)
                            {
                                //fill in the last one
                                if (column.MemberType == MemberTypes.Property)
                                    column.PropertyInfo.SetValue(item, list, null);
                                else
                                    column.FieldInfo.SetValue(item, list);
                            }
                            currentProperty = property;
                            column = itemSQL.Columns.Find(c => c.ColName == property);
                            list = (System.Collections.IList)column.ColType.GetConstructor(new Type[] { }).Invoke(null);
                            //Logger.ReportVerbose("Added list item '" + listReader[0] + "' to " + col.ColName);
                        }
                        try
                        {
                            list.Add(SQLizer.Extract(listReader, new SQLInfo.ColDef() { ColName = "value", ColType = column.InternalType }));
                        }
                        catch (Exception e)
                        {
                            Logger.ReportException("Error adding item to list " + column.ColName + " on item " + item.Name, e);
                        }
                    }
                    if (list != null)
                    {
                        //fill in the last one
                        if (column.MemberType == MemberTypes.Property)
                            column.PropertyInfo.SetValue(item, list, null);
                        else
                            column.FieldInfo.SetValue(item, list);
                    }
                }
            }
            else
            {
                Logger.ReportWarning("Ignoring invalid item " + itemType + ".  Would not instantiate in current environment.");
            }
            return item;
        }
        public IList<Index> RetrieveIndex(Folder folder, string property, Func<string, BaseItem> constructor)
        {
            bool allowEpisodes = property == "Directors" || property == "ProductionYear";
            List<Index> children = new List<Index>();
            var cmd = connection.CreateCommand();

            //we'll build the unknown items now and leave them out of child table
            List<BaseItem> unknownItems = new List<BaseItem>();

            //create a temporary table of this folder's recursive children to use in the retrievals
            string tableName = "["+folder.Id.ToString().Replace("-","")+"_"+property+"]";
            if (connection.TableExists(tableName))
            {
                connection.Exec("delete from " + tableName);
            }
            else
            {
                connection.Exec("create temporary table if not exists " + tableName + "(child)");
            }

            cmd.CommandText = "Insert into "+tableName+" (child) values(@1)";
            var childParam = cmd.Parameters.Add("@1", DbType.Guid);

            var containerList = new Dictionary<Guid, IContainer>();  //initialize this for our index
            SQLInfo.ColDef col = new SQLInfo.ColDef();
            Type currentType = null;

            lock (connection) //can't use delayed writer here - need this table now...
            {
                var tran = connection.BeginTransaction();

                foreach (var child in folder.RecursiveChildren)
                {
                    if (child is IShow && !(child is Season) && ((allowEpisodes && !(child is Series)) || (!allowEpisodes && !(child is Episode))))
                    {
                        if (child is IGroupInIndex)
                        {
                            //add the series object
                            containerList[child.Id] = (child as IGroupInIndex).MainContainer;
                        }

                        //determine if property has any value
                        if (child.GetType() != currentType)
                        {
                            currentType = child.GetType();
                            col = ItemSQL[currentType].Columns.Find(c => c.ColName == property);
                        }
                        object data = null;
                        if (col.MemberType == MemberTypes.Property)
                        {
                            data = col.PropertyInfo.GetValue(child, null);
                        }
                        else if (col.MemberType == MemberTypes.Field)
                        {
                            data = col.FieldInfo.GetValue(child);
                        }
                        if (data != null)
                        {
                            //Logger.ReportVerbose("Adding child " + child.Name + " to temp table");
                            childParam.Value = child.Id;
                            cmd.ExecuteNonQuery();
                        }
                        else
                        {
                            //add to Unknown
                            AddItemToIndex("<Unknown>", unknownItems, containerList, child);
                        }
                    }
                }
                tran.Commit();
            }

            //fill in series
            ContainerDict[tableName] = containerList;
            //create our Unknown Index - if there were any
            if (unknownItems.Count > 0)
                children.Add(new Index(constructor("<Unknown>"), unknownItems));

            //now retrieve the values for the main indicies
            cmd = connection.CreateCommand(); //new command
            property = property == "Actors" ? "ActorName" : property; //re-map to our name entry

            if (col.ListType)
            {
                //need to get values from list table
                cmd.CommandText = "select distinct value from list_items where property = '" + property + "' and guid in (select child from " + tableName + ") order by value";
            }
            else
            {
                cmd.CommandText = "select distinct " + property + " from items where guid in (select child from " + tableName + ") order by "+property;
            }

            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    //Logger.ReportVerbose("Creating index " + reader[0].ToString() + " on " + folder.Name);
                    object value = reader[0];
                    children.Add(new Index(constructor(value.ToString()), tableName, property, value));
                }
            }
            return children;
        }