/** @page libsbml-howto-implement-extension.html Step by step summary of the implementation of an extension

@tableofcontents

<p> This section describes the steps necessary to implement a <em>package
extension</em> (also known as a <em>package plugin</em>) for libSBML by hand.
The purpose of this section is to document the process.  In practice, the
libSBML developers no longer write package extensions by hand, but instead,
use a code generation system under development by the libSBML Team (a system
called DEVISER, short for <em>Design Explorer and Viewer for Iterative SBML
Enhancement of Representations</em>).  This code generator embodies the steps
below.


@section implem-dir 1. Create the directory structure

The conventional structure for a libSBML package extension involves two main
directories, one for the implementation sources and one for example code.
The following illustrates this structure:

<pre style="margin-left: 20px; line-height: 100%">
<span class="placeholder">package_root</span>
│
├── examples
│   ├── c
│   ├── c++
│   ├── csharp
│   ├── java
│   ├── javascript
│   ├── perl
│   ├── python
│   ├── r
│   └── ruby
│
└── src
    ├── bindings
    │   ├── csharp
    │   ├── java
    │   ├── javascript
    │   ├── perl
    │   ├── python
    │   ├── r
    │   ├── ruby
    │   └── swig
    │
    └── sbml
        └── packages
            │
            └── <span class="placeholder">package_name</span>
                │
                ├── common
                │   └── test
                ├── extension
                │   └── test
                ├── sbml
                │   └── test
                ├── util
                │   └── test
                └── validator
                    └── test
</pre>

The top-level directory, <span class="placeholder">package_root</span>, can
be named anything, although by convention it's named after the SBML
Level&nbsp;3 package being implemented.  The directory <span
class="placeholder">package_name</span> should be the nickname or short-form
name of the package (e.g., "comp" for the Hierarchical %Model Composition
package).

The directory structure for the implementation of the package (the tree root
at <code>src</code>) is separated into two main branches:
<code>bindings</code> for the programming language interfaces (known as the
<em>language bindings</em> in libSBML-speak) generated with the help of SWIG,
and <code>sbml</code> for actual package code.  The subdirectories under
<span class="placeholder">package_name</span> have the following purposes:

@li <code>common</code>: This contains header files that provide forward
declarations for all the object classes defined by the package, plus any
other common headers and/or code.

@li <code>extension</code>: This contains the code for the all of the
extensions of libSBML classes defined by the package.  For example, if a
package extends the Model object, this is where the extension class code is
placed.

@li <code>sbml</code>: This contains all the new SBML object classes
defined by the package.

@li <code>util</code>: As its name implies, this contains any utility
classes or other code that a package might need in its implementation.

@li <code>validator</code>: This contains code for SBML validation of the
package constructs.

Examples of real package extensions employing the directory structure
described above can be found in the libSBML source distribution, in the
<code>src/sbml/packages</code> subdirectory.


@section implem-sbaseplugin 2. Derive classes from SBasePlugin

Certain classes in an SBML Level&nbsp;3 package will be subclasses of
existing core SBML constructs, and other classes will be entirely ones
introduced by the package.  Existing SBML classes can be extended through the
use of the special-purpose classes SBasePlugin and SBMLDocumentPlugin, while
new classes are implemented as objects derived from the basic SBase class.
We discuss SBasePlugin in this section, SBMLDocumentPlugin in the next
section, and the implementation of entirely new classes in the section after
that.

The SBasePlugin class is libSBML's base class for extensions of core SBML
component objects.  It defines basic virtual methods for
reading/writing/checking additional attributes and/or subobjects; and these
methods should be overridden by subclasses to implement the necessary
features of an extended SBML object.  The documentation for the SBasePlugin
class describes the steps necessary to use it to extend existing object
classes.  Here we summarize the steps:

<ol>

<li> <em>Identify the SBML objects that need to be extended</em>.  Any
existing SBML object that gets new attributes or subobjects falls into
this category.  For instance, a package may need to extend Model to add new
list of entities (as the SBML Level&nbsp;3 %Layout package does with
ListOfLayouts).

<li> <em>Create a SBasePlugin subclass for each extended SBML
object class</em>.  This involves several substeps, summarized briefly here:

<ol style="list-style-type: lower-latin">

<li>Define protected data members and implement their initialization as well
as their handling by assignment operators, copy operators, and other
necessary operators or fields.

<li>Override SBasePlugin class-related methods such as the class constructor,
copy constructor, and others.

<li>Override SBasePlugin virtual methods for attributes on the SBML object.

<li>Override SBasePlugin virtual methods for subobjects, if the object
class contains other classes of objects.

<li>Override SBasePlugin virtual methods for XML namespaces, if the SBML
package uses extra XML namespaces beyond the default SBML namespace.

<li>Implement additional methods as needed.

</ol>

</ol>

A subclass of SBasePlugin, SBMLDocumentPlugin, is designed specifically for
extending the top-level SBML container object.  It should be used instead of
SBasePlugin to add attributes or subobjects to the <code>&lt;sbml&gt;</code>
XML element, if an SBML package calls for it.  The next section discusses this
further.

In the directory structure for packages (@ref implem-dir), the code for
extensions of existing libSBML classes is placed in the subdirectory named
<code>extension</code>.


@section implem-sbmldocument 3. Derive a class from SBMLDocumentPlugin if necessary

SBML Level&nbsp;3 packages typically do not make any changes to the top-level
<code>&lt;sbml&gt;</code> XML element beyond adding an attribute named
"required", so in most cases, the extension of SBMLDocument is very simple.
Here follows a summary of the basic steps; the documentation for the
SBMLDocumentPlugin class explains the steps in more detail.

<ol>
<li><em>Identify the changes necessary to SBMLDocument</em>.

<li><em>Create the SBMLDocumentPlugin subclass</em>.  This involves several
substeps:

    <ol style="list-style-type: lower-latin">

    <li>Override class-related methods derived from SBasePlugin, the parent
    class of SBMLDocumentPlugin.

    <li>Determine the necessary value of the "required" attribute and set up the
    class implementation to set/test/manage the value accordingly.

    <li>Define protected data members, if the package definition requires any.

    <li>Override virtual methods for new attributes, if any.

    <li>Override virtual methods for subobjects, if the package defines any
    new objects under the top-level <code>&lt;sbml&gt;</code> XML element.

    <li>Override virtual methods for XML namespaces.

    <li>Implement additional methods as needed.

</ol>
</ol>

In the directory structure for packages (Section @ref implem-dir), the code
using SBMLDocumentPlugin is placed in the subdirectory named
<code>extension</code>, grouped together with the classes derived from
SBasePlugin.


@section implem-sbase 4. Derive classes from SBase

As mentioned above, some classes in SBML Level&nbsp;3 package specifications
typically are defined as subclasses of existing core SBML objects such as
Model, Reaction, Parameter, and so forth, while others are defined as
entirely new classes.  If the package specification calls for @em new SBML
objects derived from SBML's abstract <em><strong>%SBase</strong></em> class,
the libSBML package extension should implemented them by deriving them from
the libSBML SBase class.

The following are the basic steps to subclassing SBase for the implementation
of each new SBML object class:

<ol>
  
<li><em>Identify the attributes of the class</em>.  Objects will have
attributes, subobjects (usually either for a mathematical formula or a list
of subobjects inside a ListOf), or a mixture of both.  When an object has
attributes, each attribute will have a data type; this data type will be
either one of the core SBML primitive types or a new type defined in the
specification for the package.  The first step is to gather the requirements
for these attributes.

<li><em>Identify the subobjects of each object class</em>.  Another necessary
requirements analysis step is determining if any subobjects need to be
defined and contained withing other objects.  Any that are subclassed from
SBase will be their own separate class, and will be contained inside another
class derived from ListOf.  (For example, ListOfLayouts in the SBML
Level&nbsp;3 %Layout package.)

<li><em>Write the implementation of each class</em>.

<ol style="list-style-type: lower-latin">

<li>Define protected data members that store identified subobjects and/or
attributes.  For example, the the <code>Groups</code> class in the Groups
package needs protected data members for the object identifier ("id")
attribute, object name ("name") attribute, a list of <code>Member</code>
objects (stored in a <code>ListOfMembers</code> class object derived from
ListOf), and more.
</li>

<li>Define the following two class constructors: (i) a constructor that
accepts three arguments for the SBML Level, SBML Version, and package
version; and (ii) a constructor that accepts an object derived from
SBMLNamespaces.  Make sure that the implementation of the constructor calls
the parent's constructor, and that the default SBML Level, Version and
package version are given as default arguments.  The implementation also has
to call the method <code>setSBMLNamespacesAndOwn()</code> with the 
package-specific SBMLExtensionNamespaces object, as well as the method
<code>connectToChild()</code>. Here is an example from the Groups package:
@code{.cpp}
Group::Group (unsigned int level, unsigned int version, unsigned int pkgVersion) 
  : SBase (level, version)
   ,mId("")
   ,mName("")
   ,mKind(GROUP_KIND_UNKNOWN)
   ,mMembers(level, version, pkgVersion)
   ,mMemberConstraints (level, version, pkgVersion)
{
  // set an SBMLNamespaces derived object of this package
  setSBMLNamespacesAndOwn(new GroupsPkgNamespaces(level, version, pkgVersion));

  // connect to child objects
  connectToChild();
}
@endcode
</li>

<li>Define a constructor that accepts an SBMLNamespaces object.  This
constructor needs to call three methods, as illustrated in the body of this
example from the Groups package:
@code{.cpp}
Group::Group(GroupsPkgNamespaces* groupsns)
 : SBase(groupsns)
  ,mId("")
  ,mName("")
  ,mKind(GROUP_KIND_UNKNOWN)
  ,mMembers(groupsns)
   ,mMemberConstraints (groupsns)
{
  // set the element namespace of this object
  setElementNamespace(groupsns->getURI());

  // connect to child objects
  connectToChild();

  // load package extensions bound with this object (if any) 
  loadPlugins(groupsns);
}
@endcode
<p>The call to <code>loadPlugins(...)</code> is necessary to allow the
  package to be extended by @em other package extensions.  It is also worth
  noting that the constructor for SBMLNamespaces and its derived class
  SBMLExtensionNamespaces throw an SBMLExtensionException if the argument it
  is given is invalid.  Callers will have to create the object using code
  such as the following example from the %Layout package:
@code{.cpp}
try
{
  LayputPkgNamespaces layoutns(3, 1, 1);
  Layout              layout(&layoutns); 
}
catch (SBMLExtensionException e)
{
  cerr << "Caught " << e.what() << endl;
}
@endcode
</li>

<li>Override the copy constructor, assignment operator, and
<code>clone()</code> methods from SBase and implement appropriate versions
for the package.</li>

<li>Override the following virtual methods if the object defines "id" and
"name" attributes: <code>setId(...)</code>, <code>setName(...)</code>,
<code>isSetId(...)</code>, <code>isSetName(...)</code>,
<code>unsetId(...)</code>, <code>unsetName(...)</code>.

<li>If the SBML object defines any other attributes, then for every attribute
defined by the class, implement new methods to set, get, unset, and query the
attribute value.  For an attribute named <span
class="placeholder">ATTRIB</span>, this will lead to methods named
<code>set<span class="placeholder-nospace">ATTRIB</span></code>,
<code>get<span class="placeholder-nospace">ATTRIB</span></code>,
<code>isSet<span class="placeholder-nospace">ATTRIB</span></code>, and
<code>unset<span class="placeholder-nospace">ATTRIB</span></code>.

<li>Override the following virtual methods if the object defines any
attributes:

<ul>

<li> <code>addExpectedAttributes(ExpectedAttributes& attributes)</code>: This
method should add the attributes that are expected to be found on this kind
of extended object in an SBML file or data stream.

<li> <code>readAttributes(XMLAttributes& attributes, ExpectedAttributes&
expectedAttributes)</code>: This method should read the attributes
expected to be found on this kind of extended object in an SBML file or
data stream.

<li> <code>hasRequiredAttributes()</code>: This method should return @c true
if all of the required attribute for this extended object are present on
instance of the object.

<li> <code>writeAttributes(XMLOutputStream& stream)</code>: This method should
write out the attributes of an extended object.  The implementation should
use the different kinds of <code>writeAttribute</code> methods defined by
XMLOutputStream to achieve this.

</ul>
</li>

<li>Override the following virtual methods if the object defines one or more
subobjects:

<ul>
<li> <code>createObject(XMLInputStream& stream)</code>: Subclasses must
override this method to create, store, and then return an SBML object
corresponding to the next XMLToken in the XMLInputStream.

<li> <code>connectToParent(SBase *sbase)</code>: This creates a parent-child
relationship between a given extended object and its subcomponent(s).

<li> <code>setSBMLDocument(SBMLDocument* d)</code>: This method should set the
parent SBMLDocument object on the subcomponent object instances, so that the
subcomponent instances know which SBMLDocument contains them.

<li> <code>enablePackageInternal(std::string& pkgURI, std::string& pkgPrefix,
bool flag)</code>: This method should enable or disable the subcomponent
based on whether a given XML namespace is active.

<li> <code>writeElements(XMLOutputStream& stream)</code>: This method must be
overridden to provide an implementation that will write out the expected
subcomponents/subelements to the XML output stream.

<li> <code>readOtherXML(SBase* parentObject, XMLInputStream& stream)</code>:
This function should be overridden if XML elements containing annotations, 
notes, MathML content, etc., need to be directly parsed from the
given XMLInputStream object.

<li> <code>hasRequiredElements()</code>: This method should return @c true if
a given object contains all the required subcomponents defined by the
specification for that SBML Level&nbsp;3 package.
</ul>
</li>

<li>Override the virtual method <code>writeXMLNS(XMLOutputStream&
stream)</code> if the package needs to add additional <code>xmlns</code>
attributes to declare additional XML namespace URIs.
</li>

<li>Define any additional methods needed by the class, for example to add and
remove subobjects.

</ol>
</ol>

In the directory structure for packages (Section @ref implem-dir), the code
for new object classes is placed in the subdirectory named <code>sbml</code>.

Developers can take advantage of the many package implementations available
for libSBML to see real-life examples of objects derived from SBase.


@section implem-sbmlext 5. Derive a class from SBMLExtension

The SBMLExtension class is an abstract class that must be extended by each
package extension implementation.  The class provides methods for managing
common attributes of package extensions (e.g., the SBML package name, the
package version, and more), registration of instantiated SBasePluginCreator
objects, and initialization/registration of package extensions when the
library code for the package is loaded by libSBML.

The documentation for SBMLExtension explains in detail the process of
extending the class as part of the implementation of a package extension.
The following is a summary of the steps:

<ol>

<li>Define a <code>getPackageName()</code> method that returns the name of
the package as a string.

<li>Define a set of methods that return the default SBML Level, SBML Version
and version of the package.

<li>Define methods returning the package namespace URIs

<li>Override basic pure virtual methods on SBMLExtension.

<li>Create definitions derived from SBMLExtensionNamespaces.

<li>Override the SBMLExtension method <code>getSBMLExtensionNamespaces()</code>.

<li>Define an enumeration for the package object type codes.

<li>Override the SBMLExtension method <code>getStringFromTypeCode()</code>.

<li>Implement an <code>init()</code> method.

<li>Instantiate a global SBMLExtensionRegister object.

</ol>


@section forward-decl 6. Implement a forward declaration file

Create a file that provides forward declarations for all classes defined by
the package extension.  In the directory structure for packages (Section @ref
implem-dir), this file should be placed in the subdirectory named
<code>common</code>.  Here is an example from the %Layout package; this can
be found in the file <code>src/packages/layout/common/layoutfwd.h</code>.
The definition of <code>CLASS_OR_STRUCT</code> is to permit this code to work
for both C and C++:

@code{.cpp}
#ifndef layoutfwd_h__
#define layoutfwd_h__

#ifdef __cplusplus
#  define CLASS_OR_STRUCT class
#else
#  define CLASS_OR_STRUCT struct
#endif  /* __cplusplus */

