Repository: fbergmann/libSEDML (language: python)

Issue:
getListOfAllElements not working
As it turns out, getListOfAllElements, does not return all elements, and this will need  to be fixed. Also it seems the ElementFilter construct is not available. 


Discussion / hints:

Fix patch:
diff --git a/dev/sedml.xml b/dev/sedml.xml
index 8591b7f2..3d67af5b 100644
--- a/dev/sedml.xml
+++ b/dev/sedml.xml
@@ -27,8 +27,6 @@
         </element>
         <element name="Model" typeCode="SEDML_MODEL" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="false">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="language" required="false" type="string" abstract="false"/>
             <attribute name="source" required="true" type="string" abstract="false"/>
             <attribute name="change" required="false" type="lo_element" element="Change" abstract="true"/>
@@ -58,8 +56,6 @@
         </element>
         <element name="Variable" typeCode="SEDML_VARIABLE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="true" elementName="variable">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="symbol" required="false" type="string" abstract="false"/>
             <attribute name="target" required="false" type="string" abstract="false"/>
             <attribute name="taskReference" required="false" type="SIdRef" element="Task" abstract="false"/>
@@ -74,15 +70,11 @@
         </element>
         <element name="Parameter" typeCode="SEDML_PARAMETER" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="false" elementName="parameter">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="value" required="true" type="double" abstract="false"/>
           </attributes>
         </element>
         <element name="Simulation" typeCode="SEDML_SIMULATION" hasListOf="true" hasChildren="true" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="true" elementName="simulation" listOfName="listOfSimulations">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="algorithm" required="true" type="element" element="Algorithm" abstract="false"/>
           </attributes>
           <concretes>
@@ -108,8 +100,6 @@
         </element>
         <element name="AbstractTask" typeCode="SEDML_SEDML_ABSTRACTTASK" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="true" listOfName="listOfTasks" listOfClassName="SedListOfTasks">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
           </attributes>
           <concretes>
             <concrete name="task" element="Task" minNumChildren="0" maxNumChildren="0"/>
@@ -130,8 +120,6 @@
         </element>
         <element name="DataGenerator" typeCode="SEDML_DATAGENERATOR" hasListOf="true" hasChildren="true" hasMath="true" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="false" elementName="dataGenerator">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="variable" required="false" type="lo_element" element="Variable" abstract="false"/>
             <attribute name="parameter" required="false" type="lo_element" element="Parameter" abstract="false"/>
             <attribute name="math" required="false" type="element" element="ASTNode*" abstract="false"/>
@@ -139,8 +127,6 @@
         </element>
         <element name="Output" typeCode="SEDML_OUTPUT" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="true" listOfName="listOfOutputs">
           <attributes>
-            <attribute name="id" required="false" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
           </attributes>
           <concretes>
             <concrete name="report" element="Report" minNumChildren="0" maxNumChildren="0"/>
@@ -176,8 +162,6 @@
         </element>
         <element name="AbstractCurve" typeCode="SEDML_ABSTRACTCURVE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="true" listOfName="listOfCurves" listOfClassName="SedListOfCurves">
           <attributes>
-            <attribute name="id" required="false" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="logX" required="false" type="bool" abstract="false"/>
             <attribute name="order" required="false" type="integer" abstract="false"/>
             <attribute name="style" required="false" type="SIdRef" element="Style" abstract="false"/>
@@ -206,8 +190,6 @@
         </element>
         <element name="Surface" typeCode="SEDML_OUTPUT_SURFACE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="false" elementName="surface">
           <attributes>
-            <attribute name="id" required="false" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="xDataReference" required="false" type="SIdRef" element="DataGenerator" abstract="false"/>
             <attribute name="yDataReference" required="false" type="SIdRef" element="DataGenerator" abstract="false"/>
             <attribute name="zDataReference" required="true" type="SIdRef" element="DataGenerator" abstract="false"/>
@@ -221,9 +203,7 @@
         </element>
         <element name="DataSet" typeCode="SEDML_OUTPUT_DATASET" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="false" elementName="dataSet">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
             <attribute name="label" required="true" type="string" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="dataReference" required="true" type="SIdRef" element="DataGenerator" abstract="false"/>
           </attributes>
         </element>
@@ -241,7 +221,6 @@
         </element>
         <element name="Range" typeCode="SEDML_RANGE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" baseClass="SedBase" abstract="true">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
           </attributes>
           <concretes>
             <concrete name="uniformRange" element="UniformRange" minNumChildren="0" maxNumChildren="0"/>
@@ -318,8 +297,6 @@
         </element>
         <element name="DataDescription" typeCode="SEDML_DATA_DESCRIPTION" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="false">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="format" required="false" type="string" abstract="false"/>
             <attribute name="source" required="false" type="string" abstract="false"/>
             <attribute name="dimensionDescription" required="false" type="element" element="DimensionDescription" abstract="false"/>
@@ -328,8 +305,6 @@
         </element>
         <element name="DataSource" typeCode="SEDML_DATA_SOURCE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="false">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
-            <attribute name="name" required="false" type="string" abstract="false"/>
             <attribute name="indexSet" required="false" type="SIdRef" abstract="false"/>
             <attribute name="slice" required="false" type="lo_element" element="Slice" abstract="false"/>
           </attributes>
@@ -373,7 +348,6 @@
         </element>
         <element name="FitExperiment" typeCode="SEDML_FIT_EXPERIMENT" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="false">
           <attributes>
-            <attribute name="id" required="false" type="SId" abstract="false"/>
             <attribute name="type" required="false" type="enum" element="ExperimentType" abstract="false"/>
             <attribute name="algorithm" required="false" type="element" element="Algorithm" abstract="false"/>
             <attribute name="fitMapping" required="false" type="lo_element" element="FitMapping" abstract="false"/>
