Index: cpp/frams/Makefile-SDK
===================================================================
--- cpp/frams/Makefile-SDK	(revision 723)
+++ cpp/frams/Makefile-SDK	(revision 724)
@@ -5,5 +5,5 @@
 include frams/Makefile-SDK-files
 
-SDK_TESTS=genoconv_test genomanipulation geno_test genooper_test genooper_test_fTest neuro_test loader_test_geno loader_test_param saver_test_geno serial_test multiline_f0_test f0_variants_test full_props shapeconvert part_shapes neuro_layout_test geometry_apices_test geometry_info_test geometry_surface_test geometry_volume_test simil_test simil_unittests
+SDK_TESTS=genoconv_test genomanipulation geno_test genooper_test genooper_test_fTest neuro_test loader_test_geno loader_test_param saver_test_geno serial_test multiline_f0_test f0_variants_test full_props shapeconvert part_shapes neuro_layout_test geometry_apices_test geometry_info_test geometry_surface_test geometry_volume_test simil_test simil_unittests paramtree_stdin_test paramtree_paramlist_test
 
 sdk_tests: $(SDK_TESTS)
@@ -92,7 +92,13 @@
 	$(CXX) $(SIMIL_UNITTESTS_OBJS) $(LDFLAGS) -o $@
 
+paramtree_stdin_test: $(PARAMTREE_STDIN_TEST_OBJS)
+	$(CXX) $(PARAMTREE_STDIN_TEST_OBJS) $(LDFLAGS) -o $@
+
+paramtree_paramlist_test: $(PARAMTREE_PARAMLIST_TEST_OBJS)
+	$(CXX) $(PARAMTREE_PARAMLIST_TEST_OBJS) $(LDFLAGS) -o $@
+
 #############################################
 
-ALL_OBJS=$(GENOMANIPULATION_OBJS) $(GENOCONV_TEST_OBJS) $(GENO_TEST_OBJS) $(NEURO_TEST_OBJS) $(LOADER_TEST_OBJS) $(SERIAL_TEST_OBJS) $(MULTILINE_F0_OBJS) $(F0_VARIANTS_OBJS) $(FULL_PROPS_OBJS) $(PART_SHAPES_OBJS) $(NEURO_LAYOUT_TEST_OBJS) $(GENOOPER_TEST_OBJS) $(GEOMETRY_APICES_TEST_OBJS) $(GEOMETRY_INFO_TEST_OBJS) $(GEOMETRY_SURFACE_TEST_OBJS) $(GEOMETRY_VOLUME_TEST_OBJS) $(SIMIL_TEST_OBJS) $(SIMIL_UNITTESTS_OBJS)
+ALL_OBJS=$(GENOMANIPULATION_OBJS) $(GENOCONV_TEST_OBJS) $(GENO_TEST_OBJS) $(NEURO_TEST_OBJS) $(LOADER_TEST_OBJS) $(SERIAL_TEST_OBJS) $(MULTILINE_F0_OBJS) $(F0_VARIANTS_OBJS) $(FULL_PROPS_OBJS) $(PART_SHAPES_OBJS) $(NEURO_LAYOUT_TEST_OBJS) $(GENOOPER_TEST_OBJS) $(GEOMETRY_APICES_TEST_OBJS) $(GEOMETRY_INFO_TEST_OBJS) $(GEOMETRY_SURFACE_TEST_OBJS) $(GEOMETRY_VOLUME_TEST_OBJS) $(SIMIL_TEST_OBJS) $(SIMIL_UNITTESTS_OBJS) $(PARAMTREE_STDIN_TEST_OBJS) $(PARAMTREE_PARAMLIST_TEST_OBJS)
 
 include common/Makefile-maintain
Index: cpp/frams/Makefile-SDK-files
===================================================================
--- cpp/frams/Makefile-SDK-files	(revision 723)
+++ cpp/frams/Makefile-SDK-files	(revision 724)
@@ -19,5 +19,5 @@
 GENMAN_COMMON_OBJS=frams/genetics/genman.o frams/param/mutableparam.o frams/param/mutparamlist.o frams/neuro/geneticneuroparam.o frams/neuro/neurolibparam.o
 
