/** @page libsbml-extension-support-classes Summary of extension support classes

This section describes the summary of extension support 
classes which are used for implementing a package extension in libSBML-5.

<center>
<table border="0">

<tr><td>
<a href="#Overview">1. Overview of extension support classes </a>
</td></tr>

<tr><td>
<a href="#ExtensionSupport"> 2. Extension support classes </a>
<ol> 
<li> <a href="#SBMLExtension"> SBMLExtension class</a> </li>
<li> <a href="#SBasePlugin"> SBasePlugin class</a> </li>
<li> <a href="#SBaseExtensionPoint"> SBaseExtensionPoint</a>  </li>
<li> <a href="#SBasePluginCreatorBase"> SBasePluginCreator</a> </li>
<li> <a href="#SBMLExtensionNamespaces"> SBMLExtensionNamespaces</a> </li>
<li> <a href="#SBMLExtensionRegistry"> SBMLExtensionRegistry</a> </li>
<li> <a href="#SBMLExtensionRegister"> SBMLExtensionRegister</a>  </li>
<li> <a href="#SBMLExtensionException"> SBMLExtensionException</a> </li>
</ol>
</td></tr>
</table>
</center>

<h2><a class="anchor" name="Overview">1. Overview of extension support classes </a></h2>

The package architecture of SBML Level 3 enables it to develop a package extension 
which defines additional attributes and/or elements to each pre-defined element 
in SBML Level 3 Core package.

<p>
In libSBML-5, extension support classes are provieded to enable developers
to implement their package extensions. 
Basically, each package extension consists of two set of components; one is
classes which are extended or instantiated from the extension support classes, 
and other is SBase extended classes which represent elements defined in
each package extension (e.g., &lt;listOfLayouts&gt;, &lt;layout&gt; and etc. in
layout package).
In this section, the summary of the extension support classes are described.

<p>
Some of the support classes need to be extended (i.e., implementing a subclass)
or instantiated (i.e., instantiating a class from a template class) to implement 
each package specific properties/features.
For example, basically, the following classes need to be extended by package developers
for each package extension:

<ul> 
<li> <a href="#SBasePlugin"> SBasePlugin </a> is a class plugged in a pre-defined 
element to be extended. It contains additional attributes and/or elements of a package 
extension which are directly contained by some pre-defined element to be extended, and 
it provides functions for accessing the additional attributes and/or elements.
</li>
<li> <a href="#SBMLExtension"> SBMLExtension </a> class is a core component of a package
extension. It provides functions for getting common attributes of package extension,
and functions for initializing/registering the package when the library of the package is loaded.
</li>
</ul>

Also, the following template classes need to be instantiated by package developers
for each package extension:

<ul> 
<li> <a href="#SBasePluginCreatorBase"> SBasePluginCreator</a> is a factory class which creates
an SBasePlugin extended object.</li>
<li> <a href="#SBMLExtensionNamespaces">SBMLExtensionNamespaces</a> is an SBMLNamespaces extended
template class which is specific to each package extension. It provides information of the package version, 
and used when creating an SBase extended objects of the package extension.
</li>
</ul>

The following classes don't need to be extended or instantiated:

<ul> 
<li> <a href="#SBaseExtensionPoint"> SBaseExtensionPoint</a> class represents an element to be extended 
(extension point).

</li>
<li> <a href="#SBMLExtensionRegistry"> SBMLExtensionRegistry</a> class is a central registry class. 
Each package extension is registered to this registry class.
</li>

<li> <a href="#SBMLExtensionRegister"> SBMLExtensionRegister</a> class is a simple register class.
It is used to automatically register each package extension to the SBMLExtensionRegistry class 
when each library is loaded.
</li>

<li> <a href="#SBMLExtensionException"> SBMLExtensionException</a> class is a exception class 
which can be thrown when an exception about pacakge extension occurs.
</li>
</ul>

<h2><a class="anchor" name="ExtensionSupport">2. Extension support classes </a></h2>

<h3><a class="anchor" name="SBMLExtension">1. SBMLExtension class</a></h3>

<a href="class_s_b_m_l_extension.html"> SBMLExtension </a> class (abstract class) is a core 
component of each package extension which needs to be extended by package developers. 
The class provides functions for getting common attributes of package extension (e.g. package name, 
package version, and etc.), functions for adding (registering) each instantiated SBasePluginCreator 
object, and a static function (defined in each SBMLExtension extended class) for 
initializing/registering the exntension package when the library of the package is loaded.

Package developer must implement an SBMLExtension extended class (e.g. LayoutExtension
class is implemented for layout extension), and the following functions/variables must be implemented 
in the derived class: 
  
  <ol>
    <li> <p>common static functions such as:</p>
        <ul>
          <li> <code>const std::string getPackageName()</code>, the name (label) of package
          <li> <code>const unsigned int getDefaultLevel()</code>, default level
          <li> <code>const unsigned int getDefaultVersion()</code>, default version,
          <li> <code>const unsigned int getDefaultPackageVersion()</code>, default package_version, 
          <li> <code>const std::string getXMLnsL3V1V1()</code>, URI of package versions,
        </ul>
    </li>

    <li>
      <p> pure virtual functions for getting common attributes such as:</p>
      <ul>
       <li> <code>virtual const std::string& getName () const =0</code>. This function returns the name of the package (e.g., "layout", "multi"). </li>
       <li> <code>virtual unsigned int getLevel (const std::string &uri) const =0</code>. This function returns the SBML level with the given URI of this package. </li>
       <li> <code>virtual unsigned int getVersion (const std::string &uri) const =0</code>. This function returns the SBML version with the given URI of this package. </li>
       <li> <code>virtual unsigned int getPackageVersion (const std::string &uri) const =0</code>. This function returns the package version with the given URI of this package.</li>
       <li> <code>virtual const char*  getStringFromTypeCode (int typeCode) const =0</code>. This function takes a type code of this package and returns a string representing the code.</li>
       <li> <code>virtual SBMLNamespaces* getSBMLExtensionNamespaces (const std::string &uri) const =0</code>. This function returns an SBMLNamespaces derived object (e.g., SBMLExtensionNamespaces&lt;LayoutExtension&gt; whose alias type is LayoutPkgNamespaces) corresponding to the given uri. </li>
      </ul>
    </li>

    <li>
     <p>
     <code>static int init() </code> function which initializes and registers the package 
     extension to the <a href="class_s_b_m_l_extension_registry.html"> SBMLExtensionRegistry </a> 
     class (init() function is implemented in each SBMLExtension derived class implemented by package 
     developers.)
     </p>
    </li>
  </ol>	

<p> SBMLExtension class also provides the following functions for adding/getting SBasePluginCreatorBase derived objects :</p>
  
   <ul>
     <li> <code>int addSBasePluginCreator(const SBasePluginCreatorBase* sbaseExt)</code>. This function adds the given SBasePluginCreatorBase object to this package extension. </li>
     <li> <code>SBasePluginCreatorBase* getSBasePluginCreator(const SBaseExtensionPoint& extPoint)</code>. This function returns an SBasePluginCreatorBase object of this package extension bound to the given extension point.</li>
     <li> <code>SBasePluginCreatorBase* getSBasePluginCreator(unsigned int i)</code>. This function returns an SBasePluginCreatorBase object of this package extension with the given index.</li>
   </ul>

These functions are used for initializing each package extension in the <code> init() </code> function.

The more detailed information (what virtual functions must be overridden, what static
data members must be implemented and etc.) is described in the
<a href="_s_b_m_l_extension_8h-source.html">SBMLExtension </a> class.


<h3><a class="anchor" name="SBasePlugin">2. SBasePlugin class</a></h3>

<p>
Additional attributes and/or elements of a package extension which are directly 
contained by some pre-defined element are contained/accessed by <a href="#SBasePlugin"> 
SBasePlugin </a> class which is extended by package developers for each extension point.
The extension point, which represents an element to be extended, is identified by a 
combination of a pakcage name and a typecode of the element, and is represented by
<a href="#SBaseExtensionPoint">SBaseExtensionPoint</a> class.
</p>

<p>
For example, the layout extension defines <em>&lt;listOfLayouts&gt;</em> element which is 
directly contained in <em>&lt;model&gt;</em> element of the core package. 
In the layout package (provided as one of example packages in libSBML-5), the additional 
element for the model element is implemented as ListOfLayouts class (an SBase derived class) and 
the object is contained/accessed by a LayoutModelPlugin class (an SBasePlugin derived class). 
</p>

<p>
 SBasePlugin class defines basic virtual functions for reading/writing/checking 
 additional attributes and/or top-level elements which should or must be overridden by 
 subclasses like SBase class and its derived classes.
</p>
   
<p>
   Package developers must implement an SBasePlugin exntended class for 
   each element to be extended (e.g. SBMLDocument, Model, ...) in which additional 
   attributes and/or top-level elements of the package extension are directly contained.
</p>

   To implement reading/writing functions for attributes and/or top-level 
   elements of the SBsaePlugin extended class, package developers should or must
   override the corresponding virtual functions below provided in the 
   <a href="_s_base_plugin_8h-source.html"> SBasePlugin </a> class:

   <ul>
     <li> <p>reading elements:</p>
       <ol>
         <li> <code>virtual SBase* createObject (XMLInputStream& stream) </code></li>
         <li> <code>virtual bool readOtherXML (SBase* parentObject, XMLInputStream& stream)</code></li>
       </ol>
     </li>
     <li> <p>reading attributes:</p>
       <ol>
         <li><code>virtual void addExpectedAttributes(ExpectedAttributes& attributes) </code></li>
         <li><code>virtual void readAttributes (const XMLAttributes& attributes, const ExpectedAttributes& expectedAttributes)</code></li>
       </ol>
     </li>
     <li> <p>writing elements:</p>
       <ol>
         <li><code>virtual void writeElements (XMLOutputStream& stream) const </code></li>
       </ol>
     </li>
     <li> <p>writing attributes:</p>
       <ol>
        <li><code>virtual void writeAttributes (XMLOutputStream& stream) const </code></li>
        <li><code>virtual void writeXMLNS (XMLOutputStream& stream) const </code></li>
       </ol>
     </li>

     <li> <p>checking elements:</p>
       <ol>
         <li><code>virtual bool hasRequiredElements() const </code></li>
       </ol>
     </li>

     <li> <p>checking attributes:</p>
       <ol>
         <li><code>virtual bool hasRequiredAttributes() const </code></li>
       </ol>
     </li>
   </ul>
   
<p>
   To implement package-specific creating/getting/manipulating functions of the 
   SBasePlugin derived class (e.g., getListOfLayouts(), createLyout(), getLayout(), 
   and etc are implemented in LayoutModelPlugin class of the layout package), package 
   developers must newly implement such functions (as they like) in the derived class.
</p>

<p>
   SBasePlugin class defines other virtual functions of internal implementations
   such as:
   
   <ul>
    <li><code> virtual void setSBMLDocument(SBMLDocument* d) </code>,
    <li><code> virtual void connectToParent(SBase *sbase) </code>, 
    <li><code> virtual void enablePackageInternal(const std::string& pkgURI, const std::string& pkgPrefix, bool flag) </code>
   </ul>

   These functions should or must be overridden by subclasses in which one or
   more top-level elements are defined.
</p>

<p>
   For example, the following three SBasePlugin extended classes are implemented in 
   the layout extension:
</p>

<ol>

  <li> <p><a href="class_s_b_m_l_document_plugin.html"> SBMLDocumentPlugin </a> class for SBMLDocument element</p>

    <ul>
         <li> <em> required </em> attribute is added to SBMLDocument object.
         </li>
    </ul>

<p>
(<a href="class_s_b_m_l_document_plugin.html"> SBMLDocumentPlugin </a> class is a common SBasePlugin 
extended class for SBMLDocument class. Package developers can use this class as-is if no additional 
elements/attributes (except for <em> required </em> attribute) is needed for the SBMLDocument class 
in their packages, otherwise package developers must implement a new SBMLDocumentPlugin derived class.)
</p>

  </li>

  <li> <p>LayoutModelPlugin class for Model element</p>
    <ul>
       <li> &lt;listOfLayouts&gt; element is added to Model object.
       </li>

       <li> <p>
            The following virtual functions for reading/writing/checking
            are overridden: (type of arguments and return values are omitted)
            </p>
           <ul>
              <li> <code> createObject() </code> : (read elements)
              </li>
              <li> <code> readOtherXML() </code> : (read elements in annotation of SBML L2)
              </li>
              <li> <code> writeElements() </code> : (write elements)
              </li>
           </ul>
       </li>

        <li> <p>
             The following virtual functions of internal implementations
             are overridden: (type of arguments and return values are omitted)
            </p>  
            <ul>
              <li> <code> setSBMLDocument() </code> 
              </li>
              <li> <code> connectToParent() </code>
              </li>
              <li> <code> enablePackageInternal() </code>
              </li>
            </ul>
        </li>


        <li> <p>
             The following creating/getting/manipulating functions are newly 
             implemented: (type of arguments and return values are omitted)
            </p>
            <ul>
              <li> <code> getListOfLayouts() </code>
              </li>
              <li> <code> getLayout ()  </code>
              </li>
              <li> <code> addLayout() </code>
              </li>
              <li> <code> createLayout() </code>
              </li>
              <li> <code> removeLayout() </code>
              </li>	   
              <li> <code> getNumLayouts() </code>
              </li>
           </ul>
        </li>
  
    </ul>
  </li>
	   
  <li> <p>LayoutSpeciesReferencePlugin class for SpeciesReference element (used only for SBML L2V1) </p>

      <ul>
        <li>
         <em> id </em> attribute is internally added to SpeciesReference object
          only for SBML L2V1 
        </li>

        <li>
         The following virtual functions for reading/writing/checking
          are overridden: (type of arguments and return values are omitted)
        </li>

         <ul>
           <li>
           <code> readOtherXML() </code>
           </li>
           <li>
           <code> writeAttributes() </code>
           </li>
         </ul>
       </ul>
    </li>
</ol>

<h3><a class="anchor" name="SBaseExtensionPoint">3. SBaseExtensionPoint class</a></h3>

SBaseExtensionPoint represents an element to be extended (extension point) and the
extension point is identified by a combination of a pakcage name and a typecode of the 
element.

<p>
For example, an SBaseExtensionPoint object which represents an extension point of the model
element defined in the <em>core</em> package can be created as follows:

@verbatim
      SBaseExtensionPoint  modelextp("core", SBML_MODEL);
@endverbatim

Similarly, an SBaseExtensionPoint object which represents an extension point of
the layout element defined in the layout extension can be created as follows:

@verbatim
      SBaseExtensionPoint  layoutextp("layout", SBML_LAYOUT_LAYOUT);
@endverbatim
 
SBaseExtensionPoint object is required as one of arguments of the constructor 
of SBasePluginCreator&lt;class SBasePluginType, class SBMLExtensionType&gt;
template class to identify an extension poitnt to which the plugin object created
by the creator class is plugged in.
For example, the SBasePluginCreator class which creates a LayoutModelPlugin object
of the layout extension which is plugged in to the model element of the <em>core</em>
package can be created with the corresponding SBaseExtensionPoint object as follows:

@verbatim
  // std::vector object that contains a list of URI (package versions) supported 
  // by the plugin object.
  std::vector<std::string> packageURIs;
  packageURIs.push_back(XmlnsL3V1V1);
  packageURIs.push_back(XmlnsL2);  

  // creates an extension point (model element of the "core" package)
  SBaseExtensionPoint  modelExtPoint("core",SBML_MODEL);
   
  // creates an SBasePluginCreator object 
  SBasePluginCreator<LayoutModelPlugin, LayoutExtension>  modelPluginCreator(modelExtPoint,packageURIs);
@endverbatim

This kind of code is implemented in init() function of each SBMLExtension derived classes.


<h3><a class="anchor" name="SBasePluginCreatorBase">4. SBasePluginCreator class</a></h3>

<a href="#SBasePluginCreatorBase"> SBasePluginCreator </a> template class is a factory 
class which creates an SBasePlugin object. 

<p>
Basically, package developers only have to instantiate the template class for each SBasePlugin 
extended class of their packages and have to register the instantiated objects to their 
<a href="#SBMLExtension"> SBMLExtension </a> extended classes.
</p>

<p>
The template class is instantiated for each SBasePlugin extended class and used by each 
SBase class for dynamically internally create and add the corresponding SBasePlugin object.
For example, SBasePluginCreator&lt;LayoutModelPlugin, LayoutExtension&gt; is instantiated
for creating an LayoutModelPlugin object of the layout extension.
</p>

<p>
Each SBasePlugin extended object is dynamically internally created and added to the 
corresponding SBase extended object when the SBase element is read or created (Basically,
this behaviour is internally implemented and thus package developers don't have to care the 
implementation).
</p>

For example, a LayoutModelPlugin object of SBML L3V1 Layout V1 is internally/dynamically 
created and added to a Model object when the Model object is constructed as follows:

@verbatim
     SBMLNamespaces sbmlns(3,1,"layout",1);  // namespace of L3V1 Core with L3V1 Layout V1
     Model model(&sbmlns);                   
@endverbatim

On the other hand, no SBasePlugin extended objects are created/added when no package extensions 
are specified as follows:

@verbatim
     SBMLNamespaces sbmlns(3,1);   // namespace of L3V1 Core 
     Model model(&sbmlns);    
@endverbatim

To read/create elements of a package extension in user's program, the followings are required:

  <ol>
    <li> a corresponding package extension needs to be registered to 
        <a href="#SBMLExtensionRegistry"> SBMLExtensionRegistry </a> class

        <p>
        (Basically, this is automatically done by linking a shared library 
         of the package extension with a user's program at compile time),
	</p>

    </li>

    <li> the corresponding package extension needs to be enabled in the target model 
        (i.e., xmlns attribute of the package extension is defined in &lt;sbml&gt; element).
    </li>
  </ol>

<h3><a class="anchor" name="SBMLExtensionNamespaces">5. SBMLExtensionNamespaces class</a></h3>

<p> 
<a href="#SBMLExtensionNamespaces">SBMLExtensionNamespaces</a> is a template class which
is extended from an SBMLNamespaces class and specific to each package extension. 

The purpose of this class is as follows:

   <ol>
     <li>To add information of package version, </li>
     <li>To avoid passing an invalid SBMLNamespaces object to the constructors
          of SBase derived classes of package extensions at runtime.
     </li>
  </ol>

Package developers must define (instantiate) its own SBMLNamespaces derived class 
from this template class and then define a typedef declaration as follows:
   
@verbatim
    typedef SBMLExtensionNamespaces<LayoutExtension> LayoutPkgNamespaces   

    // (this code is implemented in "src/packages/layout/extension/LayoutExtension.h")
@endverbatim


Also, package developers must implement a template instantiation code for the above 
typedef definition in its implementation file (i.e. *.cpp file).
For example, the template instantiation code for LayoutExtension is as follows:
  
@verbatim
    template class LIBSBML_EXTERN SBMLExtensionNamespaces<LayoutExtension>;

    // (this code is implemented in "src/packages/layout/extension/LayoutExtension.cpp")
@endverbatim

Each SBase derived class of package extensions should implement a constructor
that accepts its SBMLNamespaces derived class.
For example, Layout class (one of SBase derived classes in the layout extension)
defines the following constructor which accepts a LayoutPkgNamespaces object.

@verbatim
  /**
   * Creates a new Layout with the given LayoutPkgNamespaces object.
   */
   Layout(LayoutPkgNamespaces* layoutns);