@@ -422,7 +396,6 @@
         </element>
         <element name="Style" typeCode="SEDML_STYLE" hasListOf="true" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" minNumListOfChildren="0" maxNumListOfChildren="0" abstract="false">
           <attributes>
-            <attribute name="id" required="true" type="SId" abstract="false"/>
             <attribute name="baseStyle" required="false" type="SIdRef" element="Style" abstract="false"/>
             <attribute name="lineStyle" required="false" type="element" element="Line" xmlName="lineStyle" abstract="false"/>
             <attribute name="markerStyle" required="false" type="element" element="Marker" xmlName="markerStyle" abstract="false"/>
@@ -431,7 +404,7 @@
         </element>
         <element name="Line" typeCode="SEDML_LINE" hasListOf="false" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" abstract="false">
           <attributes>
-            <attribute name="style" required="false" type="enum" element="LineType" abstract="false"/>
+            <attribute name="type" required="false" type="enum" element="LineType" abstract="false"/>
             <attribute name="color" required="false" type="string" abstract="false"/>
             <attribute name="thickness" required="false" type="double" abstract="false"/>
           </attributes>
@@ -439,7 +412,7 @@
         <element name="Marker" typeCode="SEDML_MARKER" hasListOf="false" hasChildren="false" hasMath="false" childrenOverwriteElementName="false" abstract="false">
           <attributes>
             <attribute name="size" required="false" type="double" abstract="false"/>
-            <attribute name="style" required="false" type="enum" element="MarkerType" abstract="false"/>
+            <attribute name="type" required="false" type="enum" element="MarkerType" abstract="false"/>
             <attribute name="fill" required="false" type="string" abstract="false"/>
             <attribute name="lineColor" required="false" type="string" abstract="false"/>
             <attribute name="lineThickness" required="false" type="double" abstract="false"/>
diff --git a/examples/python/get_all_tasks.py b/examples/python/get_all_tasks.py
new file mode 100644
index 00000000..f9fa7c8a
--- /dev/null
+++ b/examples/python/get_all_tasks.py
@@ -0,0 +1,36 @@
+import libsedml
+import sys
+
+class TaskFilter(libsedml.SedElementFilter):
+  def __init__(self):
+      libsedml.SedElementFilter.__init__(self)
+  
+  def filter(self, element):
+    if isinstance(element, libsedml.SedAbstractTask):
+      return True
+    return False
+
+
+def get_all_tasks(filename):
+
+  doc = libsedml.readSedMLFromFile(filename)
+  if doc.getNumErrors(libsedml.LIBSEDML_SEV_ERROR) > 0: 
+    print("invalid sedml: " + doc.getErrorLog().toString())
+    return 1
+    
+  filter = TaskFilter()
+  all_tasks = doc.getListOfAllElements(filter)
+  
+  for i in range(all_tasks.getSize()): 
+    element = all_tasks.get(i)
+    print (element.downcast())
+
+
+if __name__ == "__main__":
+  num_args = len(sys.argv)
+  if num_args < 2: 
+    print("usage: get_all_tasks <sedml file>")
+    sys.exit(1)
+    
+  sys.exit(get_all_tasks(sys.argv[1]))
+    
diff --git a/examples/xml/l1v4/pe-example.xml b/examples/xml/l1v4/pe-example.xml
index 1304ddee..5a076b0f 100644
--- a/examples/xml/l1v4/pe-example.xml
+++ b/examples/xml/l1v4/pe-example.xml
@@ -27,17 +27,17 @@
       <algorithm kisaoID="KISAO:0000472"/>
       <leastSquareObjectiveFunction/>
       <listOfAdjustableParameters>
-        <adjustableParameter modelReference="model1" target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id=&apos;J2_q&apos;]">
-          <bounds initialValue="2.4" lowerBound="0.0001" upperBound="10"/>
+        <adjustableParameter modelReference="model1" target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id=&apos;J2_q&apos;]" initialValue="2.4">
+          <bounds lowerBound="0.0001" upperBound="10" scale="lin"/>
         </adjustableParameter>
-        <adjustableParameter modelReference="model1" target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id=&apos;J2_q&apos;]">
-          <bounds initialValue="2.4" lowerBound="0.0001" upperBound="10"/>
+        <adjustableParameter modelReference="model1" target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id=&apos;J2_q&apos;]" initialValue="2.4">
+          <bounds lowerBound="0.0001" upperBound="10" scale="lin"/>
         </adjustableParameter>
       </listOfAdjustableParameters>
       <listOfFitExperiments>
-        <fitExperiment id="exp1" represents="TimeCourse">
+        <fitExperiment id="exp1" type="timeCourse">
           <listOfFitMappings>
-            <fitMapping dataSource="dataS1" dataGenerator="s1_conc" type="Variable" weight="1"/>
+            <fitMapping dataSource="dataS1" target="s1_conc" type="observable" weight="1"/>
           </listOfFitMappings>
         </fitExperiment>
       </listOfFitExperiments>
@@ -69,13 +69,13 @@
       </listOfVariables>
     </dataGenerator>
   </listOfDataGenerators>
-  <output>
-    <parameterEstimationResultPlot id="plot1" id="plot1" name="Result Plot" taskRef="pe1"/>
+  <listOfOutputs>
+    <parameterEstimationResultPlot id="plot1" name="Result Plot" taskRef="pe1"/>
     <report id="report1">
       <listOfDataSets>
         <dataSet id="set1" label="OBJ" dataReference="pe_obj"/>
         <dataSet id="set2" label="FEVAL" dataReference="pe_feval"/>
       </listOfDataSets>
     </report>