LIBSBML_CPP_NAMESPACE_BEGIN

typedef CLASS_OR_STRUCT BoundingBox                     BoundingBox_t;
typedef CLASS_OR_STRUCT CompartmentGlyph                CompartmentGlyph_t;
typedef CLASS_OR_STRUCT CubicBezier                     CubicBezier_t;
typedef CLASS_OR_STRUCT Curve                           Curve_t;
typedef CLASS_OR_STRUCT Dimensions                      Dimensions_t;
typedef CLASS_OR_STRUCT GeneralGlyph                    GeneralGlyph_t;
typedef CLASS_OR_STRUCT GraphicalObject                 GraphicalObject_t;
typedef CLASS_OR_STRUCT Layout                          Layout_t;
typedef CLASS_OR_STRUCT LineSegment                     LineSegment_t;
typedef CLASS_OR_STRUCT Point                           Point_t;
typedef CLASS_OR_STRUCT ReactionGlyph                   ReactionGlyph_t;
typedef CLASS_OR_STRUCT ReferenceGlyph                  ReferenceGlyph_t;
typedef CLASS_OR_STRUCT SpeciesGlyph                    SpeciesGlyph_t;
typedef CLASS_OR_STRUCT SpeciesReferenceGlyph           SpeciesReferenceGlyph_t;
typedef CLASS_OR_STRUCT TextGlyph                       TextGlyph_t;

