\section*{Other Features of {\tt libSBOL}}
So far, we have demonstrated how one can build the CRISPR-based repression module ~\cite{kiani2014crispr} using {\tt libSBOL}. In this section, we present other major methods in the library's API. 

\subsection*{Retrieving an Existing Object}
Often, we need getter methods to retrieve a previously created object. You can easily retrieve top level objects from a document by calling a templated ``get'' method using the class of the target object as the template argument. For example, if we want to get the \lstinline+cas9_generic+ protein \sbol{ComponentDefinition} object, we can use the \lstinline+get<ComponentDefinition>+ method shown below (lines 1-4) by providing the display ID of the object. By default this retrieves the latest version of an object. Alternatively, one may pass a full URI as an argument to the getter, which may be necessary when retrieving previous versions of an object.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
ComponentDefinition &cas9_generic1 = doc.get<ComponentDefinition>("cas9_generic");
\end{lstlisting}
\end{minipage}

\subsection*{Manipulating Optional Fields}
Objects may include optional fields. These are indicated in the UML specification as properties having 0 or more possible values. For example, the role property of a ComponentDefinition is optional while the molecular type field is required. Optional properties can only be set after the object is created. The following code creates a DNA component which is designated as a promoter:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
ComponentDefinition& TargetPromoter = *new ComponentDefinition("TargetPromoter", BIOPAX_DNA, "1.0.0");
TargetPromoter.roles.set(SO_PROMOTER)
\end{lstlisting}
\end{minipage}

In addition, properties have a get method. To view the value of a property:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
cout << TargetPromoter.roles.get() << endl;
// This returns the string "http://identifiers.org/so/SO:0000167" which is the Sequence Ontology term for a promoter.
\end{lstlisting}
\end{minipage}

Note also that some properties may contain more than one value. In the specification diagrams, an asterisk symbol next to a property indicates that the property may hold an arbitrary number of values. For example, a ComponentDefinition may be assigned multiple roles. To append a new value to the values already assigned:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
TargetPromoter.roles.add(SO "0000568");
\end{lstlisting}
\end{minipage}

To get multiple values back from a property, it is necessary to iterate over the property:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
// Iterate through a property to get multiple values
for (auto i_role = reaction_participant.roles.begin(); i_role != reaction_participant.roles.end(); i_role++)
{
    string role = *i_role;
    cout << role << endl;
}
\end{lstlisting}
\end{minipage}

An important thing to remember is that the set method will always overwrite the first value of a property, while the add method will always append a new value. To remove a value, one may use the remove method. Currently the remove method requires a numerical index, though this will likely change in the future.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
TargetPromoter.roles.remove(0);
\end{lstlisting}
\end{minipage}

The number of values contained by a property can be obtained by calling the size method.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
TargetPromoter.roles.size();
\end{lstlisting}
\end{minipage}

The only exceptions where these methods are not available are the following three fields in the \lstinline+Identified+ class: \lstinline+persistentIdentity+, \lstinline+displayId+, and
\lstinline+version+.  These fields cannot be edited, since they are crucial to maintaining
compliant SBOL objects (see Section~11.2 ``Compliant SBOL Objects'' of the~\href{http://sbolstandard.org/downloads/specification-data-model-2-0/}{Specification
  (Data Model 2.0)} for more details).

\subsection*{Creating and Editing References}

Some SBOL objects point to other objects by way of references. For example, ComponentDefinitions point to their corresponding Sequences. Properties of this type should be set with the URI of the related object.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
ComponentDefinition& EYFPGene = *new ComponentDefinition("EYFPGene", BIOPAX_DNA);
Sequence& seq = *new Sequence("EYFPSequence", "atgnnntaa", SBOL_ENCODING_IUPAC);
EYFPGene.sequences.set(seq.identity.get());
\end{lstlisting}
\end{minipage}