-  </output>
+  </listOfOutputs>
 </sedML>
diff --git a/src/bindings/python/local.i b/src/bindings/python/local.i
index 316328f4..340289b7 100755
--- a/src/bindings/python/local.i
+++ b/src/bindings/python/local.i
@@ -253,10 +253,26 @@ namespace std
 }
 
 
+%extend SedBase
+{
+  SedBase* downcast()
+  {
+    return $self;
+  }
+}
+
+
 
 /**
  * Convert objects into the most specific type possible.
  */
+
+%typemap(directorin) SedBase*
+{
+  $input = SWIG_NewPointerObj(SWIG_as_voidptr($1), GetDowncastSwigType(const_cast<SedBase*>($1)),
+                               $owner | %newpointer_flags);
+}
+
 %typemap(out) SedBase*, SedSimulation*, SedAbstractTask*, SedTask*, SedOutput*, SedChange*, SedRange*, SedAbstractCurve*
 {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), GetDowncastSwigType($1),
diff --git a/src/bindings/swig/libsedml.i b/src/bindings/swig/libsedml.i
index acc139ed..afb93847 100755
--- a/src/bindings/swig/libsedml.i
+++ b/src/bindings/swig/libsedml.i
@@ -34,6 +34,7 @@
 
 
 %module(directors="1") libsedml
+%feature("director") SedElementFilter;
 
 %pragma(java) moduleclassmodifiers="
 /**
@@ -86,8 +87,8 @@ LIBNUML_CPP_NAMESPACE_USE
 
 %include "ListWrapper.h"
 %template(ASTNodeList)        ListWrapper<ASTNode>;
-%template(SedNamespacesList) ListWrapper<SedNamespaces>;
-%template(SedBaseList)          ListWrapper<SedBase>;
+%template(SedNamespacesList)  ListWrapper<SedNamespaces>;
+%template(SedBaseList)        ListWrapper<SedBase>;
 %template(SBaseList)          ListWrapper<SBase>;
 
 /**
@@ -296,9 +297,9 @@ LIBNUML_CPP_NAMESPACE_USE
 
 %extend SedBase
 {
-	ListWrapper<SedBase>* getListOfAllElements()
+	ListWrapper<SedBase>* getListOfAllElements(SedElementFilter* filter=NULL)
 	{
-		List* list = $self->getAllElements();
+		List* list = $self->getAllElements(filter);
 		return new ListWrapper<SedBase>(list);
 	}
 }
@@ -341,6 +342,7 @@ typedef std::vector<SedError> SedErrorStdVector;
 %include <sedml/SedTypeCodes.h>
 %include <sedml/SedTypes.h>
 %include <sedml/SedBase.h>
+%include <sedml/SedElementFilter.h>
 %include <sedml/SedListOf.h>
 %include <sedml/SedDocument.h>
 %include <sedml/SedErrorLog.h>
diff --git a/src/sedml/SedAdjustableParameter.cpp b/src/sedml/SedAdjustableParameter.cpp
index 5ceb3cfb..43022670 100755
--- a/src/sedml/SedAdjustableParameter.cpp
+++ b/src/sedml/SedAdjustableParameter.cpp
@@ -1189,6 +1189,23 @@ SedAdjustableParameter::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedAdjustableParameter::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mBounds, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mExperimentRefs, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedAdjustableParameter.h b/src/sedml/SedAdjustableParameter.h
index 35d05c47..df3d440a 100755
--- a/src/sedml/SedAdjustableParameter.h
+++ b/src/sedml/SedAdjustableParameter.h
@@ -978,6 +978,19 @@ class LIBSEDML_EXTERN SedAdjustableParameter : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedAlgorithm.cpp b/src/sedml/SedAlgorithm.cpp
index 6fb813de..15068c0b 100755
--- a/src/sedml/SedAlgorithm.cpp
+++ b/src/sedml/SedAlgorithm.cpp
@@ -781,6 +781,22 @@ SedAlgorithm::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedAlgorithm::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mAlgorithmParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedAlgorithm.h b/src/sedml/SedAlgorithm.h
index 4132a162..3aeec454 100755
--- a/src/sedml/SedAlgorithm.h
+++ b/src/sedml/SedAlgorithm.h
@@ -754,6 +754,19 @@ class LIBSEDML_EXTERN SedAlgorithm : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedAlgorithmParameter.cpp b/src/sedml/SedAlgorithmParameter.cpp
index e958abb9..bdcfd51c 100755
--- a/src/sedml/SedAlgorithmParameter.cpp
+++ b/src/sedml/SedAlgorithmParameter.cpp
@@ -897,6 +897,22 @@ SedAlgorithmParameter::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedAlgorithmParameter::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_POINTER(ret, sublist, mAlgorithmParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedAlgorithmParameter.h b/src/sedml/SedAlgorithmParameter.h
index 971fea18..3fe4aad9 100755
--- a/src/sedml/SedAlgorithmParameter.h
+++ b/src/sedml/SedAlgorithmParameter.h
@@ -823,6 +823,19 @@ class LIBSEDML_EXTERN SedAlgorithmParameter : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedBase.cpp b/src/sedml/SedBase.cpp
index 56167bc4..e11311cd 100755
--- a/src/sedml/SedBase.cpp
+++ b/src/sedml/SedBase.cpp
@@ -96,7 +96,7 @@ SedBase::getElementByMetaId(const std::string& metaid) const
 
 
 List*
-SedBase::getAllElements()
+SedBase::getAllElements(SedElementFilter* filter)
 {
   return NULL;
 }
diff --git a/src/sedml/SedBase.h b/src/sedml/SedBase.h
index 5d43b623..b2a16138 100644
--- a/src/sedml/SedBase.h
+++ b/src/sedml/SedBase.h
@@ -47,6 +47,7 @@
 #include <sedml/SedTypeCodes.h>
 #include <sedml/SedNamespaces.h>
 #include <sedml/SedConstructorException.h>
+#include <sedml/SedElementFilter.h>
 #include <sbml/util/List.h>
 #include <sbml/SyntaxChecker.h>
 #include <sbml/ExpectedAttributes.h>
@@ -172,7 +173,7 @@ class LIBSEDML_EXTERN SedBase
    *
    * @return a pointer to a List of pointers to all children objects.
    */
