+ void add_source(CollectionSource &);
+};
+
+template<typename T>
+class Collection::ItemLoader<T, false>: public T::Loader
+{
+public:
+ ItemLoader(T &o, Collection &):
+ T::Loader(o)
+ { }
+};
+
+template<typename T>
+class Collection::ItemLoader<T, true>: public T::Loader
+{
+public:
+ ItemLoader(T &o, Collection &c):
+ T::Loader(o, dynamic_cast<typename T::Loader::Collection &>(c))
+ { }
+};
+
+
+class CollectionItemTypeBase
+{
+protected:
+ struct TagBase
+ {
+ virtual ~TagBase() { }
+ };
+
+ template<typename T>
+ struct Tag: TagBase
+ { };
+
+ std::string kwd;
+ std::vector<std::string> suffixes;
+ TagBase *tag;
+
+ CollectionItemTypeBase();
+public:
+ virtual ~CollectionItemTypeBase();
+
+ void set_keyword(const std::string &);
+ const std::string &get_keyword() const { return kwd; }
+ void add_suffix(const std::string &);
+ bool match_name(const std::string &) const;
+ virtual void add_to_loader(Collection::Loader &) const = 0;
+ virtual bool can_create() const = 0;
+ virtual void create_item(Collection &, const std::string &) const = 0;
+ virtual void load_item(Collection &, Parser &, const std::string &) const = 0;
+
+ template<typename T>
+ bool check_type() const
+ { return dynamic_cast<Tag<T> *>(tag); }
+};
+
+
+/**
+Describes a type of item that can be loaded by a Collection. These are created
+by Collection::add_type.
+*/
+template<typename T>
+class CollectionItemType: public CollectionItemTypeBase
+{
+private:
+ struct CreatorBase
+ {
+ virtual ~CreatorBase() { }
+
+ virtual T *create(Collection &, const std::string &) const = 0;
+ };
+
+ template<typename C>
+ struct Creator: CreatorBase
+ {
+ typedef T *(C::*FuncPtr)(const std::string &);
+
+ FuncPtr func;
+
+ Creator(FuncPtr f): func(f) { }
+
+ virtual T *create(Collection &coll, const std::string &name) const
+ { return (static_cast<C &>(coll).*func)(name); }
+ };
+
+ struct StoreBase
+ {
+ virtual ~StoreBase() { }
+
+ virtual void store(Collection &, const std::string &, T *) = 0;
+
+ virtual void add_to_loader(Collection::Loader &, const std::string &) = 0;
+ };
+
+ template<typename S>
+ struct Store: StoreBase
+ {
+ virtual void store(Collection &coll, const std::string &name, T *obj)
+ { coll.add(name, static_cast<S *>(obj)); }
+
+ virtual void add_to_loader(Collection::Loader &loader, const std::string &kwd)
+ { loader.add(kwd, &Collection::Loader::item<T, S>); }
+ };
+
+ CreatorBase *creat;
+ StoreBase *store;
+
+public:
+ CollectionItemType():
+ creat(0), store(new Store<T>)
+ { tag = new Tag<T>; }
+
+ ~CollectionItemType()
+ {
+ delete creat;
+ delete store;
+ }