LIBSBML_CPP_NAMESPACE_END

#undef CLASS_OR_STRUCT

#endif  /* layoutfwd_h__ */
@endcode


@section header-file 7. Implement a package header file

Create a single header file that includes all other package header files
necessary to declare the types defined by the package extension.  In the
directory structure for packages (Section @ref implem-dir), this file should
be placed in the subdirectory named <code>common</code>.  Here is an example
from the %Layout package; this can be found in the file
<code>src/packages/layout/common/LayoutExtensionTypes.h</code>:

@code{.cpp}
#ifndef LayoutExtensionTypes_h
#define LayoutExtensionTypes_h

#include <sbml/packages/layout/common/layoutfwd.h>

#include <sbml/packages/layout/extension/LayoutExtension.h>
#include <sbml/packages/layout/extension/LayoutModelPlugin.h>
#include <sbml/packages/layout/extension/LayoutSBMLDocumentPlugin.h>

#include <sbml/packages/layout/sbml/BoundingBox.h>
#include <sbml/packages/layout/sbml/CompartmentGlyph.h>
#include <sbml/packages/layout/sbml/CubicBezier.h>
#include <sbml/packages/layout/sbml/Curve.h>
#include <sbml/packages/layout/sbml/Dimensions.h>
#include <sbml/packages/layout/sbml/GraphicalObject.h>
#include <sbml/packages/layout/sbml/Layout.h>
#include <sbml/packages/layout/sbml/LineSegment.h>
#include <sbml/packages/layout/sbml/Point.h>
#include <sbml/packages/layout/sbml/ReactionGlyph.h>
#include <sbml/packages/layout/sbml/SpeciesGlyph.h>
#include <sbml/packages/layout/sbml/SpeciesReferenceGlyph.h>
#include <sbml/packages/layout/sbml/SpeciesReferenceRole.h>
#include <sbml/packages/layout/sbml/TextGlyph.h>
#include <sbml/packages/layout/sbml/ReferenceGlyph.h>
#include <sbml/packages/layout/sbml/GeneralGlyph.h>