-  virtual List* getAllElements();
+  virtual List* getAllElements(SedElementFilter* filter = NULL);
 
 
   /**
diff --git a/src/sedml/SedComputeChange.cpp b/src/sedml/SedComputeChange.cpp
index 492bc384..b5f10c20 100755
--- a/src/sedml/SedComputeChange.cpp
+++ b/src/sedml/SedComputeChange.cpp
@@ -1126,6 +1126,23 @@ SedComputeChange::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedComputeChange::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mVariables, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedComputeChange.h b/src/sedml/SedComputeChange.h
index 677c1a88..1fb8e61c 100755
--- a/src/sedml/SedComputeChange.h
+++ b/src/sedml/SedComputeChange.h
@@ -1151,6 +1151,19 @@ class LIBSEDML_EXTERN SedComputeChange : public SedChange
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedDataDescription.cpp b/src/sedml/SedDataDescription.cpp
index 7f5e3e48..75484ebc 100755
--- a/src/sedml/SedDataDescription.cpp
+++ b/src/sedml/SedDataDescription.cpp
@@ -1070,6 +1070,23 @@ SedDataDescription::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedDataDescription::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  //SED_ADD_FILTERED_POINTER(ret, sublist, mDimensionDescription, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mDataSources, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedDataDescription.h b/src/sedml/SedDataDescription.h
index a45a18b3..5c769004 100755
--- a/src/sedml/SedDataDescription.h
+++ b/src/sedml/SedDataDescription.h
@@ -977,6 +977,19 @@ class LIBSEDML_EXTERN SedDataDescription : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedDataGenerator.cpp b/src/sedml/SedDataGenerator.cpp
index 5a392d6c..fb976e16 100755
--- a/src/sedml/SedDataGenerator.cpp
+++ b/src/sedml/SedDataGenerator.cpp
@@ -1129,6 +1129,23 @@ SedDataGenerator::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedDataGenerator::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mVariables, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedDataGenerator.h b/src/sedml/SedDataGenerator.h
index cf2aa4e3..1391d229 100755
--- a/src/sedml/SedDataGenerator.h
+++ b/src/sedml/SedDataGenerator.h
@@ -1167,6 +1167,18 @@ class LIBSEDML_EXTERN SedDataGenerator : public SedBase
 
   /** @endcond */
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
 
 
   /** @cond doxygenLibSEDMLInternal */
diff --git a/src/sedml/SedDataSource.cpp b/src/sedml/SedDataSource.cpp
index e50ec0e5..543ffb25 100755
--- a/src/sedml/SedDataSource.cpp
+++ b/src/sedml/SedDataSource.cpp
@@ -849,6 +849,22 @@ SedDataSource::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedDataSource::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mSlices, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedDataSource.h b/src/sedml/SedDataSource.h
index 9dc512f2..81e7454e 100755
--- a/src/sedml/SedDataSource.h
+++ b/src/sedml/SedDataSource.h
@@ -819,6 +819,19 @@ class LIBSEDML_EXTERN SedDataSource : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedDocument.cpp b/src/sedml/SedDocument.cpp
index 62176013..9b02f36f 100644
--- a/src/sedml/SedDocument.cpp
+++ b/src/sedml/SedDocument.cpp
@@ -2600,6 +2600,28 @@ SedDocument::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedDocument::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mDataDescriptions, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mModels, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mSimulations, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mAbstractTasks, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mDataGenerators, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mOutputs, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mStyles, filter);
+
+  return ret;
+}
+
+
 /*
  * Returns the value of the "Namespaces" element of this SedDocument.
  */
diff --git a/src/sedml/SedDocument.h b/src/sedml/SedDocument.h
index edbdc002..92344ce6 100644
--- a/src/sedml/SedDocument.h
+++ b/src/sedml/SedDocument.h
@@ -2515,6 +2515,20 @@ class LIBSEDML_EXTERN SedDocument : public SedBase
   */
   void sortOrderedObjects();
 
+ /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
+
 protected:
 
 