-SDK_OBJS=frams/util/list.o frams/util/advlist.o frams/param/param.o frams/util/sstring.o frams/util/sstringutils.o frams/util/3d.o frams/vm/classes/3dobject.o frams/model/model.o frams/model/modelparts.o frams/neuro/neurolibrary.o frams/genetics/geno.o frams/genetics/genoconv.o frams/util/extvalue.o frams/vm/classes/collectionobj.o frams/util/hashtable.o common/log.o common/stl-util.o common/nonstd_stdio.o frams/util/callbacks.o frams/param/syntparam.o frams/util/multirange.o frams/util/multimap.o frams/param/paramtabobj.o common/loggers/loggers.o frams/param/paramobj.o frams/genetics/oper_fx.o common/nonstd_math.o frams/util/validitychecks.o common/Convert.o frams/util/rndutil.o
+SDK_OBJS=frams/util/list.o frams/util/advlist.o frams/param/param.o frams/util/sstring.o frams/util/sstringutils.o frams/util/3d.o frams/vm/classes/3dobject.o frams/model/model.o frams/model/modelparts.o frams/neuro/neurolibrary.o frams/genetics/geno.o frams/genetics/genoconv.o frams/util/extvalue.o frams/vm/classes/collectionobj.o frams/util/hashtable.o common/log.o common/stl-util.o common/nonstd_stdio.o frams/util/callbacks.o frams/param/syntparam.o frams/util/multirange.o frams/util/multimap.o frams/param/paramtabobj.o common/loggers/loggers.o frams/param/paramobj.o frams/genetics/oper_fx.o common/nonstd_math.o frams/util/validitychecks.o common/Convert.o frams/util/rndutil.o common/virtfile/stringfile.o
 
 GEOMETRY_OBJS=frams/model/geometry/meshbuilder.o frams/model/geometry/modelgeometryinfo.o frams/model/geometry/geometryutils.o
@@ -32,7 +32,7 @@
 GENOMANIPULATION_OBJS= frams/_demos/genomanipulation.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS)
 
-MULTILINE_F0_OBJS=frams/_demos/multiline_f0_test.o common/virtfile/stringfile.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS)
+MULTILINE_F0_OBJS=frams/_demos/multiline_f0_test.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS)
 
-F0_VARIANTS_OBJS=frams/_demos/f0_variants_test.o common/virtfile/stringfile.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
+F0_VARIANTS_OBJS=frams/_demos/f0_variants_test.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
 
 LOADER_TEST_OBJS=frams/_demos/genotypeloader.o frams/_demos/loader_test_geno.o common/virtfile/virtfile.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
@@ -76,2 +76,6 @@
 
 SIMIL_UNITTESTS_OBJS=frams/_demos/simil_unittests.o frams/model/similarity/simil_match.o