#endif  /* LayoutExtensionTypes_h */
@endcode


@section config-macros 8. Define files for package registration

Two files need to be created in <code>src/sbml/packages</code> as part of the
libSBML scheme for including packages at compilation time.  The first file
should be named <code><span
class="placeholder">name</span>-register.h</code>, where <code><span
class="placeholder">name</span></code> is the name of the package extension.
Here is an example from the Groups package, in the file
<code>src/sbml/packages/groups-register.h</code>:

@code{.cpp}
#ifdef USE_GROUPS
#include <sbml/packages/groups/extension/GroupsExtension.h>
#endif	
@endcode

Note the contents in the file above: it includes the extension file in the
package source directory (<code>GroupExtension.h</code>), and it uses a
<code>ifdef</code> condition on a variable named <code>USE_<span
class="placeholder">NAME</span></code>, where <code><span
class="placeholder">NAME</span></code> is the package name.

The second file should be named <code><span
class="placeholder">name</span>-register.cxx</code>.  It will be used as an
inclusion by another part of libSBML to invoke the <code>init()</code> method
of the class created in step&nbsp;4 above (@ref implem-sbmlext).  This file
should have content as shown in the next example taken from
<code>src/sbml/packages/groups-register.cxx</code>:

@code{.cpp}
#ifdef USE_GROUPS
GroupsExtension::init();
#endif	
@endcode