diff --git a/src/sedml/SedElementFilter.cpp b/src/sedml/SedElementFilter.cpp
new file mode 100644
index 00000000..96be40b6
--- /dev/null
+++ b/src/sedml/SedElementFilter.cpp
@@ -0,0 +1,80 @@
+/**
+ * @cond doxygenLibsbmlInternal
+ *
+ * @file    SedElementFilter.cpp
+ * @brief   Implementation of the base class of all element filters
+ * @author  Frank T. Bergmann
+ * 
+ * <!--------------------------------------------------------------------------
+ * This file is part of libSBML.  Please visit http://sbml.org for more
+ * information about SBML, and the latest version of libSBML.
+ *
+ * Copyright (C) 2020 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. University of Heidelberg, Heidelberg, Germany
+ *     3. University College London, London, UK
+ *
+ * Copyright (C) 2019 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. University of Heidelberg, Heidelberg, Germany
+ *
+ * Copyright (C) 2013-2018 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
+ *     3. University of Heidelberg, Heidelberg, Germany
+ *
+ * Copyright (C) 2009-2013 jointly by the following organizations: 
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
+ *  
+ * Copyright (C) 2006-2008 by the California Institute of Technology,
+ *     Pasadena, CA, USA 
+ *  
+ * Copyright (C) 2002-2005 jointly by the following organizations: 
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. Japan Science and Technology Agency, Japan
+ * 
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.  A copy of the license agreement is provided
+ * in the file named "LICENSE.txt" included with this software distribution
+ * and also available online as http://sbml.org/software/libsbml/license.html
+ * ---------------------------------------------------------------------- -->*/
+
+#include <cstddef> 
+#include <sedml/common/libsedml-namespace.h> 
+#include <sedml/common/SedOperationReturnValues.h> 
+#include <sedml/SedElementFilter.h> 
+ 
+LIBSEDML_CPP_NAMESPACE_BEGIN
+
+SedElementFilter::SedElementFilter()
+: mUserData(NULL)
+{
+}
+
+
+SedElementFilter::~SedElementFilter()
+{
+}
+
+bool 
+SedElementFilter::filter(const SedBase*)
+{
+  return false;
+}
+
+void* 
+SedElementFilter::getUserData()
+{
+  return mUserData;
+}
+
+void 
+SedElementFilter::setUserData(void* userData)
+{
+  mUserData = userData;
+}
+
+LIBSEDML_CPP_NAMESPACE_END
+/** @endcond */
diff --git a/src/sedml/SedElementFilter.h b/src/sedml/SedElementFilter.h
new file mode 100644
index 00000000..207c1286
--- /dev/null
+++ b/src/sedml/SedElementFilter.h
@@ -0,0 +1,222 @@
+/**
+ * @file    SedElementFilter.h
+ * @brief   Base class of element filters.
+ * @author  Frank T. Bergmann
+ * 
+ * <!--------------------------------------------------------------------------
+ * This file is part of libSBML.  Please visit http://sbml.org for more
+ * information about SBML, and the latest version of libSBML.
+ *
+ * Copyright (C) 2020 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. University of Heidelberg, Heidelberg, Germany
+ *     3. University College London, London, UK
+ *
+ * Copyright (C) 2019 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. University of Heidelberg, Heidelberg, Germany
+ *
+ * Copyright (C) 2013-2018 jointly by the following organizations:
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
+ *     3. University of Heidelberg, Heidelberg, Germany
+ *
+ * Copyright (C) 2009-2013 jointly by the following organizations: 
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
+ *  
+ * Copyright (C) 2006-2008 by the California Institute of Technology,
+ *     Pasadena, CA, USA 
+ *  
+ * Copyright (C) 2002-2005 jointly by the following organizations: 
+ *     1. California Institute of Technology, Pasadena, CA, USA
+ *     2. Japan Science and Technology Agency, Japan
+ * 
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.  A copy of the license agreement is provided
+ * in the file named "LICENSE.txt" included with this software distribution
+ * and also available online as http://sbml.org/software/libsbml/license.html
+ * ---------------------------------------------------------------------- -->
+ *
+ * @class SedElementFilter
+ * @sbmlbrief{core} Base class for filter functions.
+ *
+ * @htmlinclude libsbml-facility-only-warning.html
+ *
+ * Some libSBML objects provide the ability to return lists of components.
+ * To provide callers with greater control over exactly what is
+ * returned, these methods take optional arguments in the form of filters.
+ * The SedElementFilter class is the parent class for these filters.
+ */
+
+/**
+ * <!-- ~ ~ ~ ~ ~ Start of common documentation strings ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+ * The following text is used as common documentation blocks copied multiple
+ * times elsewhere in this file.  The use of @class is a hack needed because
+ * Doxygen's @copydetails command has limited functionality.  Symbols
+ * beginning with "doc_" are marked as ignored in our Doxygen configuration.
+ * ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~  -->
+ *
+ * @class doc_what_is_user_data
+ *
+ * @par
+ * The user data associated with an SBML object can be used by an application
+ * developer to attach custom information to that object in the model.  In case
+ * of a deep copy, this data will passed as-is.  The data attribute will never
+ * be interpreted by libSBML.
+ */
+
+#ifndef SedElementFilter_h
+#define SedElementFilter_h
+
+
+#ifdef __cplusplus
+
+#include <sbml/common/extern.h>
+#include <sbml/common/libsbml-namespace.h>
+
+LIBSEDML_CPP_NAMESPACE_BEGIN
+
+#define SED_ADD_FILTERED_LIST(pResult,pSublist,list,pFilter)\
+{\
+  if (list.size() > 0) {\
+    if (pFilter == NULL || pFilter->filter(&list))\
+    pResult->add(&list);\
+    pSublist = list.getAllElements(pFilter);\
+    pResult->transferFrom(pSublist);\
+    delete pSublist;\
+  }\
+}
+
+#define SED_ADD_FILTERED_PLIST(pResult,pSublist,pList,pFilter)\
+{\
+  if (pList != NULL && pList->size() > 0) {\
+    if (pFilter == NULL || pFilter->filter(pList))\
+    pResult->add(pList);\
+    pSublist = pList->getAllElements(pFilter);\
+    pResult->transferFrom(pSublist);\
+    delete pSublist;\
+  }\
+}
+
+#define SED_ADD_FILTERED_POINTER(pResult,pSublist,pElement,pFilter)\
+{\
+  if (pElement != NULL) {\
+    if (pFilter == NULL || pFilter->filter(pElement))\
+    pResult->add(pElement);\
+    pSublist = pElement->getAllElements(pFilter);\
+    pResult->transferFrom(pSublist);\
+    delete pSublist;\
+  }\
+}
+
+#define SED_ADD_FILTERED_ELEMENT(pResult,pSublist,element,pFilter)\
+{\
+  {\
+    if (pFilter == NULL || pFilter->filter(&element))\
+    pResult->add(&element);\
+    pSublist = element.getAllElements(pFilter);\
+    pResult->transferFrom(pSublist);\
+    delete pSublist;\
+  }\
+}
+
+#define SED_ADD_FILTERED_FROM_PLUGIN(pResult,pSublist,pFilter)\
+{\
+    pSublist = getAllElementsFromPlugins(pFilter);\
+    pResult->transferFrom(pSublist);\
+    delete pSublist;\
+}
+
+class SedBase;
+
+class LIBSBML_EXTERN SedElementFilter
+{
+public:
+
+  /**
+   * Creates a new SedElementFilter object.
+   */
+  SedElementFilter();
+
+
+  /**
+   * Destroys this SedElementFilter.
+   */
+  virtual ~SedElementFilter();
+
+
+  /**
+   * Predicate to test elements.
+   *
+   * This is the central predicate of the SedElementFilter class.  In subclasses
+   * of SedElementFilter, callers should implement this method such that it
+   * returns @c true for @p element arguments that are "desirable" and
+   * @c false for those that are "undesirable" in whatever filtering context the
+   * SedElementFilter subclass is designed to be used.
+   *
+   * @param element the element to be tested.
+   *
+   * @return @c true if the @p element is desirable or should be kept,
+   * @c false otherwise.
+   */
+  virtual bool filter(const SedBase* element);
+
+
+  /**
+   * Returns the user data that has been previously set via setUserData().
+   *
+   * Callers can attach private data to SedElementFilter objects using
+   * setUserData().  This user data can be used by an application to store
+   * custom information to be accessed by the SedElementFilter in its work.  In
+   * case of a deep copy, the data will passed as it is.  The attribute will
+   * never be interpreted by libSBML.
+   *
+   * @return the user data of this node, or @c NULL if no user data has been
+   * set.
+   *
+   * @warning This <em>user data</em> is specific to an SedElementFilter object
+   * instance, and is not the same as the user data that may be attached to
+   * an SBML object using SBase::setUserData().
+   *
+   * @see setUserData()
+   */
+  void* getUserData();
+
+
+  /**
+   * Sets the user data of this element.
+   *
+   * Callers can attach private data to SedElementFilter objects using this
+   * method, and retrieve them using getUserData().  Such user data can be
+   * used by an application to store information to be accessed by the
+   * SedElementFilter in its work.  In case of a deep copy, this data will
+   * passed as it is.  The attribute will never be interpreted by libSBML.
+   *
+   * @param userData specifies the new user data.
+   *
+   * @copydetails doc_returns_success_code
+   * @li @sbmlconstant{LIBSBML_OPERATION_SUCCESS, OperationReturnValues_t}
+   * @li @sbmlconstant{LIBSBML_OPERATION_FAILED, OperationReturnValues_t}
+   *
+   * @warning This <em>user data</em> is specific to an SedElementFilter object
+   * instance, and is not the same as the user data that may be attached to
+   * an SBML object using SBase::setUserData().
+   *
+   * @see getUserData()
+   */
+  void setUserData(void* userData);
+
+
+private:
+  /** @cond doxygenLibsbmlInternal */
+  void* mUserData;
+
+  /** @endcond */
+};
+
+LIBSEDML_CPP_NAMESPACE_END
+
+#endif  /* __cplusplus */
+#endif  /* SedElementFilter_h */
diff --git a/src/sedml/SedFigure.cpp b/src/sedml/SedFigure.cpp
index 872543d2..6fb68dab 100755
--- a/src/sedml/SedFigure.cpp
+++ b/src/sedml/SedFigure.cpp
@@ -885,6 +885,22 @@ SedFigure::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedFigure::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mSubPlots, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedFigure.h b/src/sedml/SedFigure.h
index 3c392cb8..4e138959 100755
--- a/src/sedml/SedFigure.h
+++ b/src/sedml/SedFigure.h
@@ -833,6 +833,19 @@ class LIBSEDML_EXTERN SedFigure : public SedOutput
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedFitExperiment.cpp b/src/sedml/SedFitExperiment.cpp
index 69f094fc..2851e0c7 100644
--- a/src/sedml/SedFitExperiment.cpp
+++ b/src/sedml/SedFitExperiment.cpp
@@ -1058,6 +1058,23 @@ SedFitExperiment::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedFitExperiment::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mAlgorithm, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mFitMappings, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedFitExperiment.h b/src/sedml/SedFitExperiment.h
index 273d59c1..8eb9d29f 100644
--- a/src/sedml/SedFitExperiment.h
+++ b/src/sedml/SedFitExperiment.h
@@ -974,6 +974,19 @@ class LIBSEDML_EXTERN SedFitExperiment : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedFunctionalRange.cpp b/src/sedml/SedFunctionalRange.cpp
index 4e8fa6ec..43e42438 100755
--- a/src/sedml/SedFunctionalRange.cpp
+++ b/src/sedml/SedFunctionalRange.cpp
@@ -1228,6 +1228,23 @@ SedFunctionalRange::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedFunctionalRange::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mVariables, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedFunctionalRange.h b/src/sedml/SedFunctionalRange.h
index 133be1e4..811beda4 100755
--- a/src/sedml/SedFunctionalRange.h
+++ b/src/sedml/SedFunctionalRange.h
@@ -1209,6 +1209,19 @@ class LIBSEDML_EXTERN SedFunctionalRange : public SedRange
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedListOf.cpp b/src/sedml/SedListOf.cpp
index 3dafc4d2..86caf1b6 100755
--- a/src/sedml/SedListOf.cpp
+++ b/src/sedml/SedListOf.cpp
@@ -315,7 +315,7 @@ SedListOf::getElementByMetaId(const std::string& metaid)
 
 
 List*