+
+PARAMTREE_STDIN_TEST_OBJS=frams/_demos/paramtree_stdin_test.o frams/_demos/paramtree_print.o $(STDOUT_LOGGER_OBJS) common/virtfile/stdiofile.o $(SDK_OBJS) frams/param/paramtree.o
+
+PARAMTREE_PARAMLIST_TEST_OBJS=frams/_demos/paramtree_paramlist_test.o frams/_demos/paramtree_print.o $(STDOUT_LOGGER_OBJS) common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS) frams/neuro/neuroimpl.o frams/neuro/neurofactory.o frams/neuro/impl/neuroimpl-simple.o frams/neuro/impl/neuroimpl-channels.o frams/neuro/impl/neuroimpl-fuzzy.o frams/neuro/impl/neuroimpl-fuzzy-f0.o $(GENOTYPE_LOADER_OBJS) $(GEOMETRY_OBJS) frams/model/geometry/modelgeoclass.o frams/model/modelobj.o frams/param/paramtree.o
Index: cpp/frams/_demos/app_group_names.txt
===================================================================
--- cpp/frams/_demos/app_group_names.txt	(revision 724)
+++ cpp/frams/_demos/app_group_names.txt	(revision 724)
@@ -0,0 +1,44 @@
+# Framsticks application parameter group names, test data for paramtree_stdin_test.cpp
+# usage: paramtree_stdin_test <app_group_names.txt
+
+Experiment
+Files
+Advanced scripting
+Error handling
+Experiment: Parameters
+Experiment: Status
+World
+World: ODE Parameters
+World: ODE Parameters: Creatures Collisions
+World: ODE Parameters: Ground Collisions
+Genetics
+Genetics: Active operators
+Genetics: Neurons to add
+Genetics: f0
+Genetics: f0: Parts
+Genetics: f0: Joints
+Genetics: f0: Neurons
+Genetics: f0: Connections
+Genetics: f1
+Genetics: f1: Morphology
+Genetics: f1: Neuron net
+Genetics: f2
+Genetics: f3
+Genetics: f3: Mutation
+Genetics: f3: Crossover
+Genetics: f4
+Genetics: f9
+Genetics: fF
+Genetics: Conversions
+Creature: Neurons
+Creature: Imperfection
+Creature: Neurons: Enabled
+Creature: Similarity
+Creature: Symmetry
+Creature: Geometry
+Creature: Body constraints
+User scripts
+Experiment: Gene pools
+Experiment: Populations
+Experiment: Gene pools: Initial gene pool
+Experiment: Populations: Live creatures
Index: cpp/frams/_demos/paramtree_paramlist_test.cpp
===================================================================
--- cpp/frams/_demos/paramtree_paramlist_test.cpp	(revision 724)
+++ cpp/frams/_demos/paramtree_paramlist_test.cpp	(revision 724)
@@ -0,0 +1,44 @@
+#include <frams/util/sstringutils.h>
+#include <common/virtfile/stdiofile.h>
+#include <frams/genetics/preconfigured.h>
+#include <frams/param/paramtree.h>
+#include <frams/param/mutparamlist.h>
+#include <frams/vm/classes/genoobj.h>
+#include <frams/vm/classes/collectionobj.h>
+#include <frams/vm/classes/3dobject.h>
+#include <frams/neuro/neuroimpl.h>
+#include <frams/neuro/neurofactory.h>
+#include <frams/model/geometry/modelgeoclass.h>
+#include <frams/model/modelobj.h>
+#include "genotypeloader.h"
+#include "paramtree_print.h"
+
+// This program tests parameter tree construction for all paramtab's that are available in SDK.
+// See paramtree_test.cpp and app_group_names.txt for a more complete set (from Framsticks GUI) of paramtab objects.
+int main()
+{
+	StdioFILE::setStdio(); //setup VirtFILE::Vstdin/out/err
+	PreconfiguredGenetics genetics;
+
+	Param minigenotype_param(minigenotype_paramtab);
+	NeuroFactory neurofac;
+	neurofac.setStandardImplementation();
+	NeuroNetConfig nn_config(&neurofac);
+	ModelGeometry modelgeo;
+
+	MutableParamList combined;
+	combined += &genetics.genman.par;
+	combined += &GenoObj::getStaticParam();
+	combined += &ModelObj::getStaticParam();
+	combined += &VectorObject::getStaticParam();
+	combined += &DictionaryObject::getStaticParam();
+	combined += &Pt3D_Ext::getStaticParam();
+	combined += &Orient_Ext::getStaticParam();
+	combined += &minigenotype_param;
+	combined += &nn_config.par;
+	combined += &modelgeo.par;
+
+	ParamTree tree(combined);
+
+	printTree(&tree.root);
+}
Index: cpp/frams/_demos/paramtree_stdin_test.cpp
===================================================================
--- cpp/frams/_demos/paramtree_stdin_test.cpp	(revision 724)
+++ cpp/frams/_demos/paramtree_stdin_test.cpp	(revision 724)
@@ -0,0 +1,52 @@
+#include <frams/util/sstringutils.h>
+#include <common/virtfile/stdiofile.h>
+#include <frams/param/paramtree.h>
+#include "paramtree_print.h"
+
+class EmptyParamWithGroupsForTesting : public Param
+{
+	std::vector<ParamEntry> entries;
+	std::vector<std::shared_ptr<std::string>> strings; //could be a simple vector of strings, but then char* pointers can change when adding new strings and so ParamEntry structures would need updating. Therefore using "vector of string pointers" instead of "vector of strings".
+public:
+	EmptyParamWithGroupsForTesting()
+	{
+		ParamEntry zero_ending = { 0, 0, 0, 0 };
+		entries.push_back(zero_ending);
+	}
+	void addGroup(const char* name)
+	{
+		std::shared_ptr<string> str(new std::string(name));
+		strings.push_back(str);
+		ParamEntry tmp = { str.get()->c_str(), 0, 0, 0 };
+		entries.insert(entries.begin() + (entries.size() - 1), tmp);
+		entries[0].group = entries.size() - 1;
+		setParamTab(getParamTab());
+	}
+	ParamEntry *getParamTab()
+	{
+		return &entries[0];
+	}
+};
+
+int main()
+{
+	SString group_names;
+	StdioFILE::setStdio();//setup VirtFILE::Vstdin/out/err
+	loadSString(VirtFILE::Vstdin, group_names);
+	int pos = 0;
+	SString line;
+	EmptyParamWithGroupsForTesting param;
+	puts("(loading group names from stdin)");
+	while (group_names.getNextToken(pos, line, '\n'))
+	{
+		if ((line.len() > 0) && (line[line.len() - 1] == '\r')) //support for reading \r\n files...
+			line = line.substr(0, line.len() - 1);
+		if (line.len() > 0 && line[0] != '#') // skip empty lines and #commment lines
+			param.addGroup(line.c_str());
+	}
+	printf("%d groups\n\n", param.getGroupCount());
+
+	ParamTree tree(param);
+
+	printTree(&tree.root);
+}