\subsection*{Creating Extension Classes}
In order to allow representation of data that can not currently be represented
by the SBOL data model or data that are outside the scope of SBOL,
SBOL offers developers the ability to embed custom data. These data are exchanged unmodified between software tools that adopt SBOL employing {\tt libSBOL} or its sister libraries such as {\tt libSBOLj}. {\tt LibSBOL} employs custom extension classes in order to embed data. Extension classes are defined like any other C++ class, as long as the user adheres to some simple patterns. The extension class approach differs slightly from the custom annotation mechanism used by {\tt libSBOLj}, but the end result is the same. The following snippet illustrates an extension class for biological parts compatible with the iGEM parts registry (\url{http://parts.igem.org}).

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
#include "sbol.h"

using namespace sbol;
using namespace std;

// These constants determine the appearance of nodes in the output file
#define EXTENSION_NS "http://igem.org#"   // Must end in a hash or forward-slash
#define EXTENSION_CLASS "iGEMCDef"        // Name of the class in XML output
#define EXTENSION_PREFIX "igem"           // Namespace prefix in XML output

class iGEMComponentDefinition : public ComponentDefinition  // Derive an extension class
{
    
public:
    TextProperty partStatus;
    TextProperty notes;
    TextProperty source;
    URIProperty results;
    
    // Define the constructor. Put required fields in the argument list. Each required field must have a default value specified, even if only an empty string.
    iGEMComponentDefinition(std::string uri = "", std::string partStatus = "Under construction") :
    
        // Call public base class constructor
        ComponentDefinition(uri),
    
        // Initialize member properties. The second argument must ALWAYS be 'this'.
        partStatus(EXTENSION_NS "partStatus", this, partStatus),  // The field is initialized to the value "Under construction"
        notes(EXTENSION_NS "notes", this),                        // The optional field is not initialized with any value
        source(PURL_URI "source", this),                        // Dublin Core namespace is already defined as part of the SBOL Core
        results(EXTENSION_NS "results", this)
    {
        // Register the extension class.
        register_extension_class < iGEMComponentDefinition >(EXTENSION_NS, EXTENSION_PREFIX, EXTENSION_CLASS);
    };
    
    // Destructor
    ~iGEMComponentDefinition() {};
};

\end{lstlisting}
\end{minipage}

An extension class requires an extension namespace, a class name, and a required namespace prefix (which is just a shorthand symbol for the namespace in the output file). In the example above, the extension class iGEMCDef will be defined in the namespace http://igem.org, or simply `igem'. Note that a properly formed namespace MUST end with `/' or `\#'.  

In line 9 the extension class is derived from the core SBOL class ComponentDefinition. This means that new properties defined in the extension class will be serialized as annotations under the ComponentDefinition class. In addition, entirely new TopLevel extension classes can be defined, but this is covered in the next section.

Lines 13-16 define the extension properties. Each object in SBOL 2.0 can be annotated by having any number of
extension properties of type \lstinline+TextProperty+, \lstinline+URIProperty+, \lstinline+IntProperty+, or \lstinline+ReferencedObject+ objects that store data in the form of name/value property pairs. In addition, extension classes can be assembled into composite data structures using \lstinline+OwnedObject+ properties (not shown). 

Line 19 defines the constructor signature. Like all SBOL classes, the first argument to an extension class should be a URI that identifies the new object. Also, as a best practice consistent with the rest of the core SBOL constructors, the remaining arguments should be required fields. All fields MUST have a default value specified such that a default constructor (see \url{http://en.cppreference.com/w/cpp/language/default_constructor}) is defined.

Lines 25-28 initialize the member properties. These also follow a simple pattern. The first argument is the URI of the property, which consists of the extension namespace followed by the property name as it appears in the serialized XML file. The second argument MUST always be \lstinline+this+. In the optional third argument, an initial value for the property is specified. In this example, only the required argument partStatus is assigned an initial value. All the other properties are left blank by default.

Finally, the extension class is registered in the data model. The class interface can now be used like any other SBOL core class, and can be written to and parsed from an SBOL file. The following code demonstrates this.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
int main()
{
    Document& doc = *new Document();
    setHomespace("http://sys-bio.org");
    
    iGEMComponentDefinition& cd = *new iGEMComponentDefinition("My_component", "Available");
    cd.notes.set("This component works in E. coli");
    cd.source.set("This component was isolated from B. subtilis");
    cd.results.set("http://synbiohub.org/igem/results/Works");
    doc.add < iGEMComponentDefinition > (cd);
    doc.write("igem_example.xml");
}
\end{lstlisting}
\end{minipage}

The extension class appears in the serialized RDF/XML as a ComponentDefinition with  custom annotations embedded:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:dcterms="http://purl.org/dc/terms/"
   xmlns:igem="http://igem.org#"
   xmlns:prov="http://www.w3.org/ns/prov#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:sbol="http://sbols.org/v2#">
  <sbol:ComponentDefinition rdf:about="http://sys-bio.org/ComponentDefinition/My_component/1.0.0">
    <igem:notes>This component works in E. coli</igem:notes>
    <igem:partStatus>Available</igem:partStatus>
    <igem:results rdf:resource="http://synbiohub.org/igem/results/Works"/>
    <dcterms:source>This component was isolated from B. subtilis</dcterms:source>
    <sbol:displayId>My_component</sbol:displayId>
    <sbol:persistentIdentity rdf:resource="http://sys-bio.org/ComponentDefinition/My_component"/>
    <sbol:type rdf:resource="http://www.biopax.org/release/biopax-level3.owl#DnaRegion"/>
    <sbol:version>1.0.0</sbol:version>
  </sbol:ComponentDefinition>
</rdf:RDF>
\end{lstlisting}
\end{minipage}

\subsection*{Sharing and Distributing Extensions}
Simple extensions, such as those described above can be distributed as simple header files. Simply by including the header file with any application that links libSBOL, users can read and write extension classes and use basic accessor methods. In more advanced cases, extensions may include .cpp implementation files. In these cases, it is possible to distribute extensions as binary files. An example command line for how to compile an extension called libdummy on Mac OSX is below:

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
$ g++ -dynamiclib -std=c++11 -I/usr/local/include/sbol -I/usr/local/include/raptor2 -L/usr/local/lib -lraptor2 -lsbol dummy_extension.cpp -o libdummy.dylib
\end{lstlisting}
\end{minipage}

\subsection*{Accessing Annotations Without an Extension}
Extensions provide a means for users to quickly extend the SBOL Core data model and API. However, even if you don't have a particular extension installed, a user can still access extension data and custom annotations embedded in a file. The downside is that the user won't gain the full advantage of interfacing with the new class through an object-oriented API. Instead, the user has to access annotations using special methods in the base class. In the following example code snippet, the user interfaces with the iGEMComponentDefinition extension class by using its ComponentDefinition base class. 

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
doc.read("igem_example.xml");
ComponentDefinition& cd = doc.componentDefinitions["My_component"];
cout << cd.getPropertyValue(EXTENSION_NS "partStatus") << endl;
cout << cd.getPropertyValue(EXTENSION_NS "notes") << endl;
cout << cd.getPropertyValue(PURL_URI "source") << endl;
cout << cd.getPropertyValue(EXTENSION_NS "results") << endl;
\end{lstlisting}
\end{minipage}
    
\subsection*{Creating a TopLevel Extension Class}
Custom data can also be embedded at the top level of an SBOL document. The purpose of a top level extension class is to contain a set of annotations that are independent of any other class of SBOL object. To define a new top level class, simply derive from the TopLevel class. When deriving new classes from TopLevel class, a constant URI that defines the extension class must be specified. This URI specifies the namespace and name of the XML node for the serialized data. In this example, the Datasheet class contains two properties, a TextProperty that contains transcription data and a ReferencedObject which contains a reference to the iGEMComponentDefinition that the Datasheet describes.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
class Datasheet : public TopLevel 
{
public:
    TextProperty transcription_rate;
    ReferencedObject part;

    // Define the constructor. Put required fields in the argument list. Each required field must have a default value specified, even if only an empty string.
    Datasheet(std::string uri = "") :
    
        // Call the TopLevel constructor. Note that the first argument to the TopLevel constructor is a constant URI that defines the class. The second argument defines URIs for new object instances 
        TopLevel(EXTENSION_NS "Datashee", uri),
        transcription_rate(EXTENSION_NS "transcription_rate", this),
        part(EXTENSION_NS "part", EXTENSION_NS "iGEMCDef", this)
    {
        // Register the extension class.
        register_extension_class < Datasheet >(EXTENSION_NS, EXTENSION_PREFIX, "Datasheet");
    };
    
    // Destructor
    ~Datasheet() {};
};

int main()
{
    Document& doc = *new Document();
    setHomespace("http://sys-bio.org");
    Datasheet& data = *new Datasheet("test");
    data.transcription_rate.set("0.75");
    data.part.set("http://sys-bio.org/ComponentDefinition/My_component/1.0.0");
    doc.add < Datasheet > (data);
    doc.write("datasheet.xml");
}
\end{lstlisting}
\end{minipage}

\subsection*{Creating and Editing Child Objects}
Some SBOL objects can be composed into hierarchical parent-child relationships. In the specification diagrams, these relationships are indicated by black diamond arrows. For example ComponentDefinitions are parents of SequenceAnnotations. 

If operating in SBOL-compliant mode, you will almost always want to use the create method rather than constructors in order to create a child object. The create method constructs and adds the SequenceAnnotation in a single function call. The create method ALWAYS takes one argument–-the displayId of the new object. Some values may be initialized with default values. Refer to documentation of specific constructors to learn which parameters are assigned default values. After object creation, these fields and optional fields may be changed. 

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
SequenceAnnotation& point_mutation = TargetPromoter.annotations.create("point_mutation");
\end{lstlisting}
\end{minipage}

In SBOL-compliant mode, directly adding a child to a parent object is prohibited, in order to maintain URI persistence between them. In `open-world mode' the library makes no assumptions about how URIs are formed and leaves URI generation entirely up to the user.  In this case child objects can be directly created using constructors and added to the parent. Use \lstinline+toggleSBOLCompliance()+ if you prefer to generate your own URIs and operate in open-world mode. In future developments, constructors may be opened up for use in SBOL-compliant mode as well.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
SequenceAnnotation& point_mutation = *new SequenceAnnotation("point_mutation");
TargetPromoter.annotations.add(point_mutation);
\end{lstlisting}
\end{minipage}

\subsection*{Serialization}
The library supports reading and writing data encoded in RDF/XML format.All file I/O operations are performed on the Document object. The read and write methods are used for reading and writing files in SBOL format.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
Document& doc = *new Document();
doc.read("CRISPR_example.xml");
doc.write("CRISPR_example.xml");
\end{lstlisting}
\end{minipage}

The complete repression model described in this tutorial is provided in the libSBOL source code in the examples directory. This example is self-contained in that you can run it to generate the RDF/XML output. Note that SBOL does not provide the specification of a mathematical model directly. It is possible, however, to generate a mathematical model using SBML~\cite{SBML} and the procedure described in~\cite{roehner2015generating}. Then, the SBOL document can reference this generated SBML model.

\subsection*{Copying Objects}
The library can make copies of \sbol{TopLevel} objects using the templated \lstinline+copy+ methods.  This method takes a number of optional arguments. If no arguments are specified, a copy is made and the version is incremented. An object can be copied from one Document to another by passing a pointer to the target Document as the first argument. In addition, the object can be copied to a new namespace, which is specified as the optional second argument. Finally, a custom version tag can be specified in the third argument. The following code snippet demonstrates how the copy method may be used to copy a ComponentDefinition to a new namespace and Document.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
ComponentDefinition& venus = old_doc.get<ComponentDefinition>('venus_yfp');
ComponentDefinition& venus_copy = venus.copy<ComponentDefinition>(&new_doc, "http://igem.org");
new_doc.write("copy_example.xml");
\end{lstlisting}
\end{minipage}

\subsection*{Validation}
The library also supports validation of RDF/XML file to ensure that it conforms with SBOL specification. Validation is performed on a Document object over online validator. To run it, simply run validate() on a Document object. The returned string will contain the results of validation.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
cout << doc.validate() << endl;
\end{lstlisting}
\end{minipage}

Validation is also run when a SBOL file is created through \lstinline+write()+ function. The output of validation is returned as a string when Document.write() function is executed. Keep in mind that the file will be generated regardless of whether it passes the validation step or not.

\vspace{\abovedisplayskip}
\begin{minipage}{0.95\textwidth} 
\begin{lstlisting}
std:string response = doc.write(std::string("CRISPR_example.xml"));
cout << response << endl;
\end{lstlisting}
\end{minipage}