-SedListOf::getAllElements()
+SedListOf::getAllElements(SedElementFilter* filter)
 {
   List* ret = new List();
   List* sublist = NULL;
@@ -323,8 +323,9 @@ SedListOf::getAllElements()
   for (unsigned int i = 0; i < size(); i++) 
   {
     SedBase* obj = get(i);
-    ret->add(obj);
-    sublist = obj->getAllElements();
+    if (filter == NULL || filter->filter(obj))
+      ret->add(obj);
+    sublist = obj->getAllElements(filter);
     ret->transferFrom(sublist);
     delete sublist;
   }
diff --git a/src/sedml/SedListOf.h b/src/sedml/SedListOf.h
index 64e26545..7e8c09d6 100755
--- a/src/sedml/SedListOf.h
+++ b/src/sedml/SedListOf.h
@@ -300,7 +300,7 @@ class LIBSEDML_EXTERN SedListOf : public SedBase
    *
    * @return a List of pointers to all child objects.
    */
-  virtual List* getAllElements();
+  virtual List* getAllElements(SedElementFilter* filter = NULL);
 
 
   /**
diff --git a/src/sedml/SedModel.cpp b/src/sedml/SedModel.cpp
index aadc343a..fe35ffcd 100755
--- a/src/sedml/SedModel.cpp
+++ b/src/sedml/SedModel.cpp
@@ -1041,6 +1041,22 @@ SedModel::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedModel::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mChanges, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedModel.h b/src/sedml/SedModel.h
index e9522910..ec9b49d1 100755
--- a/src/sedml/SedModel.h
+++ b/src/sedml/SedModel.h
@@ -865,6 +865,19 @@ class LIBSEDML_EXTERN SedModel : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedParameterEstimationTask.cpp b/src/sedml/SedParameterEstimationTask.cpp
index 52d297e5..122f4366 100755
--- a/src/sedml/SedParameterEstimationTask.cpp
+++ b/src/sedml/SedParameterEstimationTask.cpp
@@ -1328,6 +1328,25 @@ SedParameterEstimationTask::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedParameterEstimationTask::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mAlgorithm, filter);
+  SED_ADD_FILTERED_POINTER(ret, sublist, mObjective, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mAdjustableParameters, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mFitExperiments, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedParameterEstimationTask.h b/src/sedml/SedParameterEstimationTask.h
index 7e62f300..2ea86782 100755
--- a/src/sedml/SedParameterEstimationTask.h
+++ b/src/sedml/SedParameterEstimationTask.h
@@ -1148,6 +1148,19 @@ class LIBSEDML_EXTERN SedParameterEstimationTask : public SedAbstractTask
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedPlot.cpp b/src/sedml/SedPlot.cpp
index 0a7e83c9..a170ce84 100644
--- a/src/sedml/SedPlot.cpp
+++ b/src/sedml/SedPlot.cpp
@@ -1119,6 +1119,23 @@ SedPlot::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedPlot::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mXAxis, filter);
+  SED_ADD_FILTERED_POINTER(ret, sublist, mYAxis, filter);
+
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedPlot.h b/src/sedml/SedPlot.h
index a5e1928d..2053afa4 100644
--- a/src/sedml/SedPlot.h
+++ b/src/sedml/SedPlot.h
@@ -799,6 +799,19 @@ class LIBSEDML_EXTERN SedPlot : public SedOutput
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedPlot2D.cpp b/src/sedml/SedPlot2D.cpp
index e6f4b33d..4a5ec801 100755
--- a/src/sedml/SedPlot2D.cpp
+++ b/src/sedml/SedPlot2D.cpp
@@ -987,6 +987,23 @@ SedPlot2D::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedPlot2D::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mRightYAxis, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mAbstractCurves, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedPlot2D.h b/src/sedml/SedPlot2D.h
index 7efcb13c..662a0dbe 100755
--- a/src/sedml/SedPlot2D.h
+++ b/src/sedml/SedPlot2D.h
@@ -922,6 +922,19 @@ class LIBSEDML_EXTERN SedPlot2D : public SedPlot
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedPlot3D.cpp b/src/sedml/SedPlot3D.cpp
index 12a25fdf..f7e68edf 100755
--- a/src/sedml/SedPlot3D.cpp
+++ b/src/sedml/SedPlot3D.cpp
@@ -986,6 +986,23 @@ SedPlot3D::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedPlot3D::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mZAxis, filter);
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mSurfaces, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedPlot3D.h b/src/sedml/SedPlot3D.h
index 511b91e3..9ac5ab82 100755
--- a/src/sedml/SedPlot3D.h
+++ b/src/sedml/SedPlot3D.h
@@ -958,6 +958,19 @@ class LIBSEDML_EXTERN SedPlot3D : public SedPlot
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedRepeatedTask.cpp b/src/sedml/SedRepeatedTask.cpp
index 4a7adfb1..4b71fd07 100755
--- a/src/sedml/SedRepeatedTask.cpp
+++ b/src/sedml/SedRepeatedTask.cpp
@@ -1455,6 +1455,24 @@ SedRepeatedTask::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedRepeatedTask::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mRanges, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mSetValues, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mSubTasks, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedRepeatedTask.h b/src/sedml/SedRepeatedTask.h
index 7dcb2c2c..297b4802 100755
--- a/src/sedml/SedRepeatedTask.h
+++ b/src/sedml/SedRepeatedTask.h
@@ -1339,6 +1339,19 @@ class LIBSEDML_EXTERN SedRepeatedTask : public SedAbstractTask
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedReport.cpp b/src/sedml/SedReport.cpp
index fbb0f7a1..6f0b1e68 100755
--- a/src/sedml/SedReport.cpp
+++ b/src/sedml/SedReport.cpp
@@ -754,6 +754,22 @@ SedReport::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedReport::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mDataSets, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedReport.h b/src/sedml/SedReport.h
index 119ee3b5..8ef52a7f 100755
--- a/src/sedml/SedReport.h
+++ b/src/sedml/SedReport.h
@@ -811,6 +811,19 @@ class LIBSEDML_EXTERN SedReport : public SedOutput
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedSetValue.cpp b/src/sedml/SedSetValue.cpp
index ef353921..6b6db1a0 100755
--- a/src/sedml/SedSetValue.cpp
+++ b/src/sedml/SedSetValue.cpp
@@ -1397,6 +1397,23 @@ SedSetValue::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedSetValue::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mVariables, filter);
+  SED_ADD_FILTERED_LIST(ret, sublist, mParameters, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedSetValue.h b/src/sedml/SedSetValue.h
index 7a677809..a397cd9e 100755
--- a/src/sedml/SedSetValue.h
+++ b/src/sedml/SedSetValue.h
@@ -1294,6 +1294,19 @@ class LIBSEDML_EXTERN SedSetValue : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedSimulation.cpp b/src/sedml/SedSimulation.cpp
index 5da807b7..6152d5c3 100755
--- a/src/sedml/SedSimulation.cpp
+++ b/src/sedml/SedSimulation.cpp
@@ -783,6 +783,22 @@ SedSimulation::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedSimulation::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mAlgorithm, filter);
+
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedSimulation.h b/src/sedml/SedSimulation.h
index c78b64b9..4d4dba89 100755
--- a/src/sedml/SedSimulation.h
+++ b/src/sedml/SedSimulation.h
@@ -671,7 +671,18 @@ class LIBSEDML_EXTERN SedSimulation : public SedBase
    */
   virtual SedBase* getElementBySId(const std::string& id);
 
-
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+  
 protected:
 
 
diff --git a/src/sedml/SedStyle.cpp b/src/sedml/SedStyle.cpp
index 772bccf5..1dcec333 100755
--- a/src/sedml/SedStyle.cpp
+++ b/src/sedml/SedStyle.cpp
@@ -1144,6 +1144,24 @@ SedStyle::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedStyle::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+  SED_ADD_FILTERED_POINTER(ret, sublist, mLineStyle, filter);
+  SED_ADD_FILTERED_POINTER(ret, sublist, mMarkerStyle, filter);
+  SED_ADD_FILTERED_POINTER(ret, sublist, mFillStyle, filter);
+
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedStyle.h b/src/sedml/SedStyle.h
index 9f873f0f..51bcb239 100755
--- a/src/sedml/SedStyle.h
+++ b/src/sedml/SedStyle.h
@@ -778,6 +778,19 @@ class LIBSEDML_EXTERN SedStyle : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 
diff --git a/src/sedml/SedVariable.cpp b/src/sedml/SedVariable.cpp
index 06fb5413..30d718b2 100755
--- a/src/sedml/SedVariable.cpp
+++ b/src/sedml/SedVariable.cpp
@@ -1076,6 +1076,22 @@ SedVariable::getElementBySId(const std::string& id)
 }
 
 