@section hook-bindings 9. Hook into the language bindings

This part of the process is unfortunately one of the most complex to perform
and to describe.  The simplest approach is to copy the files from an existing
package implementation and modify them to work with the names and objects
defined in the new package.  The following are the relevant language binding
files for C#, Java, Perl, Python, R and Ruby for a package such as Groups:

@verbatim
src/bindings/csharp/local-downcast-extension-groups.i
src/bindings/csharp/local-downcast-namespaces-groups.i
src/bindings/csharp/local-packages-groups.i

src/bindings/java/local-downcast-extension-groups.i
src/bindings/java/local-downcast-namespaces-groups.i
src/bindings/java/local-packages-groups.i

src/bindings/perl/local-downcast-extension-groups.cpp
src/bindings/perl/local-downcast-namespaces-groups.cpp
src/bindings/perl/local-downcast-packages-groups.cpp
src/bindings/perl/local-downcast-plugins-groups.cpp
src/bindings/perl/local-groups.i

src/bindings/python/local-downcast-extension-groups.cpp
src/bindings/python/local-downcast-namespaces-groups.cpp
src/bindings/python/local-downcast-packages-groups.cpp
src/bindings/python/local-downcast-plugins-groups.cpp
src/bindings/python/local-groups.i

src/bindings/r/local-downcast-extension-groups.cpp
src/bindings/r/local-downcast-namespaces-groups.cpp
src/bindings/r/local-downcast-packages-groups.cpp
src/bindings/r/local-downcast-plugins-groups.cpp
src/bindings/r/local-groups.i