@endverbatim

<h3><a class="anchor" name="SBMLExtensionRegistry">6. SBMLExtensionRegistry class</a></h3>

<a href="#SBMLExtensionRegistry"> SBMLExtensionRegistry </a> class is a central registry 
class for package extensions. Each package extension is registered to this registry class by using 
<a href="#SBMLExtensionRegister">SBMLExtensionRegister</a> class when each library of package 
extensions is loaded.
The registry class is acessed by various classes (e.g. SBase extended class) to retrieve 
the information of package extensions and to create additional attributes and/or elements
by factory objects of package extensions. In other words, libSBML can't parse package 
extensions which are not registered in the registry class.

  This class provide the following features:

  <ol>
     <li> registers a package extension 
          (adding an SBMLExtension extended class of a package extension)
	      
     <li> returns an SBMLExtension extended object for the caller to get common 
          properties of the target package extension (e.g. the name of package, 
          default level, version, package_version, and URI of package versions) 

     <li> returns an SBasePluginCreatorBase extended object for the caller (basically 
          the caller is SBase class) to internally add an SBasePlugin object of the 
          target package extension (basically when creating an SBase object with 
          the package extension)

     <li> enables/disables the registered package extensions.

     <li> returns the number of registered package extensions.
  </ol>

  At least, package developers must use this class for implementing init() function 
  in their SBMLExtension extended class for registering their packages to this class
  as follows:

@verbatim
       static void LayoutExtension::init()
       {
         LayoutExtension layoutExtension;
         ...
         <snip>
         ...
         int result = SBMLExtensionRegistry::getInstance().addExtension(&layoutExtension);
       }
@endverbatim


<h3><a class="anchor" name="SBMLExtensionRegister">7. SBMLExtensionRegister class</a></h3>

 SBMLExtensionRegister class is a template class for automatically registering 
 each package extension to the SBMLExtensionRegistry class before main() routine invoked.

 This class is very simple and easy to be used as follows (just instantiating an object):

@verbatim
     static SBMLExtensionRegister<LayoutExtension> layoutExtensionRegistry;
@endverbatim

  This code registers the LayoutExtension to the SBMLExtensionRegistry class
  when the code is parsed at start-up time.

<h3><a class="anchor" name="SBMLExtensionException">8. SBMLExtensionException class</a></h3>

 <p>
  SBMLExtensionException class is an exception class which can be thrown 
  when an exception about pacakge extension occurs (e.g., required package
  is not registered).
 </p>

 <p>
  Currently, the exception can be thrown in the following functions if
  the required package is not registered:

  <ol>
    <li> the constructor of SBMLNamespaces 
    <li> the constructor of SBMLExtensionNamespaces
  </ol>
 </p>

*/