+/*
+ * Returns a List of all child SedBase objects, including those nested to an
+ * arbitrary depth.
+ */
+List*
+SedVariable::getAllElements(SedElementFilter* filter)
+{
+  List* ret = new List();
+  List* sublist = NULL;
+
+  SED_ADD_FILTERED_LIST(ret, sublist, mRemainingDimensions, filter);
+
+  return ret;
+}
+
+
 
 /** @cond doxygenLibSEDMLInternal */
 
diff --git a/src/sedml/SedVariable.h b/src/sedml/SedVariable.h
index 217e413e..a2dc0692 100755
--- a/src/sedml/SedVariable.h
+++ b/src/sedml/SedVariable.h
@@ -957,6 +957,19 @@ class LIBSEDML_EXTERN SedVariable : public SedBase
   virtual SedBase* getElementBySId(const std::string& id);
 
 
+  /**
+   * Returns a List of all child SedBase objects, including those nested to an
+   * arbitrary depth.
+   *
+   * @param filter an ElementFilter that may impose restrictions on the objects
+   * to be retrieved.
+   *
+   * @return a List pointer of pointers to all SedBase child objects with any
+   * restriction imposed.
+   */
+  virtual List* getAllElements(SedElementFilter * filter = NULL);
+
+
 protected:
 
 


Test patch:
diff --git a/tests/TestIssues.cpp b/tests/TestIssues.cpp
index b4584322..eea4097e 100644
--- a/tests/TestIssues.cpp
+++ b/tests/TestIssues.cpp
@@ -442,6 +442,18 @@ TEST_CASE("Reading numberOfPoints", "[sedml]")
         REQUIRE(range->isSetNumberOfPoints());
         REQUIRE(range->getNumberOfPoints() == 10);
     }
+    
+    {
+      auto* list = doc->getAllElements(); 
+      REQUIRE(list != NULL);
+      REQUIRE(list->getSize() == 4);
+      REQUIRE(static_cast<SedBase*>(list->get(0))->getTypeCode() == SEDML_LIST_OF);
+      REQUIRE(static_cast<SedBase*>(list->get(1))->getTypeCode() == SEDML_TASK_REPEATEDTASK);
+      REQUIRE(static_cast<SedBase*>(list->get(2))->getTypeCode() == SEDML_LIST_OF);
+      REQUIRE(static_cast<SedBase*>(list->get(3))->getTypeCode() == SEDML_RANGE_UNIFORMRANGE);
+      delete list;
+    }
+    
     delete doc;
 }