src/bindings/ruby/local-downcast-extension-groups.cpp
src/bindings/ruby/local-downcast-namespaces-groups.cpp
src/bindings/ruby/local-downcast-packages-groups.cpp
src/bindings/ruby/local-downcast-plugins-groups.cpp
src/bindings/ruby/local-groups.i

src/bindings/swig/groups-package.h
src/bindings/swig/groups-package.i
@endverbatim


@section hook-build 10. Hook into the libSBML build system

Inclusion and compilation of packages in libSBML is supported through the use
of the CMake system.  To connect a new package extension to the rest of the
libSBML build system, two CMake files have to be created: (1) a CMake file to
compile the various parts of the package implementation, and (2) a CMake file
that connects the package to the rest of the libSBML build system.

<ol>

<li><em>CMake file to compile the package code</em>.  Create a <code><span
class="placeholder">name</span>-package.cmake</code> file at the top level of
the libSBML source tree, <code>/src</code>, where <span
class="placeholder">name</span> is the name of the package.  Here is an
example of the <code>groups-package.cmake</code> file from the Groups
package:
@code{.py}
if(ENABLE_GROUPS)
  include(${LIBSBML_ROOT_SOURCE_DIR}/groups-package.cmake)

  # Go through all the Groups directories and build a list of files.
  set(GROUPS_SOURCES)
  foreach(dir common extension sbml validator)
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sbml/packages/groups/${dir})

    file(GLOB current ${CMAKE_CURRENT_SOURCE_DIR}/sbml/packages/groups/${dir}/*.cpp
                      ${CMAKE_CURRENT_SOURCE_DIR}/sbml/packages/groups/${dir}/*.c
                      ${CMAKE_CURRENT_SOURCE_DIR}/sbml/packages/groups/${dir}/*.h)
    
    # Special handling for the validator: set the *Constraints.cpp files to be
    # 'header' files so they won't be compiled. They are #included directly instead.

    if ("${dir}" STREQUAL "validator/constraints")
      foreach(tempFile ${current})
        if ("${tempFile}" MATCHES ".*Constraints.cpp")
          set_source_files_properties(
            ${tempFile}
            PROPERTIES HEADER_FILE_ONLY true
            )
        endif()
      endforeach()
    endif()

    set(GROUPS_SOURCES ${GROUPS_SOURCES} ${current})
    
    # Mark header files for installation.
    file(GLOB groups_headers ${CMAKE_CURRENT_SOURCE_DIR}/sbml/packages/groups/${dir}/*.h)
    install(FILES ${groups_headers} DESTINATION include/sbml/packages/groups/${dir} )
  endforeach()

  # Create source group files for IDEs.
  source_group(groups_package FILES ${GROUPS_SOURCES})

  # Add the Groups package sources to libSBML sources.
  SET(LIBSBML_SOURCES ${LIBSBML_SOURCES} ${GROUPS_SOURCES})

  # Add unit test files.
  if(WITH_CHECK)
    add_subdirectory(sbml/packages/groups/extension/test)
  endif()

endif()
@endcode
</li>

<li><em>CMake file to connect the package to the rest of libSBML's build
system</em>. In the libSBML top-level, create another (different) file named
<code><span class="placeholder">name</span>-package.cmake</code>, where <span
class="placeholder">name</span> is the name of the package.  The file should
contain code that looks like the following, where this example is drawn from
the %Layout package:

@code{.cpp}
option(ENABLE_GROUPS
"Enable libSBML support for the SBML Level 3 Groups ('groups') package." OFF)

# Provide summary status                                    =
list(APPEND LIBSBML_PACKAGE_SUMMARY "SBML 'groups' package  = ${ENABLE_GROUPS}")

if(ENABLE_GROUPS)
  add_definitions(-DUSE_GROUPS)
  set(LIBSBML_PACKAGE_INCLUDES ${LIBSBML_PACKAGE_INCLUDES} "LIBSBML_HAS_PACKAGE_GROUPS")
  list(APPEND SWIG_EXTRA_ARGS -DUSE_GROUPS)
  list(APPEND SWIG_SWIGDOCDEFINES --define USE_GROUPS)
endif()
@endcode

An implementation starting with the code above could simply replace the
string <code>GROUPS</code> with the appropriate name of the package.
</li>

</ol>

*/
