From lyxinset.h:

/// Insets
class Inset {
public:
	/** This is not quite the correct place for this enum, but it is
	  better than definitions.h. I think the correct would be to let
	  each subclass of Inset declare its own enum code. Actually the
	  notion of an Inset::Code should be avoided, but I am not sure how
	  this could be done in a cleaner way. */
	enum Code {
		///
		NO_CODE,
		///
		TOC_CODE,  // table of contents
                ...
        };
        ...
}

While shifting things around for gui-indep I tried to fix the
citation combox so that it listed those citations already in use
in the document.  This lead to a big problem in identifying what
sort of inset the Inset* returned by
LyXParagraph::ReturnNextInsetPointer().  If you do as I did
initially and try LyxCode you get a NO_CODE response from the
InsetCommand child of Inset.  Making InsetCommand::LyxCode
virtual isn't sufficient either so we need something a bit better.
As noted above it would be much better to completely eliminate
Inset::Code.   What follows are a couple of suggestions:

1)  protected LString in Inset with name of ultimate derived class.

2)  counted inheritance.  Each derived class gets a unique number
    that represents its equivalent of the enum.

3)  Something better?  I'm sure I read about a neat trick in:
    "Secrets of the C++ Masters" from Micro$oft Press.  That
    would mean we would only ever use Inset* and not have to cast
    to (InsetCitation*) to get it methods.  If I remember correctly
    that trick involved a homogeneous class heirarchy -- every class
    including Inset has every method on offer and reimplements as
    needed.
 
----------------------------------------------------------------------

1)  class Inset {
    protected:          LString real_type;
    public:             LString& isReally() const;
    ...
    };

    LString& Inset::isReally() const
    {  return real_type; } 

    Thus during construction each derived class would assign its
    class name to real_type.  Then with only an Inset* we can tell
    exactly what sort of object we are actually pointing at.

    Advantages:
    Simple, minimal change to interface, we know exactly what we are
    pointing at (the ultimate derived type).

    Disadvantages:
    We only know Inset* and ultimate derived class (possibly great
    grandchild) and nothing in between.  For example,  suppose we
    want to operate on all InsetCommand and its derivatives,  then
    we would have to check each and every derived type separately
    and update the list whenever a new class derived from InsetCommand
    is added.

----------------------------------------------------------------------

2)  class Inset {
    public:             typedef unsigned int classcode;
                        typedef (bool)(*)(classcode const &) SupportCB;
    protected:          static classcode const & newClass();
                        SupportCB supportCB;
    public:             classcode const & Inset();
                        bool supports(classcode const &) const;
                        classcode const & getClasscode() const;
    private:            static classcode const my_classcode = <static_cast>0;
                        // The root class has classcode of zero.
    }

    classcode const & Inset::newClass()
    {
        static classcode counter = 0;
        return ++counter;
    }
    
    bool Inset::supports(classcode a) const
    {
        // if I don't match go immediately to the
        // ultimate derived class -- from which we
        // move back up the class heirarchy.
        return (a == my_classcode) ? true : supportCB(a);
    }

    -------------

    class InsetCommand : public Inset {
    public:            classcode InsetCommand();
                       InsetCommand();
                       static bool supports(classcode) const;
    private:           static classcode my_classcode();
    }

    InsetCommand::InsetCommand()
    {
        supportCB = InsetCommand::supports;
        my_classcode();
    }

    classcode const & InsetCommand::my_classcode()
    {
        static bool done = false;
        static classcode myclasscode;
        if (!done) {
           myclasscode = newCode();
           done = true;
        }
        return myclasscode;
    }

    bool InsetCommand::supports(classcode const & a) const
    {
        // InsetCommand is the first derivative of Inset
        // so we could stop checking here if we new all
        // support checks would start at the base class.
        // Since this is unlikely we will instead add
        // the extra test.
        return (a == my_classcode()) ? true : (a == Inset::getClasscode());
    }

    ---------

    class InsetCitation : public InsetCommand {
    public:            classcode const & InsetCitation();
                       InsetCitation();
                       static bool supports(classcode const &) const;
                       classcode const & getClasscode() const;
    private:           static classcode const & my_classcode();
    }

    InsetCitation::InsetCitation() : InsetCommand("cite")
    {
        supportCB = InsetCitation::supports;
        my_classcode();
    }

    classcode const & InsetCitation::InsetCitation() : InsetCommand("cite")
    {
        supportCB = InsetCitation::supports;
        return my_classcode();
    }

    bool InsetCitation::supports(classcode const & a) const
    {
        return (a == my_classcode()) ? true : InsetCommand::supports(a);
    }

    ///// now a little test.
    Inset* inset = ReturnNextInsetPointer(pos);
    if (inset->supports(InsetCitation()) {
        if (((InsetCitation*)inset)->LyxCode() != Inset::CITATION_CODE) {
            abort();
        }
    }


    Advantages:
    We can identify any level of derived classes from parent to
    great grandchild and so on.  All checking is effectively done using
    types but will work with all compilers (not just those that support
    "typename" or comparison of types).

    Disadvantages:
    A bit complicated but not overly so.  Inserting another level of
    derivation between two classes requires modifying the code of the
    class that has been pushed down a level -- this should be extremely
    rare though.
    Adds a dummy constructor to Inset although this isn't really needed
    and could be left out (if we have an Inset* it must be pointing at
    an object derived from Inset so we don't need to use an Inset()
    test).

-----------------------------------------------------------------------
